CIS GitHub Enterprise Benchmark
Security configuration recommendations for GitHub Enterprise Server and Cloud
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for GitHub Enterprise. It covers organization authentication, repository security, Actions CI/CD hardening, dependency and code scanning, secret management, audit logging, and integration security using the GitHub REST API and GHES administration.
| Section | Area | Focus |
|---|---|---|
| 1 | Organization Authentication | 2FA enforcement, SAML SSO, and admin privilege minimization |
| 2 | Repository Security | Default permissions, branch protection, and access controls |
| 3 | Actions & CI/CD Security | Action restrictions, runner groups, and workflow hardening |
| 4 | Dependency & Code Scanning | Dependabot alerts, CodeQL analysis, and vulnerability management |
| 5 | Secret Management | Secret scanning, push protection, and deploy key restrictions |
| 6 | Audit & Compliance | Audit log streaming, IP allow lists, and compliance monitoring |
| 7 | Integration Security | Webhook TLS, OAuth app restrictions, and third-party access control |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all GitHub Enterprise deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Organization Authentication
▶1.1 Identity & Access
▶This recommendation ensures that two-factor authentication is required for all members on the GitHub Enterprise source code management platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the GitHub Enterprise source code management platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check organization 2FA requirement:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG | \
jq '{two_factor_requirement_enabled}'# Enforce 2FA for all organization members:
curl -s -X PATCH -H "Authorization: Bearer $GH_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"two_factor_requirement_enabled": true}' \
https://api.github.com/orgs/$ORGThis recommendation verifies that SAML single sign-on is configured on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check SAML SSO status:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG | \
jq '{saml_enabled: .plan.filled_seats}' # Enterprise: check GHES admin
# GHES: Check SAML via Management Console
gh api /admin/saml -H 'Accept: application/json'# Enable SAML SSO (GHES Management Console): # Navigate to: https://HOSTNAME/setup/settings # Authentication > SAML > Enable SAML authentication # SSO URL: https://idp.example.com/sso # Issuer: https://idp.example.com # Upload IdP public certificate
This setting ensures that organization admin count is minimized on the GitHub Enterprise source code management platform. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the GitHub Enterprise source code management platform is essential for defense in depth.
# List organization owners: curl -s -H "Authorization: Bearer $GH_TOKEN" \ 'https://api.github.com/orgs/$ORG/members?role=admin' | \ jq '.[].login' # Audit outside collaborators: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/orgs/$ORG/outside_collaborators | \ jq '.[].login'
# Remove unnecessary admin users:
curl -s -X PUT -H "Authorization: Bearer $GH_TOKEN" \
-d '{"role": "member"}' \
https://api.github.com/orgs/$ORG/memberships/$USERNAME
# Remove outside collaborators:
curl -s -X DELETE -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG/outside_collaborators/$USERNAME2 — Repository Security
▶2.1 Repository Configuration
▶This recommendation verifies that default repository permissions are set to read on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check repository visibility defaults:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG | \
jq '{default_repository_permission, members_can_create_public_repositories}'# Restrict default repository permissions:
curl -s -X PATCH -H "Authorization: Bearer $GH_TOKEN" \
-d '{"default_repository_permission": "read", "members_can_create_public_repositories": false}' \
https://api.github.com/orgs/$ORGThis recommendation ensures that branch protection rules are enforced on default branches on the GitHub Enterprise source code management platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.
Without this enforcement, the GitHub Enterprise source code management platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.
# Check branch protection rules:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/$ORG/$REPO/branches/main/protection | \
jq '{enforce_admins: .enforce_admins.enabled, required_reviews: .required_pull_request_reviews.required_approving_review_count, status_checks: .required_status_checks.strict}'# Enable branch protection on main:
curl -s -X PUT -H "Authorization: Bearer $GH_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"required_status_checks":{"strict":true,"contexts":["ci/build"]},"enforce_admins":true,"required_pull_request_reviews":{"required_approving_review_count":2,"dismiss_stale_reviews":true},"restrictions":null}' \
https://api.github.com/repos/$ORG/$REPO/branches/main/protection3 — Actions & CI/CD Security
▶3.1 Workflow Security
▶This setting ensures that GitHub Actions are restricted to selected actions on the GitHub Enterprise source code management platform. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the GitHub Enterprise source code management platform is essential for defense in depth.
# List GitHub Actions workflow permissions: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/orgs/$ORG/actions/permissions | \ jq . # Check allowed actions: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/orgs/$ORG/actions/permissions/selected-actions | jq .
# Restrict Actions to selected actions only:
curl -s -X PUT -H "Authorization: Bearer $GH_TOKEN" \
-d '{"enabled_repositories": "all", "allowed_actions": "selected"}' \
https://api.github.com/orgs/$ORG/actions/permissions
# Allow only verified creators:
curl -s -X PUT -H "Authorization: Bearer $GH_TOKEN" \
-d '{"github_owned_allowed": true, "verified_allowed": true, "patterns_allowed": []}' \
https://api.github.com/orgs/$ORG/actions/permissions/selected-actionsThis recommendation verifies that self-hosted runners are not used for public repositories on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check self-hosted runner groups:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG/actions/runner-groups | \
jq '.runner_groups[] | {name, visibility, allows_public_repositories}'# Restrict runner groups to private repos:
curl -s -X PATCH -H "Authorization: Bearer $GH_TOKEN" \
-d '{"name": "production-runners", "visibility": "selected", "allows_public_repositories": false}' \
https://api.github.com/orgs/$ORG/actions/runner-groups/$RUNNER_GROUP_ID4 — Dependency & Code Scanning
▶4.1 Vulnerability Management
▶This recommendation verifies that Dependabot alerts and security updates are enabled on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Dependabot alerts: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/repos/$ORG/$REPO/vulnerability-alerts -I | grep HTTP # Check security advisories: curl -s -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/repos/$ORG/$REPO/dependabot/alerts?state=open | \ jq '.[].security_advisory.severity' | sort | uniq -c
# Enable Dependabot alerts and updates:
curl -s -X PUT -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/$ORG/$REPO/vulnerability-alerts
# Create dependabot.yml:
mkdir -p .github && cat > .github/dependabot.yml <<'EOF'
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
EOFThis recommendation verifies that CodeQL code scanning is configured on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check code scanning alerts:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/$ORG/$REPO/code-scanning/alerts?state=open | \
jq '.[].rule | {id, severity, description}'# Enable CodeQL analysis:
mkdir -p .github/workflows && cat > .github/workflows/codeql.yml <<'EOF'
name: CodeQL
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with:
languages: javascript
- uses: github/codeql-action/analyze@v3
EOF5 — Secret Management
▶5.1 Secret Protection
▶This recommendation verifies that secret scanning and push protection are enabled on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check secret scanning status:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/$ORG/$REPO | \
jq '{security_and_analysis: .security_and_analysis}'# Enable secret scanning and push protection:
curl -s -X PATCH -H "Authorization: Bearer $GH_TOKEN" \
-d '{"security_and_analysis":{"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"}}}' \
https://api.github.com/repos/$ORG/$REPOThis recommendation verifies that deploy keys are read-only on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List deploy keys:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/repos/$ORG/$REPO/keys | \
jq '.[] | {id, title, read_only, created_at}'# Create read-only deploy key:
ssh-keygen -t ed25519 -C "deploy-key" -f deploy_key -N ""
curl -s -X POST -H "Authorization: Bearer $GH_TOKEN" \
-d '{"title": "CI/CD deploy key", "key": "'$(cat deploy_key.pub)'", "read_only": true}' \
https://api.github.com/repos/$ORG/$REPO/keys6 — Audit & Compliance
▶6.1 Logging & Access Control
▶This recommendation verifies that audit log streaming is configured on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check audit log (Enterprise):
curl -s -H "Authorization: Bearer $GH_TOKEN" \
'https://api.github.com/orgs/$ORG/audit-log?per_page=5' | \
jq '.[] | {action, actor, created_at}'# Configure audit log streaming (GHES):
# Site Admin > Audit log > Log streaming
# Supported: Azure Blob, AWS S3, Splunk, Google Cloud Storage
# Set retention: minimum 180 days
# API: Enable audit log streaming:
curl -s -X POST -H "Authorization: Bearer $GH_TOKEN" \
-d '{"enabled": true, "stream": {"type": "s3", "bucket": "gh-audit-logs", "region": "us-east-1"}}' \
https://api.github.com/admin/audit-log/streamThis recommendation verifies that IP allow lists are configured for the organization on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check IP allow list:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG/ip-allow-list | \
jq '.[] | {allow_list_value, name, is_active}'# Add IP allow list entry:
curl -s -X POST -H "Authorization: Bearer $GH_TOKEN" \
-d '{"allow_list_value": "10.0.0.0/8", "name": "Corporate VPN", "is_active": true}' \
https://api.github.com/orgs/$ORG/ip-allow-list7 — Integration Security
▶7.1 Webhooks & OAuth
▶This recommendation verifies that webhooks use HTTPS and secrets on the GitHub Enterprise source code management platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the GitHub Enterprise source code management platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check webhook configurations:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG/hooks | \
jq '.[] | {url: .config.url, insecure_ssl: .config.insecure_ssl, active}'# Configure webhook with secret and TLS:
curl -s -X POST -H "Authorization: Bearer $GH_TOKEN" \
-d '{"name": "web", "active": true, "events": ["push", "pull_request"], "config": {"url": "https://hooks.example.com/github", "content_type": "json", "secret": "WEBHOOK_SECRET", "insecure_ssl": "0"}}' \
https://api.github.com/orgs/$ORG/hooksThis setting ensures that third-party OAuth application access is restricted on the GitHub Enterprise source code management platform. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the GitHub Enterprise source code management platform is essential for defense in depth.
# Check OAuth app authorizations:
curl -s -H "Authorization: Bearer $GH_TOKEN" \
https://api.github.com/orgs/$ORG/credential-authorizations | \
jq '.[] | {login, credential_type, authorized_credential_title}'# Review and restrict OAuth apps: # Organization > Settings > Third-party access > OAuth application policy # Set to: Restrict access # Review pending requests and revoke unnecessary apps # Revoke credential authorization: curl -s -X DELETE -H "Authorization: Bearer $GH_TOKEN" \ https://api.github.com/orgs/$ORG/credential-authorizations/$CREDENTIAL_ID