From ca84dd1894d38836c63cfff4703f08cd17b55add Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 6 Nov 2023 17:43:50 +0200 Subject: [PATCH] Remove examples and use the official repo instead (#1528) * Remove examples and add a makefile for cloning them from the official repo Signed-off-by: Radoslav Dimitrov * Update provider.yaml --------- Signed-off-by: Radoslav Dimitrov --- .gitignore | 3 + Makefile | 31 +++- cmd/dev/examples/provider.yaml | 38 +++++ cmd/dev/examples/pull_request.yaml | 24 +++ cmd/dev/examples/repository.yaml | 24 +++ .../dev/examples}/versioned_artifact.yaml | 15 ++ examples/Makefile | 20 +++ examples/README.md | 8 + examples/github/profiles/pr_vuln_check.yaml | 30 ---- examples/github/profiles/profile.yaml | 155 ------------------ .../github/profiles/profile_artifact.yaml | 18 -- examples/github/provider.yaml | 22 --- examples/github/pull_request.yaml | 9 - examples/github/repository.yaml | 9 - .../rule-types/actions_check_pinned_tags.yaml | 82 --------- .../rule-types/allowed_selected_actions.yaml | 77 --------- .../github/rule-types/artifact_signature.yaml | 79 --------- .../branch_protection_allow_deletions.yaml | 66 -------- .../branch_protection_allow_force_pushes.yaml | 67 -------- .../branch_protection_allow_fork_syncing.yaml | 67 -------- .../rule-types/branch_protection_enabled.yaml | 63 ------- .../branch_protection_enforce_admins.yaml | 66 -------- .../branch_protection_lock_branch.yaml | 67 -------- ...ction_require_conversation_resolution.yaml | 67 -------- ...nch_protection_require_linear_history.yaml | 67 -------- ...e_pull_request_approving_review_count.yaml | 67 -------- ...quire_pull_request_code_owners_review.yaml | 67 -------- ...re_pull_request_dismiss_stale_reviews.yaml | 67 -------- ...on_require_pull_request_push_approval.yaml | 66 -------- ...anch_protection_require_pull_requests.yaml | 81 --------- .../branch_protection_require_signatures.yaml | 61 ------- .../github/rule-types/codeql_enabled.yaml | 142 ---------------- .../default_workflow_permissions.yaml | 57 ------- .../rule-types/dependabot_configured.yaml | 109 ------------ .../rule-types/dockerfile_no_latest_tag.yaml | 55 ------- .../rule-types/github_actions_allowed.yaml | 67 -------- examples/github/rule-types/license.yaml | 71 -------- .../github/rule-types/pr_trusty_check.yaml | 50 ------ .../rule-types/pr_vulnerability_check.yaml | 80 --------- .../repo_workflow_access_level.yaml | 60 ------- .../rule-types/secret_push_protection.yaml | 56 ------- .../github/rule-types/secret_scanning.yaml | 58 ------- .../rule-types/trivy_action_enabled.yaml | 73 --------- internal/engine/rule_types_test.go | 6 +- 44 files changed, 163 insertions(+), 2304 deletions(-) create mode 100644 cmd/dev/examples/provider.yaml create mode 100644 cmd/dev/examples/pull_request.yaml create mode 100644 cmd/dev/examples/repository.yaml rename {examples/github => cmd/dev/examples}/versioned_artifact.yaml (59%) create mode 100644 examples/Makefile create mode 100644 examples/README.md delete mode 100644 examples/github/profiles/pr_vuln_check.yaml delete mode 100644 examples/github/profiles/profile.yaml delete mode 100644 examples/github/profiles/profile_artifact.yaml delete mode 100644 examples/github/provider.yaml delete mode 100644 examples/github/pull_request.yaml delete mode 100644 examples/github/repository.yaml delete mode 100644 examples/github/rule-types/actions_check_pinned_tags.yaml delete mode 100644 examples/github/rule-types/allowed_selected_actions.yaml delete mode 100644 examples/github/rule-types/artifact_signature.yaml delete mode 100644 examples/github/rule-types/branch_protection_allow_deletions.yaml delete mode 100644 examples/github/rule-types/branch_protection_allow_force_pushes.yaml delete mode 100644 examples/github/rule-types/branch_protection_allow_fork_syncing.yaml delete mode 100644 examples/github/rule-types/branch_protection_enabled.yaml delete mode 100644 examples/github/rule-types/branch_protection_enforce_admins.yaml delete mode 100644 examples/github/rule-types/branch_protection_lock_branch.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_conversation_resolution.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_linear_history.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_pull_request_approving_review_count.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_pull_request_code_owners_review.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_pull_request_dismiss_stale_reviews.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_pull_request_push_approval.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_pull_requests.yaml delete mode 100644 examples/github/rule-types/branch_protection_require_signatures.yaml delete mode 100644 examples/github/rule-types/codeql_enabled.yaml delete mode 100644 examples/github/rule-types/default_workflow_permissions.yaml delete mode 100644 examples/github/rule-types/dependabot_configured.yaml delete mode 100644 examples/github/rule-types/dockerfile_no_latest_tag.yaml delete mode 100644 examples/github/rule-types/github_actions_allowed.yaml delete mode 100644 examples/github/rule-types/license.yaml delete mode 100644 examples/github/rule-types/pr_trusty_check.yaml delete mode 100644 examples/github/rule-types/pr_vulnerability_check.yaml delete mode 100644 examples/github/rule-types/repo_workflow_access_level.yaml delete mode 100644 examples/github/rule-types/secret_push_protection.yaml delete mode 100644 examples/github/rule-types/secret_scanning.yaml delete mode 100644 examples/github/rule-types/trivy_action_enabled.yaml diff --git a/.gitignore b/.gitignore index b94166ea87..bbc26f4017 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ docs/.docusaurus /deployment/helm/templates/combined.yml /deployment/helm/charts /deployment/helm/*.tgz + +# Ignore examples cloned repo +examples/rules-and-profiles/ diff --git a/Makefile b/Makefile index cc8e944502..6166b3295b 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,9 @@ projectname?=minder +# Profile and Rule examples +include examples/Makefile + # Unfortunately, we need OS detection for docker-compose OS := $(shell uname -s) @@ -38,19 +41,22 @@ BUILDTAGS?=$(TARGET_ENV) default: help -.PHONY: help gen clean-gen build run-cli run-server bootstrap test clean cover lint pre-commit migrateup migratedown sqlc mock cli-docs identity - +.PHONY: help help: ## list makefile targets @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: gen gen: buf sqlc mock ## Run code generation targets (buf, sqlc, mock) +.PHONY: buf buf: ## Run protobuf code generation buf generate +.PHONY: clean-gen clean-gen: rm -rf $(shell find pkg/api -iname "*.go") & rm -rf $(shell find pkg/api -iname "*.swagger.json") & rm -rf pkg/api/protodocs +.PHONY: cli-docs cli-docs: @rm -rf docs/docs/ref/cli/commands @mkdir -p docs/docs/ref/cli/commands @@ -58,6 +64,7 @@ cli-docs: @echo 'position: 20' >> docs/docs/ref/cli/commands/_category_.yml @go run -tags '$(BUILDTAGS)' cmd/cli/main.go docs +.PHONY: build build: ## build golang binary CGO_ENABLED=0 go build \ -trimpath \ @@ -67,14 +74,17 @@ build: ## build golang binary CGO_ENABLED=0 go build -trimpath -tags '$(BUILDTAGS)' -o ./bin/$(projectname)-server ./cmd/server CGO_ENABLED=0 go build -trimpath -tags '$(BUILDTAGS)' -o ./bin/medev ./cmd/dev +.PHONY: run-cli run-cli: ## run the CLI, needs additional arguments @go run -ldflags "-X main.version=$(shell git describe --abbrev=0 --tags)" -tags '$(BUILDTAGS)' ./cmd/cli +.PHONY: run-server run-server: ## run the app @go run -ldflags "-X main.version=$(shell git describe --abbrev=0 --tags)" -tags '$(BUILDTAGS)' ./cmd/server serve DOCKERARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') +.PHONY: run-docker run-docker: ## run the app under docker. # podman (at least) doesn't seem to like multi-arch images, and sometimes picks the wrong one (e.g. amd64 on arm64) # We also need to remove the build: directives to use ko builds @@ -84,6 +94,7 @@ run-docker: ## run the app under docker. $(COMPOSE) -f .resolved-compose.yaml down && $(COMPOSE) -f .resolved-compose.yaml up $(COMPOSE_ARGS) $(services) rm .resolved-compose.yaml* +.PHONY: helm helm: ## build the helm chart to a local archive, using ko for the image build cd deployment/helm; \ ko resolve --platform=${KO_PLATFORMS} --base-import-paths --push=${KO_PUSH_IMAGE} -f values.yaml > values.tmp.yaml && \ @@ -93,11 +104,13 @@ helm: ## build the helm chart to a local archive, using ko for the image build cat values.yaml git checkout deployment/helm/values.yaml +.PHONY: helm-template helm-template: ## renders the helm templates which is useful for debugging cd deployment/helm; \ helm dependency update && \ helm template . +.PHONY: bootstrap bootstrap: ## install build deps go generate -tags tools tools/tools.go # N.B. each line runs in a different subshell, so we don't need to undo the 'cd' here @@ -117,30 +130,40 @@ bootstrap: ## install build deps # Make sure the keys are readable by the docker user chmod 644 .ssh/* -test: clean ## display test coverage +.PHONY: test +test: clean init-examples ## display test coverage go test -json -race -v ./... | gotestfmt +.PHONY: clean clean: ## clean up environment rm -rf dist/* & rm -rf bin/* +.PHONY: cover cover: ## display test coverage go test -v -race $(shell go list ./... | grep -v /vendor/) -v -coverprofile=coverage.out go tool cover -func=coverage.out +.PHONY: lint lint: ## lint go files golangci-lint run +.PHONY: pre-commit pre-commit: ## run pre-commit hooks pre-commit run --all-files +.PHONY: sqlc sqlc: ## generate sqlc files sqlc generate +.PHONY: migrateup migrateup: ## run migrate up @go run -tags '$(BUILDTAGS)' cmd/server/main.go migrate up --yes + +.PHONY: migratedown migratedown: ## run migrate down @go run -tags '$(BUILDTAGS)' cmd/server/main.go migrate down +.PHONY: dbschema dbschema: ## generate database schema with schema spy, monitor file until doc is created and copy it mkdir -p database/schema/output && chmod a+w database/schema/output cd database/schema && $(COMPOSE) run -u 1001:1001 --rm schemaspy -configFile /config/schemaspy.properties -imageformat png @@ -148,11 +171,13 @@ dbschema: ## generate database schema with schema spy, monitor file until doc is cp database/schema/output/diagrams/summary/relationships.real.large.png docs/static/img/minder/schema.png cd database/schema && $(COMPOSE) down -v && rm -rf output +.PHONY: mock mock: ## generate mocks mockgen -package mockdb -destination database/mock/store.go github.com/stacklok/minder/internal/db Store mockgen -package mockgh -destination internal/providers/github/mock/github.go -source pkg/providers/v1/providers.go GitHub mockgen -package auth -destination internal/auth/mock/jwtauth.go github.com/stacklok/minder/internal/auth JwtValidator,KeySetFetcher +.PHONY: github-login github-login: ## setup GitHub login on Keycloak ifndef KC_GITHUB_CLIENT_ID $(error KC_GITHUB_CLIENT_ID is not set) diff --git a/cmd/dev/examples/provider.yaml b/cmd/dev/examples/provider.yaml new file mode 100644 index 0000000000..8c4aec534a --- /dev/null +++ b/cmd/dev/examples/provider.yaml @@ -0,0 +1,38 @@ +# +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +# This is a sample provider integrating minder with GitHub +# There are details which you'll need to fill in yourself. +version: v1 +type: provider +name: github +context: + organization: ACME +def: + endpoint: 'https://api.github.com/' + auth: + type: oauth2 + client_id: 'your-client-id' + client_secret: 'your-client-secret' + scopes: ['repo', 'read:org'] + client_types: + - rest + - graphql + entities: + - repositories + - build_environments + - artifacts + diff --git a/cmd/dev/examples/pull_request.yaml b/cmd/dev/examples/pull_request.yaml new file mode 100644 index 0000000000..8ae60442ba --- /dev/null +++ b/cmd/dev/examples/pull_request.yaml @@ -0,0 +1,24 @@ +# +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +url: https://api.github.com/repos/jakubtestorg/bad-npm/pulls/3 +commitSHA: bd9958a63c9b95ccc2bc0cf1eef65a87529aed16 +number: 3 +repo_owner: jakubtestorg +repo_name: bad-npm +patches: + - name: package-lock.json + patch_Url: https://github.com/jakubtestorg/bad-npm/raw/123/package-lock.json +authorID: 144222806 diff --git a/cmd/dev/examples/repository.yaml b/cmd/dev/examples/repository.yaml new file mode 100644 index 0000000000..473ba48904 --- /dev/null +++ b/cmd/dev/examples/repository.yaml @@ -0,0 +1,24 @@ +# +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +owner: stacklok +name: Demo-Repo-Go +repoId: 605597568 +HookUrl: +clone_url: "https://github.com/stacklok/Demo-Repo-Go.git" +CreatedAt: 2021-03-19T16:00:00Z +UpdatedAt: 2021-03-19T16:00:00Z +Registered: true diff --git a/examples/github/versioned_artifact.yaml b/cmd/dev/examples/versioned_artifact.yaml similarity index 59% rename from examples/github/versioned_artifact.yaml rename to cmd/dev/examples/versioned_artifact.yaml index 2c7fc6b43d..574b3ca553 100644 --- a/examples/github/versioned_artifact.yaml +++ b/cmd/dev/examples/versioned_artifact.yaml @@ -1,3 +1,18 @@ +# +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + artifact: artifactId: 5482209 name: test diff --git a/examples/Makefile b/examples/Makefile new file mode 100644 index 0000000000..5e8e518a5c --- /dev/null +++ b/examples/Makefile @@ -0,0 +1,20 @@ +# +# Copyright 2023 Stacklok, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +default: init-examples + +.PHONY: init-examples +init-examples: ## clone example rules and profiles + git clone https://github.com/stacklok/minder-rules-and-profiles.git examples/rules-and-profiles | true diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000000..0b3d5538f7 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,8 @@ +# Minder examples + +## Bootstrap the examples directory + +Run `make` to clone the examples from the [https://github.com/stacklok/minder-rules-and-profiles](https://github.com/stacklok/minder-rules-and-profiles) +```bash +make +``` diff --git a/examples/github/profiles/pr_vuln_check.yaml b/examples/github/profiles/pr_vuln_check.yaml deleted file mode 100644 index fee79f4cd8..0000000000 --- a/examples/github/profiles/pr_vuln_check.yaml +++ /dev/null @@ -1,30 +0,0 @@ -# sample profile for validating artifact signatures -version: v1 -type: profile -name: acme-github-profile-pr-vuln-check -context: - provider: github -alert: "on" -remediate: "off" -pull_request: - - type: pr_vulnerability_check - def: - action: profile_only - ecosystem_config: - - name: npm - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://registry.npmjs.org - - name: Go - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://proxy.golang.org - sum_repository: - url: https://sum.golang.org - - name: pypi - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://pypi.org/pypi diff --git a/examples/github/profiles/profile.yaml b/examples/github/profiles/profile.yaml deleted file mode 100644 index 2ddc672e08..0000000000 --- a/examples/github/profiles/profile.yaml +++ /dev/null @@ -1,155 +0,0 @@ ---- -# sample profile for validating repositories -version: v1 -type: profile -name: acme-github-profile -context: - provider: github -alert: "on" -remediate: "off" -repository: - - type: secret_scanning - def: - enabled: true - - type: secret_push_protection - def: - enabled: true - - type: github_actions_allowed - def: - allowed_actions: selected - - type: allowed_selected_actions - def: - github_owned_allowed: true - verified_allowed: true - patterns_allowed: [] - - type: default_workflow_permissions - def: - default_workflow_permissions: read - can_approve_pull_request_reviews: false - - type: codeql_enabled - def: - languages: [go, javascript, typescript] - schedule_interval: '30 4-6 * * *' - - type: actions_check_pinned_tags - def: {} - - type: dependabot_configured - def: - package_ecosystem: gomod - schedule_interval: weekly - apply_if_file: go.mod - - type: dependabot_configured - def: - package_ecosystem: npm - schedule_interval: weekly - apply_if_file: package.json - - type: dockerfile_no_latest_tag - def: {} - - type: trivy_action_enabled - def: {} - - type: branch_protection_enabled - params: - branch: main - def: {} - - type: branch_protection_allow_deletions - params: - branch: main - def: - allow_deletions: false - - type: branch_protection_allow_force_pushes - params: - branch: main - def: - allow_force_pushes: false - - type: branch_protection_enforce_admins - params: - branch: main - def: - enforce_admins: true - - type: branch_protection_lock_branch - params: - branch: main - def: - lock_branch: false - - type: branch_protection_require_conversation_resolution - params: - branch: main - def: - required_conversation_resolution: true - - type: branch_protection_require_linear_history - params: - branch: main - def: - required_linear_history: true - - type: branch_protection_require_pull_request_approving_review_count - params: - branch: main - def: - required_approving_review_count: 1 - - type: branch_protection_require_pull_request_code_owners_review - params: - branch: main - def: - require_code_owner_reviews: true - - type: branch_protection_require_pull_request_dismiss_stale_reviews - params: - branch: main - def: - dismiss_stale_reviews: true - - type: branch_protection_require_pull_request_last_push_approval - params: - branch: main - def: - require_last_push_approval: true - - type: branch_protection_require_pull_requests - params: - branch: main - def: - required_pull_request_reviews: true - - type: branch_protection_require_signatures - params: - branch: main - def: - required_signatures: false - - type: license - def: - license_filename: LICENSE - license_type: "" -artifact: - - type: artifact_signature - params: - tags: [main] - name: test - def: - is_signed: true - is_verified: true - is_bundle_verified: true -pull_request: - - type: pr_vulnerability_check - def: - action: review - ecosystem_config: - - name: npm - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://registry.npmjs.org - - name: go - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://proxy.golang.org - sum_repository: - url: https://sum.golang.org - - name: pypi - vulnerability_database_type: osv - vulnerability_database_endpoint: https://api.osv.dev/v1/query - package_repository: - url: https://pypi.org/pypi - - type: pr_trusty_check - def: - action: summary - ecosystem_config: - - name: npm - score: 5 - - name: pypi - score: 5 diff --git a/examples/github/profiles/profile_artifact.yaml b/examples/github/profiles/profile_artifact.yaml deleted file mode 100644 index 8335833860..0000000000 --- a/examples/github/profiles/profile_artifact.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -# sample profile for validating artifact signatures -version: v1 -type: profile -name: acme-github-profile-artifact -context: - provider: github -alert: "on" -remediate: "off" -artifact: - - type: artifact_signature - params: - tags: [main] - name: test - def: - is_signed: true - is_verified: true - is_bundle_verified: true diff --git a/examples/github/provider.yaml b/examples/github/provider.yaml deleted file mode 100644 index 3c482fb680..0000000000 --- a/examples/github/provider.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# This is a sample provider integrating minder with GitHub -# There are details which you'll need to fill in yourself. -version: v1 -type: provider -name: github -context: - organization: ACME -def: - endpoint: 'https://api.github.com/' - auth: - type: oauth2 - client_id: 'your-client-id' - client_secret: 'your-client-secret' - scopes: ['repo', 'read:org'] - client_types: - - rest - - graphql - entities: - - repositories - - build_environments - - artifacts \ No newline at end of file diff --git a/examples/github/pull_request.yaml b/examples/github/pull_request.yaml deleted file mode 100644 index 1b45f85bd7..0000000000 --- a/examples/github/pull_request.yaml +++ /dev/null @@ -1,9 +0,0 @@ -url: https://api.github.com/repos/jakubtestorg/bad-npm/pulls/3 -commitSHA: bd9958a63c9b95ccc2bc0cf1eef65a87529aed16 -number: 3 -repo_owner: jakubtestorg -repo_name: bad-npm -patches: - - name: package-lock.json - patch_Url: https://github.com/jakubtestorg/bad-npm/raw/123/package-lock.json -authorID: 144222806 diff --git a/examples/github/repository.yaml b/examples/github/repository.yaml deleted file mode 100644 index 6453257c5f..0000000000 --- a/examples/github/repository.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -owner: stacklok -name: Demo-Repo-Go -repoId: 605597568 -HookUrl: -clone_url: "https://github.com/stacklok/Demo-Repo-Go.git" -CreatedAt: 2021-03-19T16:00:00Z -UpdatedAt: 2021-03-19T16:00:00Z -Registered: true diff --git a/examples/github/rule-types/actions_check_pinned_tags.yaml b/examples/github/rule-types/actions_check_pinned_tags.yaml deleted file mode 100644 index 67a835c5f0..0000000000 --- a/examples/github/rule-types/actions_check_pinned_tags.yaml +++ /dev/null @@ -1,82 +0,0 @@ ---- -version: v1 -type: rule-type -name: actions_check_pinned_tags -context: - provider: github -description: Verifies that any actions use pinned tags -guidance: | - Verifies that any actions use pinned tags - Pinning an action to a full length commit SHA is currently the only way to use - an action as an immutable release. Pinning to a particular SHA helps mitigate - the risk of a bad actor adding a backdoor to the action's repository, as they - would need to generate a SHA-1 collision for a valid Git object payload. - When selecting a SHA, you should verify it is from the action's repository - and not a repository fork. - - For more information, see - https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - # In this case there are no settings that need to be configured - rule_schema: {} - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - # This example uses the checks for that GitHub actions are using pinned tags - # for the use directive, in the form of SHA-1 hash. - # For example, this wil fail: - # uses: actions/checkout@v2 - # This will pass: - # uses: actions/checkout@f3d2b746c498f2d3d1f2d3d1f2d3d1f2d3d1f2d3 - eval: - type: rego - rego: - type: constraints - def: | - package minder - - violations[{"msg": msg}] { - # List all workflows - workflows := file.ls("./.github/workflows") - - # Read all workflows - some w - workflowstr := file.read(workflows[w]) - - # Parse the YAML content - workflow := yaml.unmarshal(workflowstr) - - # Iterate over all jobs and steps in the current workflow - some job_name - job_steps := workflow.jobs[job_name].steps - - # Ensure each step uses a SHA-1 hash - some step_num - s := job_steps[step_num] - - # Check if the step has a uses directive - not is_null(s.uses) - - # Split the uses directive at '@' - parts := split(s.uses, "@") - - # Check if the string after '@' is 40 characters long (SHA-1 hash length) - count(parts[1]) != 40 - - # All characters should be hexadecimal - not regex.match(`^[a-fA-F0-9]+$`, parts[1]) - msg := sprintf("Workflow '%v' uses an unpinned action '%v' in job '%v' step '%v'", [workflows[w], s.uses, job_name, step_num]) - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/allowed_selected_actions.yaml b/examples/github/rule-types/allowed_selected_actions.yaml deleted file mode 100644 index 4e04e066e1..0000000000 --- a/examples/github/rule-types/allowed_selected_actions.yaml +++ /dev/null @@ -1,77 +0,0 @@ ---- -version: v1 -type: rule-type -name: allowed_selected_actions -context: - provider: github -description: | - Verifies the settings for selected actions and reusable workflows that are allowed - in a repository. To use this rule, the repository profile for allowed_actions must - be configured to selected. -guidance: | - Having an overview over which actions and reusable workflows are allowed in a repository is important and allows for a better overall security posture. - - For more information, see - https://docs.github.com/en/rest/actions/permissions#set-allowed-actions-and-reusable-workflows-for-a-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - type: object - properties: - github_owned_allowed: - type: boolean - "description": "Whether GitHub-owned actions are allowed. For example, this includes the actions in the `actions` organization." - verified_allowed: - type: boolean - "description": "Whether actions from GitHub Marketplace verified creators are allowed. Set to `true` to allow all actions by GitHub Marketplace verified creators." - patterns_allowed: - type: array - description: "Specifies a list of string-matching patterns to allow specific action(s) and reusable workflow(s). Wildcards, tags, and SHAs are allowed. For example, `monalisa/octocat@*`, `monalisa/octocat@v2`, `monalisa/*`.\n\n**Note**: The `patterns_allowed` setting only applies to public repositories." - items: - type: string - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions/selected-actions" - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: ".github_owned_allowed" - # profile points to the profile itself. - profile: - def: '.github_owned_allowed' - - ingested: - def: ".verified_allowed" - profile: - def: '.verified_allowed' - - ingested: - def: ".patterns_allowed" - profile: - def: ".patterns_allowed" - # Defines the configuration for remediating on the rule - remediate: - type: rest - rest: - method: PUT - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions/selected-actions" - body: | - {"github_owned_allowed":{{ .Profile.github_owned_allowed }},"verified_allowed":{{ .Profile.verified_allowed }},"patterns_allowed":[{{range $index, $pattern := .Profile.patterns_allowed}}{{if $index}},{{end}}"{{ $pattern }}"{{end}}]} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/artifact_signature.yaml b/examples/github/rule-types/artifact_signature.yaml deleted file mode 100644 index 9afb3c2308..0000000000 --- a/examples/github/rule-types/artifact_signature.yaml +++ /dev/null @@ -1,79 +0,0 @@ ---- -version: v1 -type: rule-type -name: artifact_signature -context: - provider: github -description: Verifies that a given artifact has a valid signature. -guidance: | - Artifact signing allows a user to add a digital fingerprint to an artifact and verify its trust later. - It allows the artifact user to verify the source and trust the container image. - Minder leverages sigstore(cosign) to verify an artifact has been signed. - - For more information, see - https://docs.sigstore.dev/signing/signing_with_containers -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: artifact - # Defines the schema for parameters that will be passed to the rule - param_schema: - type: object - properties: - name: - type: string - description: "The name of the artifact to check." - tags: - "type": array - "items": { - "type": "string" - } - description: "The tags of the artifact to check. Must be a subset of the tags the artifact has" - type: - "type": string - "default": "container" - "enum": ["container"] - description: "The type of artifact to check. Currently only container is supported." - required: - - tags - # Defines the schema for writing a rule with this rule being checked - rule_schema: - type: "object" - properties: - is_signed: - type: boolean - description: "Set to true to enforce artifact being signed." - is_verified: - type: boolean - description: "Set to true to enforce artifact signature being verified." - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: artifact - # Currently no configuration - artifact: {} - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - import future.keywords.every - import future.keywords.if - - default allow := false - - allow if { - every artifactVersion in input.ingested { - every key, value in input.profile { - artifactVersion.Verification[key] == value - } - } - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_allow_deletions.yaml b/examples/github/rule-types/branch_protection_allow_deletions.yaml deleted file mode 100644 index 527926c1ef..0000000000 --- a/examples/github/rule-types/branch_protection_allow_deletions.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_allow_deletions -context: - provider: github -description: Whether the branch can be deleted -guidance: | - Allow users with push access to delete matching branches. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - allow_deletions: - type: boolean - description: "Allows deletion of the protected branch by anyone with write access to the repository." - default: false - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".allow_deletions.enabled" - profile: - def: ".allow_deletions" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"allow_deletions":{{ .Profile.allow_deletions }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_allow_force_pushes.yaml b/examples/github/rule-types/branch_protection_allow_force_pushes.yaml deleted file mode 100644 index 343a647f64..0000000000 --- a/examples/github/rule-types/branch_protection_allow_force_pushes.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_allow_force_pushes -context: - provider: github -description: Whether force pushes are allowed to the branch -guidance: | - Permit force pushes for all users with push access. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - allow_force_pushes: - type: boolean - description: "Permits force pushes to the protected branch by anyone with write access to the repository." - required: - - allow_force_pushes - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".allow_force_pushes.enabled" - profile: - def: ".allow_force_pushes" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"allow_force_pushes":{{ .Profile.allow_force_pushes }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_allow_fork_syncing.yaml b/examples/github/rule-types/branch_protection_allow_fork_syncing.yaml deleted file mode 100644 index 4a9845428c..0000000000 --- a/examples/github/rule-types/branch_protection_allow_fork_syncing.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_allow_fork_syncing -context: - provider: github -description: Whether users can pull changes from upstream when the branch is locked -guidance: | - A locked branch cannot be pulled from - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - allow_fork_syncing: - type: boolean - description: "Whether users can pull changes from upstream when the branch is locked. Set to `true` to allow fork syncing. Set to `false` to prevent fork syncing." - required: - - allow_fork_syncing - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".allow_fork_syncing.enabled" - profile: - def: ".allow_fork_syncing" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"allow_fork_syncing":{{ .Profile.allow_fork_syncing }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_enabled.yaml b/examples/github/rule-types/branch_protection_enabled.yaml deleted file mode 100644 index 063aa7715f..0000000000 --- a/examples/github/rule-types/branch_protection_enabled.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_enabled -context: - provider: github -description: Verifies that a branch has a branch protection rule -guidance: | - You can protect important branches by setting branch protection rules, which define whether - collaborators can delete or force push to the branch and set requirements for any pushes to the branch, - such as passing status checks or a linear commit history. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - rule_schema: {} - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - import future.keywords.every - import future.keywords.if - - default allow := false - - allow if { - input.ingested.url != "" - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_enforce_admins.yaml b/examples/github/rule-types/branch_protection_enforce_admins.yaml deleted file mode 100644 index eec69d02f5..0000000000 --- a/examples/github/rule-types/branch_protection_enforce_admins.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_enforce_admins -context: - provider: github -description: Whether the protection rules apply to repository administrators -guidance: | - Enforce required status checks for repository administrators - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - enforce_admins: - description: "Specifies whether the protection rule applies to repository administrators." - type: boolean - default: true - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".enforce_admins.enabled" - profile: - def: ".enforce_admins" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"enforce_admins": {{ .Profile.enforce_admins }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_lock_branch.yaml b/examples/github/rule-types/branch_protection_lock_branch.yaml deleted file mode 100644 index 36c1bb6717..0000000000 --- a/examples/github/rule-types/branch_protection_lock_branch.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_lock_branch -context: - provider: github -description: Whether the branch is locked -guidance: | - Can set the branch as read-only. Users cannot push to the branch. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - lock_branch: - type: boolean - description: "Whether to set the branch as read-only. If this is true, users will not be able to push to the branch." - required: - - lock_branch - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".lock_branch.enabled" - profile: - def: ".lock_branch" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"lock_branch":{{ .Profile.lock_branch }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_conversation_resolution.yaml b/examples/github/rule-types/branch_protection_require_conversation_resolution.yaml deleted file mode 100644 index e66c4aca9c..0000000000 --- a/examples/github/rule-types/branch_protection_require_conversation_resolution.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_conversation_resolution -context: - provider: github -description: Whether PR reviews must be resolved before merging -guidance: | - When enabled, all conversations on code must be resolved before a pull request can be merged into a branch that matches this rule - - For more information, see - https://docs.github.com/github/administering-a-repository/defining-the-mergeability-of-pull-requests/about-protected-branches#require-conversation-resolution-before-merging -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - required_conversation_resolution: - type: boolean - description: "Requires all conversations on code to be resolved before a pull request can be merged into a branch that matches this rule." - required: - - required_conversation_resolution - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_conversation_resolution.enabled" - profile: - def: ".required_conversation_resolution" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_conversation_resolution":{{ .Profile.required_conversation_resolution }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_linear_history.yaml b/examples/github/rule-types/branch_protection_require_linear_history.yaml deleted file mode 100644 index d149d580b7..0000000000 --- a/examples/github/rule-types/branch_protection_require_linear_history.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_linear_history -context: - provider: github -description: Whether the branch requires a linear history with no merge commits -guidance: | - Prevent merge commits from being pushed to matching branches. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - required_linear_history: - type: boolean - description: "Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch." - required: - - required_linear_history - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_linear_history.enabled" - profile: - def: ".required_linear_history" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_linear_history":{{ .Profile.required_linear_history }} } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "low" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_pull_request_approving_review_count.yaml b/examples/github/rule-types/branch_protection_require_pull_request_approving_review_count.yaml deleted file mode 100644 index 1e7c11fe9c..0000000000 --- a/examples/github/rule-types/branch_protection_require_pull_request_approving_review_count.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_pull_request_approving_review_count -context: - provider: github -description: Require a certain number of approving reviews before merging -guidance: | - Each pull request must have a certain number of approving reviews before it can be merged into a matching branch. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - required_approving_review_count: - description: "Specify the number of reviewers required to approve pull requests. Use a number between 1 and 6 or 0 to not require reviewers." - type: integer - required: - - required_approving_review_count - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_pull_request_reviews.required_approving_review_count" - profile: - def: ".required_approving_review_count" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_pull_request_reviews":{"required_approving_review_count":{{ .Profile.required_approving_review_count }}}} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_pull_request_code_owners_review.yaml b/examples/github/rule-types/branch_protection_require_pull_request_code_owners_review.yaml deleted file mode 100644 index 45ab1ff6f6..0000000000 --- a/examples/github/rule-types/branch_protection_require_pull_request_code_owners_review.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_pull_request_code_owners_review -context: - provider: github -description: Verifies that a branch requires review from code owners. -guidance: | - Require an approved review in pull requests including files with a designated code owner. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - require_code_owner_reviews: - description: "Set to true to require an approved review in pull requests including files with a designated code owner." - type: boolean - required: - - require_code_owner_reviews - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_pull_request_reviews.require_code_owner_reviews" - profile: - def: ".require_code_owner_reviews" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_pull_request_reviews":{"require_code_owner_reviews":{{ .Profile.require_code_owner_reviews }}}} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_pull_request_dismiss_stale_reviews.yaml b/examples/github/rule-types/branch_protection_require_pull_request_dismiss_stale_reviews.yaml deleted file mode 100644 index b3094dbd33..0000000000 --- a/examples/github/rule-types/branch_protection_require_pull_request_dismiss_stale_reviews.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_pull_request_dismiss_stale_reviews -context: - provider: github -description: Require that new pushes to the branch dismiss old reviews -guidance: | - New reviewable commits pushed to a matching branch will dismiss pull request review approvals. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - dismiss_stale_reviews: - description: "Set to true to dismiss approving reviews when someone pushes a new commit." - type: boolean - required: - - dismiss_stale_reviews - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_pull_request_reviews.dismiss_stale_reviews" - profile: - def: ".dismiss_stale_reviews" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_pull_request_reviews":{"dismiss_stale_reviews":{{ .Profile.dismiss_stale_reviews }}}} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_pull_request_push_approval.yaml b/examples/github/rule-types/branch_protection_require_pull_request_push_approval.yaml deleted file mode 100644 index fcbf2523a0..0000000000 --- a/examples/github/rule-types/branch_protection_require_pull_request_push_approval.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_pull_request_last_push_approval -context: - provider: github -description: Require that the most recent push to a branch be approved by someone other than the person who pushed it. -guidance: | - The most recent push to a branch must be approved by someone other than the person who pushed it. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - require_last_push_approval: - description: "Whether the most recent push must be approved by someone other than the person who pushed it." - type: boolean - default: false - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_pull_request_reviews.require_last_push_approval" - profile: - def: ".require_last_push_approval" - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - patch: | - {"required_pull_request_reviews":{"require_last_push_approval":{{ .Profile.require_last_push_approval }}}} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_pull_requests.yaml b/examples/github/rule-types/branch_protection_require_pull_requests.yaml deleted file mode 100644 index 4f05e76419..0000000000 --- a/examples/github/rule-types/branch_protection_require_pull_requests.yaml +++ /dev/null @@ -1,81 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_pull_requests -context: - provider: github -description: Verifies that a branch requires pull requests -guidance: | - Require that a pull request be opened before merging to a branch. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - required_pull_request_reviews: - type: boolean - description: | - When enabled, all commits must be made to a non-protected branch and - submitted via a pull request before they can be merged into a branch - that matches this rule. - required: - - required_pull_request_reviews - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - import future.keywords.every - import future.keywords.if - - default allow := false - - allow if { - input.ingested.required_pull_request_reviews.url != "" - } - # Defines the configuration for remediating the rule - remediate: - type: gh_branch_protection - gh_branch_protection: - # Note that this rule will ever only fail if there are no PR settings at all, - # so we can safely set the entire PR settings to an empty object. In that case, - # GH is actually helpful and selects reasonable defaults - patch: | - {"required_pull_request_reviews":{}} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/branch_protection_require_signatures.yaml b/examples/github/rule-types/branch_protection_require_signatures.yaml deleted file mode 100644 index 5ed38d5475..0000000000 --- a/examples/github/rule-types/branch_protection_require_signatures.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -version: v1 -type: rule-type -name: branch_protection_require_signatures -context: - provider: github -description: Whether commits to the branch must be signed -guidance: | - Commits pushed to matching branches must have verified signatures. - - For more information, see - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for parameters that will be passed to the rule - param_schema: - properties: - branch: - type: string - description: "The name of the branch to check." - required: - - branch - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - required_signatures: - description: "Specifies whether commits to the branch must be signed." - type: boolean - required: - - required_signatures - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: '/repos/{{.Entity.Owner}}/{{.Entity.Name}}/branches/{{ index .Params "branch" }}/protection' - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - fallback: - - http_code: 404 - body: | - {"http_status": 404, "message": "Not Protected"} - # Defines the configuration for evaluating data ingested against the given policy - eval: - type: jq - jq: - - ingested: - def: ".required_signatures.enabled" - profile: - def: ".required_signatures" - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/codeql_enabled.yaml b/examples/github/rule-types/codeql_enabled.yaml deleted file mode 100644 index 6a8006e37d..0000000000 --- a/examples/github/rule-types/codeql_enabled.yaml +++ /dev/null @@ -1,142 +0,0 @@ ---- -version: v1 -type: rule-type -name: codeql_enabled -context: - provider: github -description: Verifies that CodeQL is enabled for the repository -guidance: | - CodeQL is a tool that can be used to analyze code for security vulnerabilities. - It is recommended that repositories have some form of static analysis enabled - to ensure that vulnerabilities are not introduced into the codebase. - - To enable CodeQL, add a GitHub workflow to the repository that runs the - CodeQL analysis. - - For more information, see - https://docs.github.com/en/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#configuring-code-scanning-for-a-private-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - type: object - properties: - languages: - type: array - items: - type: string - description: | - Only applicable for remediation. Sets the CodeQL languages to use in the workflow. - CodeQL supports 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' - schedule_interval: - type: string - description: | - Only applicable for remediation. Sets the schedule interval for the workflow. - required: - - languages - - schedule_interval - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - default allow := false - - allow { - # List all workflows - workflows := file.ls("./.github/workflows") - - # Read all workflows - some w - workflowstr := file.read(workflows[w]) - - workflow := yaml.unmarshal(workflowstr) - - # Ensure a workflow contains the codel-ql action - some i - steps := workflow.jobs.analyze.steps[i] - startswith(steps.uses, "github/codeql-action/analyze@") - } - remediate: - type: pull_request - pull_request: - title: "Add CodeQL configuration" - body: | - This is a Minder automated pull request. - - This pull request adds a CodeQL workflow to the repository. - - For more information, see - https://docs.github.com/en/code-security/secure-coding/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning - contents: - - path: .github/workflows/codeql.yml - action: replace - content: | - # Adapted from https://raw.githubusercontent.com/actions/starter-workflows/main/code-scanning/codeql.yml - name: "CodeQL" - - on: - workflow_dispatch: - push: - branches: [ "main" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main" ] - schedule: - - cron: '{{ .Profile.schedule_interval }}' - - jobs: - analyze: - name: Analyze - # Runner size impacts CodeQL analysis time. To learn more, please see: - # - https://gh.io/recommended-hardware-resources-for-running-codeql - # - https://gh.io/supported-runners-and-hardware-resources - # - https://gh.io/using-larger-runners - # Consider using larger runners for possible analysis time improvements. - runs-on: ${{"{{"}} (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' {{"}}"}} - timeout-minutes: ${{"{{"}} (matrix.language == 'swift' && 120) || 360 {{"}}"}} - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [{{range $index, $pattern := .Profile.languages}}{{if $index}},{{end}}"{{ $pattern }}"{{end}}] - # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ] - # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both - # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{"{{"}} matrix.language {{"}}"}} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/default_workflow_permissions.yaml b/examples/github/rule-types/default_workflow_permissions.yaml deleted file mode 100644 index 1519269b1e..0000000000 --- a/examples/github/rule-types/default_workflow_permissions.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -version: v1 -type: rule-type -name: default_workflow_permissions -context: - provider: github -description: | - Verifies the default workflow permissions granted to the GITHUB_TOKEN - when running workflows in a repository, as well as if GitHub Actions - can submit approving pull request reviews. -guidance: | - Having control over the default workflow permissions for a repository is important and allows for a better security posture. - - For more information, see - https://docs.github.com/en/rest/actions/permissions#set-default-workflow-permissions-for-a-repository -def: - in_entity: repository - rule_schema: - type: object - properties: - default_workflow_permissions: - type: string - description: "The default workflow permissions granted to the GITHUB_TOKEN when running workflows." - enum: - - read - - write - can_approve_pull_request_reviews: - type: boolean - description: "Whether GitHub Actions can approve pull requests." - required: - - default_workflow_permissions - - can_approve_pull_request_reviews - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions/workflow" - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: ".default_workflow_permissions" - # profile points to the profile itself. - profile: - def: ".default_workflow_permissions" - - ingested: - def: ".can_approve_pull_request_reviews" - profile: - def: ".can_approve_pull_request_reviews" - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/dependabot_configured.yaml b/examples/github/rule-types/dependabot_configured.yaml deleted file mode 100644 index 85884a67ca..0000000000 --- a/examples/github/rule-types/dependabot_configured.yaml +++ /dev/null @@ -1,109 +0,0 @@ ---- -version: v1 -type: rule-type -name: dependabot_configured -context: - provider: github -description: Verifies that Dependabot is configured for the repository -guidance: | - Dependabot enables Automated dependency updates for repositories. - It is recommended that repositories have some form of automated dependency updates enabled - to ensure that vulnerabilities are not introduced into the codebase. - - For more information, see - https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - # In this case there are no settings that need to be configured - rule_schema: - type: object - properties: - package_ecosystem: - type: string - description: | - The package ecosystem that the rule applies to. - For example, npm, docker, github-actions, etc. - schedule_interval: - type: string - description: | - The interval that the rule should be evaluated. - For example, daily, weekly, monthly, etc. - apply_if_file: - type: string - description: | - Optional. If specified, the rule will only be evaluated if the given file exists. - This is useful for rules that are only applicable to certain types of repositories. - required: - - package_ecosystem - - schedule_interval - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - # This example uses the checks for a dependabot configuration in the dependabot.yml file - # configured to run weekly for the package ecosystem specified. - # Another example, for NPM could be: - # update["package-ecosystem"] == "npm" - # update.schedule.interval == "daily" - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - default allow := false - - # Set allow if we don't need to skip and the rule evaluation passes - allow { - # Read the dependabot configuration - fileStr := file.read("./.github/dependabot.yml") - - # Parse the YAML content - config := yaml.unmarshal(fileStr) - - # Ensure a configuration contains the package ecosystem daily update schedule - update := config.updates[_] - update["package-ecosystem"] == input.profile.package_ecosystem - update.schedule.interval == input.profile.schedule_interval - } - - # We skip if the apply_if_file is specified and the file does not exist - skip { - input.profile.apply_if_file != "" - not file.exists(input.profile.apply_if_file) - } - remediate: - type: pull_request - pull_request: - title: "Add Dependabot configuration for {{.Profile.package_ecosystem }}" - body: | - This is a Minder automated pull request. - - This pull request adds a Dependabot configuration to the repository to handle - package updates for {{.Profile.package_ecosystem }}. - - For more information, see - https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file - contents: - - path: .github/dependabot.yml - action: replace - content: | - version: 2 - updates: - - package-ecosystem: "{{.Profile.package_ecosystem }}" - directory: "/" - schedule: - interval: "{{.Profile.schedule_interval }}" - open-pull-requests-limit: 10 - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/dockerfile_no_latest_tag.yaml b/examples/github/rule-types/dockerfile_no_latest_tag.yaml deleted file mode 100644 index bcee10ce26..0000000000 --- a/examples/github/rule-types/dockerfile_no_latest_tag.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -version: v1 -type: rule-type -name: dockerfile_no_latest_tag -context: - provider: github -description: Verifies that the Dockerfile image references don't use the latest tag -guidance: | - Using the latest tag for Docker images is not recommended as it can lead to unexpected behavior. - It is recommended to use a checksum instead, as that's immutable and will always point to the same image. -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - # In this case there are no settings that need to be configured - rule_schema: {} - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - # This example uses the checks for that GitHub actions are using pinned tags - # for the use directive, in the form of SHA-1 hash. - # For example, this wil fail: - # uses: actions/checkout@v2 - # This will pass: - # uses: actions/checkout@f3d2b746c498f2d3d1f2d3d1f2d3d1f2d3d1f2d3 - eval: - type: rego - rego: - type: constraints - def: | - package minder - - violations[{"msg": msg}] { - # Read Dockerfile - dockerfile := file.read("Dockerfile") - - # Find all lines that start with FROM - from_lines := regex.find_n("^FROM \\S+.*^", dockerfile, -1) - - # Is there the `latest` tag? - from_line := from_lines[_] - endswith(from_line, ":latest") - - msg := sprintf("Dockerfile contains 'latest' tag in import: %s", [from_line]) - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/github_actions_allowed.yaml b/examples/github/rule-types/github_actions_allowed.yaml deleted file mode 100644 index 5b9659476a..0000000000 --- a/examples/github/rule-types/github_actions_allowed.yaml +++ /dev/null @@ -1,67 +0,0 @@ ---- -version: v1 -type: rule-type -name: github_actions_allowed -context: - provider: github -description: | - Verifies permissions for github actions for a specific repository. - - Setting up permissions for github actions can be a bit tricky. This rule will - help you verify that the permissions are set up correctly for a specific repository. - This rule allows you to limit the actions that are allowed to run for a repository. - It is recommended to use the `selected` option for allowed actions, and then - select the actions that are allowed to run. -guidance: | - Configure your repository to match the organization's profile for allowed actions. - - For more information, see - https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#managing-github-actions-permissions-for-your-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - type: object - properties: - allowed_actions: - type: string - description: The permissions profile that controls the actions and reusable workflows that are allowed to run. - enum: - - "all" - - "local_only" - - "selected" - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions" - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: ".allowed_actions" - profile: - def: ".allowed_actions" - remediate: - type: rest - rest: - method: PUT # (jakub): PATCH doesn't seem to work - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions" - body: | - { "enabled": true, "allowed_actions": "{{.Profile.allowed_actions}}" } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/license.yaml b/examples/github/rule-types/license.yaml deleted file mode 100644 index e73b2383e1..0000000000 --- a/examples/github/rule-types/license.yaml +++ /dev/null @@ -1,71 +0,0 @@ ---- -version: v1 -type: rule-type -name: license -context: - provider: github -description: Verifies that there's a license file of a given type present in the repository. -guidance: | - The license rule type ensures that a license file is present in the repository and its license type complies with - the configured license type in your profile. - - For more information, see - https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - # In this case there are no settings that need to be configured - rule_schema: - type: object - properties: - license_filename: - type: string - description: | - The license filename to look for. - For example, LICENSE, LICENSE.txt, etc. - default: LICENSE - license_type: - type: string - description: | - The license type to look for. - For example, Apache, MIT, etc. - Leave "" to only check for the presence of the license file. - required: - - license_filename - - license_type - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - # The following example checks for the presence of a license file and the license type. - # If the license type is not specified (license_type = ""), then only the presence of the license file is checked. - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - import future.keywords.if - - default allow := false - - allow if { - # Read the license file and check if it contains the license type - fileStr := file.read(input.profile.license_filename) - contains(fileStr, input.profile.license_type) - } else if { - # Check if the file exists and the license type is left blank - file.exists(input.profile.license_filename) - input.profile.license_type == "" - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "low" diff --git a/examples/github/rule-types/pr_trusty_check.yaml b/examples/github/rule-types/pr_trusty_check.yaml deleted file mode 100644 index eac5a4310a..0000000000 --- a/examples/github/rule-types/pr_trusty_check.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -version: v1 -type: rule-type -name: pr_trusty_check -context: - provider: github -description: Verifies that pull requests do not add any dependencies with low Trusty scores -guidance: | - For every pull request submitted to a repository, this rule will check if the pull request - adds a new dependency with a low Trusty score. If a dependency with a low - score is added, the PR will commented on or even rejected, depending on the configuration. -def: - in_entity: pull_request - rule_schema: - type: object - properties: - action: - type: string - description: "The action to take if a package with a low score is found." - enum: - # the evaluator engine will merely pass on an error, marking the profile as failed if a packages with low scores is found - - profile_only - # the evaluator engine will add a single summary comment with a table listing the packages with low scores found - - summary - default: review - ecosystem_config: - type: array - description: "The configuration for the ecosystems to check." - items: - type: object - properties: - name: - type: string - description: "The name of the ecosystem to check. Currently only `npm` and `pypi` are supported." - pi_threshold: - type: number - description: "The minimum Trusty score for a dependency to be considered safe." - default: 5 - ingest: - type: diff - diff: - ecosystems: - - name: npm - depfile: package-lock.json - - name: pypi - depfile: requirements.txt - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: trusty - trusty: {} diff --git a/examples/github/rule-types/pr_vulnerability_check.yaml b/examples/github/rule-types/pr_vulnerability_check.yaml deleted file mode 100644 index e4528e6ee4..0000000000 --- a/examples/github/rule-types/pr_vulnerability_check.yaml +++ /dev/null @@ -1,80 +0,0 @@ ---- -version: v1 -type: rule-type -name: pr_vulnerability_check -context: - provider: github -description: Verifies that pull requests do not add any vulnerable dependencies -guidance: | - For every pull request submitted to a repository, this rule will check if the pull request - adds a new dependency with known vulnerabilities. If it does, the rule will fail and the - pull request will be rejected or commented on. -def: - in_entity: pull_request - rule_schema: - type: object - properties: - action: - type: string - description: "The action to take if a vulnerability is found." - enum: - # minder will review the PR, suggest changes and mark the PR as changes requested if a vulnerability is found - - review - # minder will comment and suggest changes on the PR if a vulnerability is found. Additionally, minder - # will set the commit_status of the PR HEAD to failed to prevent the commit from being merged - - commit_status - # minder will comment and suggest changes on the PR if a vulnerability is found, but not request changes - - comment - # the evaluator engine will merely pass on an error, marking the profile as failed if a vulnerability is found - - profile_only - # the evaluator engine will add a single summary comment with a table listing the vulnerabilities found - - summary - default: review - ecosystem_config: - type: array - description: "The configuration for the ecosystems to check." - items: - type: object - properties: - name: - type: string - description: "The name of the ecosystem to check. Currently `npm`, `go` and `pypi` are supported." - vulnerability_database_type: - type: string - "description": "The kind of vulnerability database to use. Currently only `osv` is supported." - vulnerability_database_endpoint: - type: string - "description": "The endpoint of the vulnerability database to use." - package_repository: - type: object - properties: - url: - type: string - description: "The URL of the package repository to use." - "description": "The package repository to use." - sum_repository: - type: object - properties: - url: - type: string - description: "The URL of the Go sum repository to use. Only used if the ecosystem is `go`." - "description": "The Go sum repository to use." - ingest: - type: diff - diff: - ecosystems: - - name: npm - depfile: package-lock.json - - name: go - depfile: go.sum - - name: pypi - depfile: requirements.txt - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: vulncheck - vulncheck: {} - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/repo_workflow_access_level.yaml b/examples/github/rule-types/repo_workflow_access_level.yaml deleted file mode 100644 index 3fbf91eecc..0000000000 --- a/examples/github/rule-types/repo_workflow_access_level.yaml +++ /dev/null @@ -1,60 +0,0 @@ ---- -version: v1 -type: rule-type -name: repo_workflow_access_level -context: - provider: github -description: | - Verifies the level of access that workflows outside of the repository have - to actions and reusable workflows in the repository. This only applies to private repositories. -guidance: | - Actions and reusable workflows in your private repositories can be shared with other private repositories owned by the same user or organization. - - For more information, see - https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#allowing-access-to-components-in-a-private-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - access_level: - type: string - enum: ["none", "user", "organization"] - required: - - access_level - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions/access" - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: ".access_level" - # profile points to the profile itself. - profile: - def: '.access_level' - remediate: - type: rest - rest: - method: PUT - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}/actions/permissions/access" - body: | - { "access_level": "{{.Profile.access_level}}" } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/secret_push_protection.yaml b/examples/github/rule-types/secret_push_protection.yaml deleted file mode 100644 index 8ccb01aba0..0000000000 --- a/examples/github/rule-types/secret_push_protection.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- -version: v1 -type: rule-type -name: secret_push_protection -context: - provider: github -description: Verifies that secret push protection is enabled for a given repository. -guidance: | - You can use secret scanning to prevent supported secrets from being pushed into your repository by enabling secret scanning push protection. - - For more information, see - https://docs.github.com/en/code-security/secret-scanning/push-protection-for-repositories-and-organizations#enabling-secret-scanning-as-a-push-protection-for-a-repository -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - enabled: - type: boolean - default: true - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}" - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: '.security_and_analysis.secret_scanning_push_protection.status == "enabled"' - # profile points to the profile itself. - profile: - def: ".enabled" - remediate: - type: rest - rest: - method: PATCH - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}" - body: | - { "security_and_analysis": {"secret_scanning_push_protection": { "status": "enabled" } } } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/secret_scanning.yaml b/examples/github/rule-types/secret_scanning.yaml deleted file mode 100644 index be0ff79972..0000000000 --- a/examples/github/rule-types/secret_scanning.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -version: v1 -type: rule-type -name: secret_scanning -context: - provider: github -description: Verifies that secret scanning is enabled for a given repository. -guidance: | - Secret scanning is a feature that scans repositories for secrets and alerts - the repository owner when a secret is found. To enable this feature in GitHub, - you must enable it in the repository settings. - - For more information, see - https://docs.github.com/en/github/administering-a-repository/about-secret-scanning -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - rule_schema: - properties: - enabled: - type: boolean - default: true - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: rest - rest: - # This is the path to the data source. Given that this will evaluate - # for each repository in the organization, we use a template that - # will be evaluated for each repository. The structure to use is the - # protobuf structure for the entity that is being evaluated. - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}" - # This is the method to use to retrieve the data. It should already default to JSON - parse: json - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: jq - jq: - # Ingested points to the data retrieved in the `ingest` section - - ingested: - def: '.security_and_analysis.secret_scanning.status == "enabled"' - # profile points to the profile itself. - profile: - def: ".enabled" - remediate: - type: rest - rest: - method: PATCH - endpoint: "/repos/{{.Entity.Owner}}/{{.Entity.Name}}" - body: | - { "security_and_analysis": {"secret_scanning": { "status": "enabled" } } } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/examples/github/rule-types/trivy_action_enabled.yaml b/examples/github/rule-types/trivy_action_enabled.yaml deleted file mode 100644 index fefd7b7121..0000000000 --- a/examples/github/rule-types/trivy_action_enabled.yaml +++ /dev/null @@ -1,73 +0,0 @@ ---- -version: v1 -type: rule-type -name: trivy_action_enabled -context: - provider: github -description: Verifies that the Trivy action is enabled for the repository and scanning -guidance: | - Trivy is an open source vulnerability scanner for repositories, containers and other - artifacts provided by Aqua Security. It is used to scan for vulnerabilities in the - codebase and dependencies. This rule ensures that the Trivy action is enabled for - the repository and scanning is performed. - - Set it up by adding the following to your workflow: - - ```yaml - - name: Trivy Scan - uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f # v0.12.0 - with: - image-ref: ${{ github.repository }} - format: json - exit-code: 1 - ``` - - For more information, see - https://github.com/marketplace/actions/aqua-security-trivy -def: - # Defines the section of the pipeline the rule will appear in. - # This will affect the template used to render multiple parts - # of the rule. - in_entity: repository - # Defines the schema for writing a rule with this rule being checked - # In this case there are no settings that need to be configured - rule_schema: {} - # Defines the configuration for ingesting data relevant for the rule - ingest: - type: git - git: - branch: main - # Defines the configuration for evaluating data ingested against the given profile - eval: - type: rego - rego: - type: deny-by-default - def: | - package minder - - default allow := false - - allow { - # List all workflows - workflows := file.ls("./.github/workflows") - - # Read all workflows - some w - workflowstr := file.read(workflows[w]) - - workflow := yaml.unmarshal(workflowstr) - - # Iterate jobs - job := workflow.jobs[_] - - # Iterate steps - step := job.steps[_] - - # Check if the step is a trivy action - startswith(step.uses, "aquasecurity/trivy-action@") - } - # Defines the configuration for alerting on the rule - alert: - type: security_advisory - security_advisory: - severity: "medium" \ No newline at end of file diff --git a/internal/engine/rule_types_test.go b/internal/engine/rule_types_test.go index ccecf0ef9e..e4a50eceb4 100644 --- a/internal/engine/rule_types_test.go +++ b/internal/engine/rule_types_test.go @@ -30,11 +30,11 @@ func TestExampleRulesAreValidatedCorrectly(t *testing.T) { t.Parallel() t.Log("parsing example profile") - pol, err := engine.ReadProfileFromFile("../../examples/github/profiles/profile.yaml") - require.NoError(t, err, "failed to parse example profile") + pol, err := engine.ReadProfileFromFile("../../examples/rules-and-profiles/profiles/github/profile.yaml") + require.NoError(t, err, "failed to parse example profile, make sure to do - make init-examples") // open rules in example directory - err = filepath.Walk("../../examples/github/rule-types", func(path string, info os.FileInfo, err error) error { + err = filepath.Walk("../../examples/rules-and-profiles/rule-types/github", func(path string, info os.FileInfo, err error) error { // skip directories if info.IsDir() { return nil