Secrets and Environment Management in Pipelines
A pipeline that builds and deploys your app almost always needs credentials, registry logins, cloud provider access, database passwords. Handling these safely is one of the most consequential parts of CI/CD to get right.
Repository/organization secrets
CI platforms provide an encrypted secrets store separate from your code, referenced in workflows without ever appearing in the YAML or logs:
steps:
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: ./deploy.sh
GitHub Actions automatically redacts any value matching a registered secret from logs, if a step accidentally echoes $AWS_SECRET_ACCESS_KEY, the log shows *** instead of the real value.
Least-privilege deploy credentials
The credentials your pipeline uses to deploy should follow the same rule as everything else: only what's needed. A pipeline deploying a static site to one S3 bucket doesn't need account-wide admin access, give it a role/user scoped to exactly that bucket (and nothing else), the same IAM principle from the AWS course, applied to your CI system's credentials specifically.
Environment-specific configuration
Different environments (staging, production) usually need different config: different database URLs, different feature flag defaults, different API keys. GitHub Actions Environments let you scope secrets and required approvals per environment:
jobs:
deploy-production:
environment: production
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh
An environment: production job can require manual approval before running, and only has access to secrets scoped to that environment, staging secrets and production secrets never mix, even within the same repository.
OIDC: no long-lived secrets at all
The most modern approach skips storing cloud credentials as secrets entirely: OIDC (OpenID Connect) lets your CI platform request short-lived, auto-expiring credentials directly from your cloud provider for each run, nothing long-lived to leak in the first place.
WARNING
A leaked CI secret is one of the most common ways real production incidents start, because CI credentials are often broader than they need to be ("just give it admin, it's easier"). Treat pipeline credentials with the exact same least-privilege scrutiny you'd apply to a human's access.