Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 125 additions & 82 deletions compliance/frameworks/cis_azure_benchmark.json

Large diffs are not rendered by default.

60 changes: 15 additions & 45 deletions compliance/frameworks/iso27001.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,55 +570,25 @@
"control_name": "Reporting information security events",
"description": "No monitored destination exists for security alerts or Sentinel incidents. A.16.1.2 requires information security events to be reported through appropriate management channels as quickly as possible; an alert with no notified recipient cannot be reported or acted on."
},
"AZ-NET-018": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "PaaS resources using Private Link should not retain unnecessary public network exposure."
},
"AZ-NET-019": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Private Endpoint connections must be approved and operational."
},
"AZ-NET-020": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Private Endpoints require an associated service-appropriate Private DNS zone."
},
"AZ-NET-021": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Private Endpoint FQDNs must resolve to private addresses through the controlled network path."
},
"AZ-NET-022": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Critical PaaS resources restrict public exposure unless an approved exception exists."
"AZ-CI-001": {
"control_id": "A.9.2.4",
"control_name": "CI/CD Workflow Uses Long-Lived Azure Credentials",
"description": "CI/CD workflows should use workload identity federation (OIDC) instead of long-lived client secrets or storage keys stored as repository secrets."
},
"AZ-NET-023": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Azure Firewall denies traffic identified by Microsoft threat intelligence."
},
"AZ-NET-024": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Application Gateway WAF operates in Prevention mode at the application boundary."
"AZ-CI-002": {
"control_id": "A.9.2.3",
"control_name": "CI/CD Workflow Has Unnecessarily Broad Token Permissions",
"description": "Workflow GITHUB_TOKEN permissions should follow least privilege with an explicit permissions block granting only required scopes."
},
"AZ-NET-025": {
"control_id": "A.12.4.1",
"control_name": "Event logging",
"description": "Application Gateway WAF diagnostic categories are exported to an approved monitoring destination."
"AZ-CI-003": {
"control_id": "A.12.1.2",
"control_name": "Third-Party Workflow Action Not Pinned to Immutable Commit SHA",
"description": "Third-party GitHub Actions must be pinned to a full 40-character commit SHA to prevent supply-chain attacks via mutable tags."
},
"AZ-NET-026": {
"AZ-CI-004": {
"control_id": "A.14.2.5",
"control_name": "Secure system engineering principles",
"description": "Current managed application and bot rules are maintained at the web perimeter."
},
"AZ-NET-027": {
"control_id": "A.13.1.1",
"control_name": "Network controls",
"description": "Rate limiting protects internet-facing application entry points."
"control_name": "Untrusted Pull-Request Input Reaches Privileged Workflow Context",
"description": "Workflows triggered by pull_request_target or workflow_run must not check out or execute untrusted PR code in a context with secret access."
}
}
}
62 changes: 16 additions & 46 deletions compliance/frameworks/nist_csf.json
Original file line number Diff line number Diff line change
Expand Up @@ -570,55 +570,25 @@
"control_name": "Incidents are reported consistent with established criteria",
"description": "No monitored destination exists for security alerts or Sentinel incidents. RS.CO-2 requires incidents to be reported consistent with established criteria; an alert with no notified recipient is never reported to anyone who can act on it."
},
"AZ-NET-018": {
"control_id": "PR.AC-3",
"control_name": "Remote access is managed",
"description": "Disabling unnecessary public access ensures the Private Endpoint is the managed remote access path."
},
"AZ-NET-019": {
"control_id": "PR.AC-5",
"control_name": "Network integrity is protected",
"description": "Approved Private Endpoint connections preserve the intended private network boundary."
},
"AZ-NET-020": {
"control_id": "PR.AC-5",
"control_name": "Network integrity is protected",
"description": "Private DNS zone association directs service names through the intended private endpoint path."
},
"AZ-NET-021": {
"control_id": "PR.AC-5",
"control_name": "Network integrity is protected",
"description": "Private address resolution provides evidence that service traffic follows the private network boundary."
},
"AZ-NET-022": {
"control_id": "PR.AC-3",
"control_name": "Remote access is managed",
"description": "Critical PaaS public access is disabled unless an explicit approved exception exists."
},
"AZ-NET-023": {
"control_id": "DE.CM-1",
"control_name": "The network is monitored",
"description": "Azure Firewall threat intelligence alerts on and denies traffic involving known malicious infrastructure."
},
"AZ-NET-024": {
"control_id": "PR.PT-4",
"control_name": "Communications and control networks are protected",
"description": "Application Gateway WAF Prevention mode actively blocks matching application attacks."
"AZ-CI-001": {
"control_id": "PR.AC-1",
"control_name": "CI/CD Workflow Uses Long-Lived Azure Credentials",
"description": "CI/CD workflows should use workload identity federation (OIDC) instead of long-lived client secrets or storage keys stored as repository secrets."
},
"AZ-NET-025": {
"control_id": "DE.CM-1",
"control_name": "The network is monitored",
"description": "Application Gateway access, performance, and firewall logs provide perimeter monitoring evidence."
"AZ-CI-002": {
"control_id": "PR.AC-4",
"control_name": "CI/CD Workflow Has Unnecessarily Broad Token Permissions",
"description": "Workflow GITHUB_TOKEN permissions should follow least privilege with an explicit permissions block granting only required scopes."
},
"AZ-NET-026": {
"control_id": "PR.PT-4",
"control_name": "Communications and control networks are protected",
"description": "Current base and bot managed rules protect the web application perimeter."
"AZ-CI-003": {
"control_id": "PR.IP-1",
"control_name": "Third-Party Workflow Action Not Pinned to Immutable Commit SHA",
"description": "Third-party GitHub Actions must be pinned to a full 40-character commit SHA to prevent supply-chain attacks via mutable tags."
},
"AZ-NET-027": {
"control_id": "PR.PT-4",
"control_name": "Communications and control networks are protected",
"description": "Rate-limit rules protect internet-facing applications from abusive request volume."
"AZ-CI-004": {
"control_id": "PR.AC-4",
"control_name": "Untrusted Pull-Request Input Reaches Privileged Workflow Context",
"description": "Workflows triggered by pull_request_target or workflow_run must not check out or execute untrusted PR code in a context with secret access."
}
}
}
64 changes: 17 additions & 47 deletions compliance/frameworks/soc2.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
"AZ-DB-004": {
"control_id": "CC6.6",
"control_name": "Restricts Access from Outside the Network Boundary",
"description": "Enabling 'Allow access to Azure services' on a SQL Server firewall creates a rule that permits any Azure-hosted resource including services from other tenants to connect to the database. CC6.6 requires that access from outside the network boundary is restricted to authorised sources. Disabling this setting and replacing it with explicit firewall rules or private endpoints enforces the network boundary and ensures only known and trusted systems can reach the SQL Server."
"description": "Enabling 'Allow access to Azure services' on a SQL Server firewall creates a rule that permits any Azure-hosted resource \u2014 including services from other tenants \u2014 to connect to the database. CC6.6 requires that access from outside the network boundary is restricted to authorised sources. Disabling this setting and replacing it with explicit firewall rules or private endpoints enforces the network boundary and ensures only known and trusted systems can reach the SQL Server."
},
"AZ-IDN-004": {
"control_id": "CC6.3",
Expand Down Expand Up @@ -570,55 +570,25 @@
"control_name": "Incident Response",
"description": "No monitored destination exists for security alerts or Sentinel incidents. CC7.4 requires the entity to respond to identified security incidents; an alert nobody is notified of cannot trigger the incident-response process CC7.4 requires."
},
"AZ-NET-018": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Private Link targets restrict unnecessary public network access."
},
"AZ-NET-019": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Private Endpoint connections are approved and operational before they are relied upon as an access boundary."
},
"AZ-NET-020": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Private DNS association preserves the approved private access path."
},
"AZ-NET-021": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Private Endpoint service names resolve to private addresses within the approved access boundary."
},
"AZ-NET-022": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Critical PaaS resources restrict public access unless an approved exception exists."
},
"AZ-NET-023": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Azure Firewall denies traffic involving infrastructure identified by threat intelligence."
},
"AZ-NET-024": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Application Gateway WAF Prevention mode blocks matching malicious requests."
"AZ-CI-001": {
"control_id": "CC6.1",
"control_name": "CI/CD Workflow Uses Long-Lived Azure Credentials",
"description": "CI/CD workflows should use workload identity federation (OIDC) instead of long-lived client secrets or storage keys stored as repository secrets."
},
"AZ-NET-025": {
"control_id": "CC7.2",
"control_name": "System monitoring",
"description": "Application Gateway access, performance, and firewall logs support anomaly monitoring."
"AZ-CI-002": {
"control_id": "CC6.3",
"control_name": "CI/CD Workflow Has Unnecessarily Broad Token Permissions",
"description": "Workflow GITHUB_TOKEN permissions should follow least privilege with an explicit permissions block granting only required scopes."
},
"AZ-NET-026": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Current application and bot managed rules protect the logical access boundary."
"AZ-CI-003": {
"control_id": "CC7.1",
"control_name": "Third-Party Workflow Action Not Pinned to Immutable Commit SHA",
"description": "Third-party GitHub Actions must be pinned to a full 40-character commit SHA to prevent supply-chain attacks via mutable tags."
},
"AZ-NET-027": {
"control_id": "CC6.6",
"control_name": "Logical Access Security Measures",
"description": "Rate-limit rules protect public application access from abusive request volume."
"AZ-CI-004": {
"control_id": "CC8.1",
"control_name": "Untrusted Pull-Request Input Reaches Privileged Workflow Context",
"description": "Workflows triggered by pull_request_target or workflow_run must not check out or execute untrusted PR code in a context with secret access."
}
}
}
32 changes: 32 additions & 0 deletions playbooks/cli/fix_az_ci_001.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Fix AZ-CI-001: Replace long-lived Azure credentials with workload identity federation
# Usage: bash fix_az_ci_001.sh <AZURE_APP_ID> <TENANT_ID> <SUBSCRIPTION_ID> <REPO>
set -euo pipefail
APP_ID="${1:?Usage: $0 <app-id> <tenant-id> <subscription-id> <repo>}"
TENANT_ID="${2:?}"
SUBSCRIPTION_ID="${3:?}"
REPO="${4:?}"

echo "[1/4] Creating federated identity credential for GitHub Actions..."
az ad app federated-credential create \
--id "$APP_ID" \
--parameters "{
\"name\": \"github-oidc\",
\"issuer\": \"https://token.actions.githubusercontent.com\",
\"subject\": \"repo:${REPO}:ref:refs/heads/main\",
\"audiences\": [\"api://AzureADTokenExchange\"]
}"

echo "[2/4] Update workflow: add id-token: write permission"
echo " Replace azure/login with:"
echo " - uses: azure/login@v2"
echo " with:"
echo " client-id: \${{ secrets.AZURE_CLIENT_ID }}"
echo " tenant-id: \${{ secrets.AZURE_TENANT_ID }}"
echo " subscription-id: \${{ secrets.AZURE_SUBSCRIPTION_ID }}"

echo "[3/4] Remove AZURE_CLIENT_SECRET from repository secrets"
gh secret delete AZURE_CLIENT_SECRET --repo "$REPO" 2>/dev/null || true
gh secret delete ARM_CLIENT_SECRET --repo "$REPO" 2>/dev/null || true

echo "[4/4] Done. Validate with: az login --federated-token"
14 changes: 14 additions & 0 deletions playbooks/cli/fix_az_ci_002.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# Fix AZ-CI-002: Add least-privilege permissions block to workflow
# Usage: bash fix_az_ci_002.sh <workflow-file>
set -euo pipefail
WORKFLOW="${1:?Usage: $0 <path-to-workflow.yml>}"

echo "[INFO] Add the following to the top level of $WORKFLOW:"
echo ""
echo "permissions:"
echo " contents: read"
echo ""
echo "[INFO] Override per-job only where broader access is needed."
echo "[INFO] Never use permissions: write-all in production workflows."
echo "[INFO] See: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs"
20 changes: 20 additions & 0 deletions playbooks/cli/fix_az_ci_003.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Fix AZ-CI-003: Pin third-party actions to immutable commit SHAs
# Usage: bash fix_az_ci_003.sh <workflow-file>
set -euo pipefail
WORKFLOW="${1:?Usage: $0 <path-to-workflow.yml>}"

echo "[INFO] For each unpinned action in $WORKFLOW, replace the tag with a full SHA:"
echo " Before: uses: actions/checkout@v4"
echo " After: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2"
echo ""
echo "[INFO] Use pin-github-action to automate:"
echo " pip install pin-github-action"
echo " pin-github-action $WORKFLOW"
echo ""
echo "[INFO] Enable Dependabot to keep pinned SHAs updated:"
echo " Add to .github/dependabot.yml:"
echo " - package-ecosystem: github-actions"
echo " directory: /"
echo " schedule:"
echo " interval: weekly"
20 changes: 20 additions & 0 deletions playbooks/cli/fix_az_ci_004.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Fix AZ-CI-004: Prevent untrusted PR code from reaching privileged context
# Usage: bash fix_az_ci_004.sh
set -euo pipefail

echo "[INFO] For pull_request_target workflows that check out PR code:"
echo ""
echo "[1/3] Never use actions/checkout with PR head ref in pull_request_target:"
echo " Remove: ref: \${{ github.event.pull_request.head.sha }}"
echo ""
echo "[2/3] Split privileged and unprivileged steps:"
echo " - Untrusted build: triggered by pull_request (no secrets)"
echo " - Privileged deploy: triggered by workflow_run on completed build"
echo ""
echo "[3/3] If checkout of PR code is required, remove all secret access:"
echo " permissions:"
echo " contents: read"
echo " env: {} # no secrets"
echo ""
echo "[INFO] See: https://securitylab.github.com/research/github-actions-preventing-pwn-requests/"
Loading
Loading