Understanding GitHub Actions secret types, storage hierarchy, and threat model. Secure patterns for managing credentials, tokens, and sensitive configuration.
Understands GitHub Actions secret types, storage hierarchy, and threat models. Claude uses this when reviewing workflows for credential exposure risks and recommending secure secret management patterns.
/plugin marketplace add adaptive-enforcement-lab/claude-skills/plugin install secure@ael-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
examples.mdreference.mdscripts/example-1.yamlscripts/example-2.yamlscripts/example-3.yamlscripts/example-4.yamlscripts/example-5.yamlscripts/example-6.yamlscripts/example-7.yamlscripts/example-8.yamlscripts/example-9.yamlSecrets in GitHub Actions are the keys to your kingdom. Exposed credentials mean compromised infrastructure. Manage them like your business depends on it. Because it does.
The Risk
Secrets in GitHub Actions grant access to production systems, cloud accounts, package registries, and third-party services. A single leaked credential can mean full infrastructure compromise, data exfiltration, or supply chain attacks against your users.
GitHub Actions secrets are encrypted environment variables stored at repository, organization, or environment level. They inject sensitive values into workflows without exposing them in logs or code.
How Secrets Work:
${{ secrets.SECRET_NAME }}Key Characteristics:
$SECRETS_NAME syntax in shellGitHub offers three storage levels for secrets. Understanding scope is critical for least-privilege access.
Scope: Single repository only
Access: All workflows in that repository
Use Cases:
Configuration: Settings → Secrets and variables → Actions → Repository secrets
Example:
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Repository secret - available to this repo only
- run: echo "${{ secrets.DEPLOY_KEY }}" | base64 -d > deploy.key
Risk: Accessible to all workflows in repository. Compromised workflow file can exfiltrate.
Scope: Multiple repositories within organization
Access: Selected repositories or all repositories in org
Use Cases:
Configuration: Organization Settings → Secrets and variables → Actions → Organization secrets
Visibility Policy:
Example:
name: Publish
on: [release]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Organization secret - shared across repos
- run: npm publish --registry=https://npm.example.com
env:
NPM_TOKEN: ${{ secrets.ORG_NPM_TOKEN }}
Risk: Broader attack surface. Compromise of any selected repository exposes secret to attacker.
Scope: Specific deployment environment (production, staging, dev)
Access: Only workflows that target that environment
Use Cases:
Configuration: Settings → Environments → Environment name → Environment secrets
Protection Rules:
Example:
name: Deploy Production
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # Triggers environment protection
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Environment secret - production only, requires approval
- run: ./deploy.sh
env:
PROD_API_KEY: ${{ secrets.PROD_API_KEY }}
Risk: Lowest risk with proper protection rules. Approval gates prevent unauthorized access.
Type: Sensitive values encrypted by GitHub
Use Cases: Passwords, API keys, tokens, certificates, private keys
Example:
env:
DATABASE_PASSWORD: ${{ secrets.DB_PASSWORD }}
API_TOKEN: ${{ secrets.EXTERNAL_API_TOKEN }}
Characteristics:
Type: Non-sensitive configuration values stored as plaintext
Use Cases: Environment names, URLs, feature flags, non-secret configuration
Example:
env:
API_ENDPOINT: ${{ vars.API_URL }}
ENVIRONMENT: ${{ vars.DEPLOY_ENV }}
Characteristics:
Security Note: Variables are NOT secrets. Never store credentials as variables.
Type: Short-lived JSON Web Tokens for cloud federation
Use Cases: AWS, GCP, Azure authentication without long-lived credentials
Example:
permissions:
id-token: write # Request OIDC token
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# google-github-actions/auth v2.1.0
- uses: google-github-actions/auth@f112390a2df9932162083945e46d439060d66ec2
with:
workload_identity_provider: 'projects/123/locations/global/workloadIdentityPools/github/providers/github-provider'
service_account: 'deploy@project.iam.gserviceaccount.com'
- run: gcloud compute instances list
Characteristics:
Benefit: Eliminates long-lived credentials. Reduces secret sprawl and rotation burden.
See OIDC Federation Patterns for complete implementation guide.
Understanding how secrets leak is the first step to preventing exposure.
Mechanism: Secret accidentally printed to stdout/stderr
Example:
# DANGEROUS - Exposes secret in logs
- run: echo "Deploying with key ${{ secrets.DEPLOY_KEY }}"
Result: Secret visible in workflow logs despite masking (masking is best-effort, not guaranteed).
Prevention: Never interpolate secrets into commands that may log them. Use environment variables instead.
# Safe - secret passed via environment, not command line
- run: ./deploy.sh
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
Mechanism: Malicious PR injects code that exfiltrates secrets
Example:
# DANGEROUS - PR from fork can inject code
name: CI
on: [pull_request_target] # Runs with repo secrets even for forks
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
ref: ${{ github.event.pull_request.head.sha }} # Checks out PR code
# Attacker controls test.sh via PR
- run: ./test.sh
env:
API_KEY: ${{ secrets.API_KEY }} # Exposed to attacker
Attack: Attacker submits PR with malicious test.sh that sends $API_KEY to attacker server.
Prevention: Use pull_request (not pull_request_target) for untrusted code. Isolate secret access.
See the full implementation guide in the source documentation.
See examples.md for code examples.
See reference.md for complete documentation.
Master authentication and authorization patterns including JWT, OAuth2, session management, and RBAC to build secure, scalable access control systems. Use when implementing auth systems, securing APIs, or debugging security issues.