secrets
Detects hardcoded secrets and sensitive information in workflow files.
Why This Matters
Hardcoded secrets in workflow files:
- Expose credentials publicly: GitHub repos (even private ones) may become public
- Cannot be rotated easily: Changing requires updating all workflow files
- Appear in logs: May be printed in workflow run logs
- Violate security policies: Most organizations prohibit hardcoded secrets
What It Detects
| Pattern | Description |
|---|---|
| AWS Access Keys | AKIA... pattern |
| AWS Secret Keys | 40-character base64 strings after aws_secret |
| GitHub Tokens | ghp_, gho_, ghu_, ghs_, ghr_ prefixes |
| Private Keys | -----BEGIN ... PRIVATE KEY----- |
| Generic API Keys | api_key, apikey, api-key with values |
| Generic Secrets | secret, password, token with values |
Example Output
ci.yml:15: (secrets) Possible hardcoded AWS access key detected
ci.yml:22: (secrets) Possible hardcoded GitHub token detected
ci.yml:30: (secrets) Possible hardcoded private key detected
Auto-fix
Not supported - Secrets must be removed and replaced with proper secret references manually.
How to Fix
Use GitHub Secrets
# Bad
env:
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
# Good
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
Use Environment Secrets
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Uses secrets from 'production' environment
steps:
- run: deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }}
Use OIDC for Cloud Providers
For AWS, Azure, and GCP, use OIDC instead of long-lived credentials:
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/my-role
aws-region: us-east-1
Common Patterns Detected
AWS Credentials
# Detected as potential secret
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
GitHub Tokens
# Detected as potential secret
GITHUB_TOKEN: ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
API Keys
# Detected as potential secret
api_key: sk-1234567890abcdef
API_KEY: "some-secret-value"
Private Keys
# Detected as potential secret
SSH_KEY: |
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
-----END RSA PRIVATE KEY-----
False Positives
Some patterns may trigger false positives:
- Example/placeholder values in comments
- Base64-encoded non-secret data
- Test fixtures with fake credentials
If you encounter false positives, you can:
- Disable the secrets linter for specific projects
- Use obviously fake values in examples (e.g.,
AKIAEXAMPLE123456789)
Security Best Practices
- Never commit real secrets - Even if you remove them later, they’re in git history
- Use GitHub Secrets - Encrypted and only exposed to workflows
- Rotate if exposed - If a secret was ever in code, treat it as compromised
- Use OIDC - Prefer short-lived credentials over long-lived secrets
- Audit regularly - Run this linter in CI to catch accidental commits