After this lesson, you will be able to: Manage environment variables and secrets across staging vs production, use feature environments per branch, and integrate with cloud-native secret stores.
Secrets management is where most teams either get sloppy (commit a key by accident) or over-engineer (vault per environment with rotation). This lesson covers the practical middle.
Repository secrets: stored in GitHub Actions, scoped to one repo. Easy. Most secrets live here. Environment secrets: scoped to a GitHub Environment (`staging`, `production`). Different DB passwords per env. Organization secrets: shared across many repos. Useful for 'we use the same Datadog API key everywhere'. All three are encrypted at rest, masked in logs, and never visible after creation.
Tie the secret to the environment, then reference normally.
# Settings > Environments > production > Add secret DATABASE_URL# Then in workflow:jobs:deploy:runs-on: ubuntu-latestenvironment: productionsteps:- name: Migraterun: npx prisma migrate deployenv:DATABASE_URL: ${{ secrets.DATABASE_URL }}# No need to specify 'environment: production' on the secret;# it auto-resolves from the env set on the job.# Same workflow with environment: staging would resolve a DIFFERENT secret# (the staging DATABASE_URL configured on the staging environment).
Vercel + Netlify do this automatically: every PR gets its own preview URL. For containers: spin up a temporary K8s namespace or a per-PR docker compose stack. Pattern: workflow_run on pull_request; deploy to `pr-${PR_NUMBER}.example.com`; tear down on PR close. Value: stakeholders click a real URL to review changes, not a screenshot.
Most projects can live with GitHub Secrets forever. Add AWS Secrets Manager / HashiCorp Vault / 1Password Secrets when: 1. You need rotation (auto-rotated DB passwords). 2. You need per-instance secrets (e.g. each EC2 instance fetches its own). 3. You need audit logs of who accessed which secret when. 4. You have many repos that share secrets and want central management. Until then, GitHub Secrets is fine.
Committing `.env` to git. Use `.gitignore` from day one + `.env.example` for the template. Reusing the same DATABASE_URL between staging and production. Staging breakage = prod breakage. Using OIDC tokens with `*` resource policies. Always scope: 'only this repo / this branch / this workflow'. Long-lived AWS access keys in GitHub Secrets. Migrate to OIDC. Storing secrets in Dockerfile build args. Visible in image layer history.
Pick the best reason.
Sign in and purchase access to unlock this lesson.