Workflow exposes all its secrets at once
Control: Workflows must not expose all secrets at once· Config key: workflowMustNotExportEntireSecretsContext
📋 What is this?
A GitHub Actions workflow serialises the whole secrets context with toJson(secrets) or toJSON(secrets) and pipes the result into a step's environment, run: script, or with: input. The resulting string contains every secret the job has access to (repository, organisation and environment) and travels through whatever downstream consumer the step passes it to (a third-party action, a remote server, a log line). Even with GitHub's automatic log redaction, a single echo of the JSON payload has been enough to leak tokens in past supply-chain incidents; a compromised reusable action sees them directly regardless of logging.
⚠️ Impact
GitHub's redactor masks known secret strings in logs. A toJson(secrets) dump produces a single JSON value containing every secret as a substring of a larger string; the redactor does not recognise the wrapping and the secrets leak verbatim. The risk compounds when the dump is forwarded to anything outside GitHub's runtime: a curl, a docker run, a scratch file picked up by an artifact upload.
🔧 How to fix
Pass only the specific secrets the step needs, by name: env: { TOKEN: ${{ secrets.NPM_TOKEN }} }. If the step forwards credentials to a reusable workflow, name each one in the secrets: block of the call rather than using toJson(secrets) or secrets: inherit.
# .github/workflows/deploy.yml: ❌ Aggregated secrets dumpjobs: deploy: runs-on: ubuntu-latest steps: - env: ALL_SECRETS: ${{ toJson(secrets) }} run: echo "$ALL_SECRETS" > /tmp/sec.json && ./debug.sh /tmp/sec.json# .github/workflows/deploy.yml: ✅ Scoped per-secretjobs: deploy: runs-on: ubuntu-latest steps: - env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: aws s3 sync . s3://my-bucket
# .plumber.yamlgithub: controls: workflowMustNotExportEntireSecretsContext: enabled: true💡 Tips
- Same shape as ISSUE-213 (github-context dump) but with secrets, so it is one severity higher.
- If you genuinely need to enumerate secrets (rare), do it inside an
environment:with a required reviewer and revoke afterward.
⚙️ Configuration
This control is configured in .plumber.yaml under the github section:
github:
controls:
workflowMustNotExportEntireSecretsContext:
enabled: trueSee the CLI documentation for the full configuration reference.