Skip to content

CIS GitHub Benchmark

CIS GitHub Benchmark, platform-side posture for a single GitHub organization or repository. Sections 1.1 (Code Changes), 1.4 (Third-Party), and 1.5 (Code Risks) are evidenced directly by the SCM-* rule pack, which reads the GitHub REST API; a representative slice of GHA-* workflow rules anchors 1.5.2 (CI/CD pipeline instructions).

Use this page alongside the CIS Software Supply Chain Guide when a GitHub audit asks for both the platform settings and the build-chain posture. Pair with OpenSSF Scorecard and SCM provider docs for the underlying signals.

At a glance

  • Controls in this standard: 28
  • Controls evidenced by at least one check: 28 / 28
  • Distinct checks evidencing this standard: 138
  • Of those, autofixable with --fix: 18

Severity levels (CRITICAL / HIGH / MEDIUM / LOW / INFO) follow the same scale across every provider and standard. See How to read severity on the standards overview for the definitions.

Coverage by control

Click a control ID to jump to the per-control section with the full check list. The severity mix column shows the spread of evidencing checks by severity (Critical / High / Medium / Low / Info).

Control Title Checks Severity mix
1.1.3 Ensure any change to code is approved by two strongly authenticated users 5 3H · 2M
1.1.4 Ensure previous approvals are dismissed when updates are introduced 3 3M
1.1.5 Ensure there are restrictions on who can dismiss code change reviews 3 1H · 2M
1.1.6 Ensure code owners are set for extra sensitive code or configuration 2 2M
1.1.7 Ensure code owner's review is required when a change affects owned code 2 2M
1.1.9 Ensure all checks have passed before merging new code 3 2M · 1L
1.1.10 Ensure open Git branches are up to date before they can be merged 2 1M · 1L
1.1.11 Ensure all open comments are resolved before merging code 1 1L
1.1.12 Ensure verification of signed commits for new changes 5 1H · 4M
1.1.13 Ensure linear history is required 2 1H · 1L
1.1.14 Ensure branch protection rules are enforced for administrators 3 2H · 1M
1.1.15 Ensure pushing/merging on default branches is restricted 4 1H · 2M · 1L
1.1.16 Ensure force push is denied 3 2H · 1M
1.1.17 Ensure branch deletion is denied 4 2H · 1M · 1L
1.1.18 Ensure any merging of code is automatically scanned for security 6 3M · 3L
1.1.19 Ensure any merging of code is automatically scanned for vulnerabilities 1 1M
1.1.20 Ensure any merging of code is automatically scanned for secrets 2 2H
1.2.5 Ensure all copies (forks) of code are tracked and accounted for 1 1M
1.2.6 Ensure all code projects are tracked for changes in dependents/dependencies 2 1M · 1L
1.3.8 Ensure strict base permissions are set for repositories 1 1H
1.3.10 Ensure SCM administrators control contribution access (deploy keys, write) 2 2H
1.4.1 Ensure administrator approval is required for every installed application 2 1H · 1M
1.4.3 Ensure the access granted to each installed application is limited 2 1H · 1M
1.4.4 Ensure only secured webhooks are used 1 1H
1.5.1 Ensure scanners are in place to identify and prevent sensitive data in code 16 8C · 6H · 1M · 1L
1.5.2 Ensure scanners are in place to secure CI/CD pipeline instructions 64 12C · 42H · 9M · 1L
1.5.3 Ensure scanners are in place to secure IaC instructions 26 7C · 19H
1.5.4 Ensure scanners are in place to identify and confirm presence of vulnerabilities 8 1H · 6M · 1L

Filter at runtime

Restrict a scan to checks that evidence this standard with --standard cis_github:

# All providers, only checks tied to this standard
pipeline_check --standard cis_github

# Compose with --pipeline to scope by provider
pipeline_check --pipeline github --standard cis_github

# Compose with another standard to widen the lens
pipeline_check --pipeline aws --standard cis_github --standard owasp_cicd_top_10

Controls in scope

1.1.3: Ensure any change to code is approved by two strongly authenticated users

Evidenced by 5 checks across SCM.

Check Title Severity Provider Fix
SCM-002 Default branch protection does not require pull request reviews HIGH SCM
SCM-011 Default branch protection does not require CODEOWNERS reviews MEDIUM SCM
SCM-014 Default branch protection does not require approval of the most recent push MEDIUM SCM
SCM-023 Deployment environment lacks required-reviewer protection HIGH SCM
SCM-032 Active ruleset doesn't require a PR review (governance theater) HIGH SCM

1.1.4: Ensure previous approvals are dismissed when updates are introduced

Evidenced by 3 checks across SCM.

Check Title Severity Provider Fix
SCM-012 Default branch protection keeps stale reviews after a push MEDIUM SCM
SCM-014 Default branch protection does not require approval of the most recent push MEDIUM SCM
SCM-037 Active ruleset's pull_request rule doesn't dismiss stale reviews MEDIUM SCM

1.1.5: Ensure there are restrictions on who can dismiss code change reviews

Evidenced by 3 checks across SCM.

Check Title Severity Provider Fix
SCM-018 Required PR reviews can be bypassed by named identities MEDIUM SCM
SCM-021 Actions can approve pull requests (self-approval bypass) HIGH SCM
SCM-031 Repo allows auto-merge (no human-timing gate) MEDIUM SCM

1.1.6: Ensure code owners are set for extra sensitive code or configuration

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-011 Default branch protection does not require CODEOWNERS reviews MEDIUM SCM
SCM-017 Repository has no CODEOWNERS file MEDIUM SCM

1.1.7: Ensure code owner's review is required when a change affects owned code

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-011 Default branch protection does not require CODEOWNERS reviews MEDIUM SCM
SCM-017 Repository has no CODEOWNERS file MEDIUM SCM

1.1.9: Ensure all checks have passed before merging new code

Evidenced by 3 checks across SCM.

Check Title Severity Provider Fix
SCM-008 Default branch protection does not require status checks MEDIUM SCM
SCM-033 Active ruleset doesn't require status checks MEDIUM SCM
SCM-039 Active ruleset doesn't pin a required workflow LOW SCM

1.1.10: Ensure open Git branches are up to date before they can be merged

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-008 Default branch protection does not require status checks MEDIUM SCM
SCM-042 Active ruleset doesn't require merge queue LOW SCM

1.1.11: Ensure all open comments are resolved before merging code

Evidenced by 1 check across SCM.

Check Title Severity Provider Fix
SCM-013 Default branch protection does not require conversation resolution LOW SCM

1.1.12: Ensure verification of signed commits for new changes

Evidenced by 5 checks across SCM.

Check Title Severity Provider Fix
SCM-006 Default branch protection does not require signed commits MEDIUM SCM
SCM-030 Repository ruleset has bypass actor with bypass_mode: always HIGH SCM
SCM-036 Active ruleset doesn't require signed commits MEDIUM SCM
SCM-043 Tag-targeted ruleset doesn't require signed commits MEDIUM SCM
SCM-044 Default-branch signed-commits requirement bypassed for admins MEDIUM SCM

1.1.13: Ensure linear history is required

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-030 Repository ruleset has bypass actor with bypass_mode: always HIGH SCM
SCM-038 Active ruleset doesn't require linear history LOW SCM

1.1.14: Ensure branch protection rules are enforced for administrators

Evidenced by 3 checks across SCM.

Check Title Severity Provider Fix
SCM-010 Branch protection allows administrators to bypass HIGH SCM
SCM-030 Repository ruleset has bypass actor with bypass_mode: always HIGH SCM
SCM-044 Default-branch signed-commits requirement bypassed for admins MEDIUM SCM

1.1.15: Ensure pushing/merging on default branches is restricted

Evidenced by 4 checks across SCM.

Check Title Severity Provider Fix
SCM-001 Default branch has no protection rule HIGH SCM
SCM-019 Push restrictions allowlist names individual users LOW SCM
SCM-024 Deployment environment can deploy from any branch MEDIUM SCM
SCM-029 Repository ruleset is in evaluate / disabled mode (not enforced) MEDIUM SCM

1.1.16: Ensure force push is denied

Evidenced by 3 checks across SCM.

Check Title Severity Provider Fix
SCM-007 Default branch protection allows force-pushes HIGH SCM
SCM-030 Repository ruleset has bypass actor with bypass_mode: always HIGH SCM
SCM-034 Active ruleset doesn't block force-push MEDIUM SCM

1.1.17: Ensure branch deletion is denied

Evidenced by 4 checks across SCM.

Check Title Severity Provider Fix
SCM-009 Default branch protection allows branch deletion HIGH SCM
SCM-030 Repository ruleset has bypass actor with bypass_mode: always HIGH SCM
SCM-035 Active ruleset doesn't block branch deletion LOW SCM
SCM-043 Tag-targeted ruleset doesn't require signed commits MEDIUM SCM

1.1.18: Ensure any merging of code is automatically scanned for security

Evidenced by 6 checks across SCM.

Check Title Severity Provider Fix
SCM-003 GitHub default code scanning is not enabled MEDIUM SCM
SCM-039 Active ruleset doesn't pin a required workflow LOW SCM
SCM-040 Active ruleset doesn't gate on code scanning results LOW SCM
SCM-045 Default code scanning uses the limited query suite LOW SCM
SCM-046 Default code scanning is configured but paused MEDIUM SCM
SCM-047 Repo language excluded from default code-scanning coverage MEDIUM SCM

1.1.19: Ensure any merging of code is automatically scanned for vulnerabilities

Evidenced by 1 check across SCM.

Check Title Severity Provider Fix
SCM-005 Dependabot security updates are not enabled MEDIUM SCM

1.1.20: Ensure any merging of code is automatically scanned for secrets

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-004 GitHub secret scanning is not enabled HIGH SCM
SCM-015 Secret scanning push protection is not enabled HIGH SCM

1.2.5: Ensure all copies (forks) of code are tracked and accounted for

Evidenced by 1 check across SCM.

Check Title Severity Provider Fix
SCM-028 Private repo allows forking MEDIUM SCM

1.2.6: Ensure all code projects are tracked for changes in dependents/dependencies

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-005 Dependabot security updates are not enabled MEDIUM SCM
SCM-016 Private vulnerability reporting is not enabled LOW SCM

1.3.8: Ensure strict base permissions are set for repositories

Evidenced by 1 check across SCM.

Check Title Severity Provider Fix
SCM-027 Outside collaborator holds write / maintain / admin access HIGH SCM

1.3.10: Ensure SCM administrators control contribution access (deploy keys, write)

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-025 Repo has write-enabled deploy keys (push backdoor) HIGH SCM
SCM-027 Outside collaborator holds write / maintain / admin access HIGH SCM

1.4.1: Ensure administrator approval is required for every installed application

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-021 Actions can approve pull requests (self-approval bypass) HIGH SCM
SCM-022 Repo Actions permissions allow any source (no allow-list) MEDIUM SCM

1.4.3: Ensure the access granted to each installed application is limited

Evidenced by 2 checks across SCM.

Check Title Severity Provider Fix
SCM-020 Default workflow GITHUB_TOKEN has write permission HIGH SCM
SCM-022 Repo Actions permissions allow any source (no allow-list) MEDIUM SCM

1.4.4: Ensure only secured webhooks are used

Evidenced by 1 check across SCM.

Check Title Severity Provider Fix
SCM-026 Webhook ships events insecurely (HTTP / no-TLS / no-secret) HIGH SCM

1.5.1: Ensure scanners are in place to identify and prevent sensitive data in code

Evidenced by 16 checks across 6 providers (CloudFormation, Dockerfile, GitHub Actions, Kubernetes, SCM, Terraform).

Check Title Severity Provider Fix
CF-002 Stateful data-store resource carries a plaintext secret CRITICAL CloudFormation
DF-006 ENV or ARG carries a credential-shaped literal value CRITICAL Dockerfile
DF-019 COPY/ADD source path looks like a credential file HIGH Dockerfile 🔧 fix
DF-020 ARG declares a credential-named build argument HIGH Dockerfile 🔧 fix
GHA-005 AWS auth uses long-lived access keys MEDIUM GitHub Actions 🔧 fix
GHA-033 Secret value echoed / printed in a run: block CRITICAL GitHub Actions
GHA-039 services / container credentials embedded as literal in workflow CRITICAL GitHub Actions
GHA-055 Reusable workflow outputs derive a secret or caller-input value HIGH GitHub Actions
GHA-057 Secret-scanner output sent to network egress CRITICAL GitHub Actions
K8S-017 Container env value carries a credential-shaped literal CRITICAL Kubernetes
K8S-018 Secret stringData/data carries a credential-shaped literal CRITICAL Kubernetes
K8S-037 ConfigMap data carries a credential-shaped literal HIGH Kubernetes
SCM-004 GitHub secret scanning is not enabled HIGH SCM
SCM-015 Secret scanning push protection is not enabled HIGH SCM
SCM-016 Private vulnerability reporting is not enabled LOW SCM
TF-002 Stateful data-store resource carries a plaintext secret CRITICAL Terraform

1.5.2: Ensure scanners are in place to secure CI/CD pipeline instructions

Evidenced by 64 checks across 6 providers (Argo Workflows, Buildkite, GitHub Actions, GitLab CI, SCM, Tekton).

Check Title Severity Provider Fix
GHA-001 Action not pinned to commit SHA HIGH GitHub Actions 🔧 fix
GHA-002 pull_request_target checks out PR head CRITICAL GitHub Actions 🔧 fix
GHA-003 Script injection via untrusted context HIGH GitHub Actions 🔧 fix
GHA-004 Workflow permissions block missing or overprovisioned MEDIUM GitHub Actions 🔧 fix
GHA-005 AWS auth uses long-lived access keys MEDIUM GitHub Actions 🔧 fix
GHA-019 GITHUB_TOKEN written to persistent storage CRITICAL GitHub Actions 🔧 fix
GHA-030 OIDC token requested without environment-protected job HIGH GitHub Actions
GHA-031 Workflow uses retired set-output / save-state command HIGH GitHub Actions 🔧 fix
GHA-032 run: invokes local script on untrusted-trigger workflow CRITICAL GitHub Actions
GHA-033 Secret value echoed / printed in a run: block CRITICAL GitHub Actions
GHA-034 Reusable workflow called with secrets: inherit MEDIUM GitHub Actions 🔧 fix
GHA-035 github-script step interpolates untrusted context HIGH GitHub Actions
GHA-036 runs-on interpolates untrusted context HIGH GitHub Actions 🔧 fix
GHA-037 actions/checkout persists GITHUB_TOKEN into .git/config HIGH GitHub Actions 🔧 fix
GHA-038 Workflow re-enables retired ::set-env / ::add-path commands CRITICAL GitHub Actions
GHA-039 services / container credentials embedded as literal in workflow CRITICAL GitHub Actions
GHA-040 Action reference matches a known-compromised SHA or tag CRITICAL GitHub Actions
GHA-041 Action upstream repo has a single contributor MEDIUM GitHub Actions
GHA-042 Action upstream repo is newly created MEDIUM GitHub Actions
GHA-043 Low-star action runs with sensitive permissions HIGH GitHub Actions
GHA-044 Build tool runs lifecycle scripts on untrusted-trigger workflow HIGH GitHub Actions
GHA-045 Caller-controlled ref input feeds actions/checkout HIGH GitHub Actions
GHA-046 Manual PR-head fetch on untrusted-trigger workflow CRITICAL GitHub Actions
GHA-047 Action ref resolves to a recently committed tag or SHA MEDIUM GitHub Actions
GHA-048 Workflow step writes a file under .github/workflows/ CRITICAL GitHub Actions
GHA-049 Workflow step makes a privileged git write (cross-repo or actions[bot] bypass) HIGH GitHub Actions
GHA-050 Publish step relies on long-lived registry token HIGH GitHub Actions
GHA-051 services / container image is not pinned by digest HIGH GitHub Actions
GHA-052 actions/cache key includes untrusted PR-controllable input HIGH GitHub Actions
GHA-053 if: predicate evaluates attacker-controllable context as expression HIGH GitHub Actions
GHA-054 actions/checkout with ssh-key persists SSH credential in repo HIGH GitHub Actions 🔧 fix
GHA-055 Reusable workflow outputs derive a secret or caller-input value HIGH GitHub Actions
GHA-056 Workflow body contains a known supply-chain worm indicator CRITICAL GitHub Actions
GHA-057 Secret-scanner output sent to network egress CRITICAL GitHub Actions
GHA-058 Agentic CLI invoked with permission-bypass flags HIGH GitHub Actions
GHA-059 npm install without registry-signature verification step MEDIUM GitHub Actions
GHA-060 pip install without --require-hashes verification MEDIUM GitHub Actions
GHA-061 GitHub App token minted without a permissions: filter MEDIUM GitHub Actions
GHA-062 OIDC subject claim in sibling IaC grants overly broad scope HIGH GitHub Actions
GHA-092 PR head SHA captured then re-fetched (force-push race) HIGH GitHub Actions
GHA-093 Living-off-the-Pipeline indicators (workflow-command abuse) HIGH GitHub Actions
GHA-105 Self-hosted runner reachable from an untrusted PR trigger HIGH GitHub Actions
GHA-106 AI agent CLI runs with a write-scoped GITHUB_TOKEN HIGH GitHub Actions
GHA-110 Workflow disables Go module checksum / sum-db verification HIGH GitHub Actions
GHA-111 AI agent generates IaC applied to the cloud in the same job HIGH GitHub Actions
GHA-112 Self-hosted deploy job not gated by a protected environment HIGH GitHub Actions
GHA-113 OIDC trusted-publishing job without an environment gate HIGH GitHub Actions
GHA-114 Package-publish workflow runs on an unrestricted push trigger HIGH GitHub Actions
GHA-116 Workflow serializes the entire secrets context (toJSON(secrets)) HIGH GitHub Actions
GHA-117 IaC apply on an untrusted pull_request trigger CRITICAL GitHub Actions
GHA-118 Untrusted content written to $GITHUB_ENV / $GITHUB_PATH HIGH GitHub Actions
GHA-119 Untrusted context reaches an agentic AI CLI (prompt injection) HIGH GitHub Actions
GHA-120 ML model loaded with trust_remote_code (code execution) HIGH GitHub Actions
GHA-122 Unsafe deserialization of a fetched artifact (pickle RCE) HIGH GitHub Actions
SCM-020 Default workflow GITHUB_TOKEN has write permission HIGH SCM
SCM-041 Active ruleset doesn't gate on a deployment environment LOW SCM
TAINT-001 Untrusted input flows across step boundaries via step outputs HIGH GitHub Actions
TAINT-002 Untrusted input flows across jobs via jobs.<id>.outputs: HIGH GitHub Actions
TAINT-003 Untrusted input forwarded into reusable workflow with: HIGH GitHub Actions
TAINT-004 Untrusted input flows across jobs via dotenv artifact HIGH GitLab CI
TAINT-005 Untrusted input flows across steps via buildkite-agent meta-data HIGH Buildkite
TAINT-006 Untrusted input flows across tasks via Tekton results HIGH Tekton
TAINT-007 Untrusted input flows across templates via Argo outputs.parameters HIGH Argo Workflows
TAINT-008 Untrusted input flows via GitLab extends: template inheritance HIGH GitLab CI

1.5.3: Ensure scanners are in place to secure IaC instructions

Evidenced by 26 checks across 4 providers (CloudFormation, Dockerfile, Kubernetes, Terraform).

Check Title Severity Provider Fix
CF-001 Template declares AWS::IAM::AccessKey (long-lived credential) CRITICAL CloudFormation
CF-002 Stateful data-store resource carries a plaintext secret CRITICAL CloudFormation
CF-003 CodeBuild project's VPC contains a public subnet HIGH CloudFormation
DF-001 FROM image not pinned to sha256 digest HIGH Dockerfile 🔧 fix
DF-005 RUN uses shell-eval (eval / sh -c on a variable / backticks) HIGH Dockerfile
DF-006 ENV or ARG carries a credential-shaped literal value CRITICAL Dockerfile
DF-008 RUN invokes docker --privileged or escalates capabilities HIGH Dockerfile
DF-019 COPY/ADD source path looks like a credential file HIGH Dockerfile 🔧 fix
DF-020 ARG declares a credential-named build argument HIGH Dockerfile 🔧 fix
DF-021 RUN pip install bypasses TLS or uses an HTTP index HIGH Dockerfile
DF-024 RUN npm/yarn/pnpm install runs lifecycle scripts HIGH Dockerfile
DF-026 ENV disables Node.js TLS certificate verification HIGH Dockerfile
DF-027 ENV disables Python HTTPS certificate verification HIGH Dockerfile
DF-028 ENV disables Git TLS certificate verification HIGH Dockerfile
DF-029 ENV neuters Python requests CA bundle HIGH Dockerfile
DF-031 COPY --from external image not pinned to sha256 digest HIGH Dockerfile
K8S-001 Container image not pinned by sha256 digest HIGH Kubernetes 🔧 fix
K8S-002 Pod hostNetwork: true HIGH Kubernetes 🔧 fix
K8S-005 Container securityContext.privileged: true CRITICAL Kubernetes 🔧 fix
K8S-013 Pod uses a hostPath volume HIGH Kubernetes 🔧 fix
K8S-017 Container env value carries a credential-shaped literal CRITICAL Kubernetes
K8S-018 Secret stringData/data carries a credential-shaped literal CRITICAL Kubernetes
K8S-037 ConfigMap data carries a credential-shaped literal HIGH Kubernetes
TF-001 Plan declares aws_iam_access_key (long-lived credential) HIGH Terraform
TF-002 Stateful data-store resource carries a plaintext secret CRITICAL Terraform
TF-003 CodeBuild VPC config references a public subnet HIGH Terraform

1.5.4: Ensure scanners are in place to identify and confirm presence of vulnerabilities

Evidenced by 8 checks across 3 providers (AWS, GitHub Actions, SCM).

Check Title Severity Provider Fix
ECR-001 Image scanning on push not enabled HIGH AWS
ECR-007 Inspector v2 enhanced scanning disabled for ECR MEDIUM AWS
GHA-020 No vulnerability scanning step MEDIUM GitHub Actions
SCM-003 GitHub default code scanning is not enabled MEDIUM SCM
SCM-005 Dependabot security updates are not enabled MEDIUM SCM
SCM-045 Default code scanning uses the limited query suite LOW SCM
SCM-046 Default code scanning is configured but paused MEDIUM SCM
SCM-047 Repo language excluded from default code-scanning coverage MEDIUM SCM

Not covered

Org-admin controls that require account-level audit endpoints, MFA enforcement (1.3.4), member inventories (1.3.1), installed-app lists (1.4.2), and similar — are listed in the benchmark but not yet evidenced by an SCM-* rule. Open an issue if your team would value coverage; the GitHub Admin API surface is the next planned expansion of the SCM provider.


This page is generated. Edit pipeline_check/core/standards/data/cis_github.py (mappings) or scripts/gen_standards_docs.py (intro / per-control prose) and run python scripts/gen_standards_docs.py cis_github.