For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/cicd-github-overprovisioned-secrets.md.
A documentation index is available at /llms.txt.
Referencing the entire GitHub Actions secrets context or using dynamic/non-literal secret indexing exposes all repository secrets to the workflow runner. If a workflow or runner is compromised, an attacker could read every secret instead of only the ones required by the job.
This rule flags expression patterns that serialize or expand the secrets object—specifically calls to toJSON(secrets) and context accesses like secrets[<non-literal>] where the index is not a literal string or number. Reference required secrets explicitly by literal property names, such as secrets.MY_SECRET. Expressions that call toJSON(secrets) or use non-literal secret indices will be flagged.
name:Proper Secret Usageon:pushjobs:deploy:runs-on:ubuntu-latest# Proper: individual secret in job-level envenv:DEPLOY_TOKEN:${{ secrets.DEPLOY_TOKEN }}API_KEY:${{ secrets.API_KEY }}# Proper: individual secret check in job-level ifif:${{ secrets.DEPLOY_TOKEN != '' }}steps:# Proper: individual secrets in step run block- name:Deploy with specific secretrun:| curl -H "Authorization: Bearer ${{ secrets.DEPLOY_TOKEN }}" \
-H "API-Key: ${{ secrets.API_KEY }}" \
https://api.example.com/deploy# Proper: individual secret in step-level if- name:Conditional deploymentif:${{ secrets.PRODUCTION_KEY != '' }}run:echo "Deploying to production"# Proper: individual secrets in step env block- name:Step with environment variablesenv:DB_PASSWORD:${{ secrets.DB_PASSWORD }}SMTP_PASSWORD:${{ secrets.SMTP_PASSWORD }}run:echo "Configured environment"# Proper: individual secret in step with block- name:Use action with secretuses:some/action@v1with:token:${{ secrets.GITHUB_TOKEN }}api_key:${{ secrets.API_KEY }}# Proper: matrix with literal values (not dynamic secret indexing)- name:Deploy to environmentrun:echo "Deploying with ${{ secrets.DEPLOY_TOKEN }}"# Proper: toJSON on non-secret contexts- name:Use toJSON on envrun:echo '${{ toJSON(env) }}'# Proper: toJSON on github context- name:Use toJSON on github contextrun:echo '${{ toJSON(github.event) }}'
Non-Compliant Code Examples
name:Overprovisioned Secretson:pushjobs:deploy:runs-on:ubuntu-latest# toJSON(secrets) in job-level env blockenv:ALL_SECRETS:${{ toJSON(secrets) }}# toJSON(secrets) in job-level if conditionif:${{ toJSON(secrets) != '{}' }}steps:# toJSON(secrets) in step run block- name:Export all secretsrun:echo '${{ toJSON(secrets) }}'# Dynamic secret indexing in step run block- name:Dynamic secret accessrun:| SECRET_NAME="DEPLOY_TOKEN_${{ matrix.env }}"
echo ${{ secrets[format('DEPLOY_TOKEN_{0}', matrix.env)] }}# toJSON(secrets) in step-level if condition- name:Check secrets with toJSONif:${{ toJSON(secrets) != '{}' }}run:echo "Has secrets"# Dynamic secret indexing in step-level if condition- name:Check dynamic secretif:${{ secrets[format('KEY_{0}', github.event.inputs.env)] != '' }}run:echo "Secret exists"# toJSON(secrets) in step env block- name:Step with env secretsenv:SECRETS_JSON:${{ toJSON(secrets) }}run:echo "Processing secrets"# Dynamic indexing in step env block- name:Step with dynamic envenv:DYNAMIC_SECRET:${{ secrets[github.event.inputs.secret_name] }}run:echo "Using dynamic secret"# toJSON(secrets) in step with block- name:Action with toJSON secretsuses:some/action@v1with:config:${{ toJSON(secrets) }}# Dynamic indexing in step with block- name:Action with dynamic secretuses:another/action@v1with:token:${{ secrets[matrix.secret_key] }}another-job:runs-on:ubuntu-latest# Dynamic indexing in job-level env blockenv:TOKEN:${{ secrets[format('TOKEN_{0}', github.ref_name)] }}# Dynamic indexing in job-level if conditionif:${{ secrets[github.event.inputs.key] != '' }}steps:- run:echo "Running"
name:dogfood-overprovisioned-secrets-noncompliant-workflow-envon:workflow_dispatch:{}env:ALL_SECRETS:${{ toJSON(secrets) }}DYNAMIC_SECRET:${{ secrets[matrix.secret_key] }}jobs:deploy:runs-on:ubuntu-lateststeps:- run:echo "inherits env; entire secrets JSON is available to the job"
1
2
rulesets:- CICD / GitHub # Rules to enforce / GitHub.
Request a personalized demo
Get Started with Datadog
Ask AI
AI-generated responses may be inaccurate. Verify important info.