Use environment secrets for anything that deploys or touches production, because they can sit behind required reviewers. Use repository secrets for a single repo's lower-risk needs. Use organization secrets for values many repositories share, restricted to selected repositories. Choose the narrowest scope that works.
The three scopes
GitHub documents three places to create a secret:
- Repository secret. Created by people with write access to an organization repository.
- Environment secret. Created for a named environment. In organization repositories this takes admin access.
- Organization secret. Created by organization owners, with an access policy of all repositories, private repositories only, or selected repositories.
Decision table
| Situation | Scope | Why |
|---|---|---|
| Token for a test service used by one repo | Repository | Simple and contained |
| Production deploy credential | Environment | A job cannot read environment secrets until a required reviewer approves |
| Same registry login used by twelve repos | Organization, selected repositories | One place to rotate, limited audience |
| Credential only needed by a protected release step | Environment | Ties access to the deployment gate |
GitHub's hardening guide says it directly: with required reviewers on an environment, a workflow job cannot access environment secrets until a reviewer approves.
Rules that apply to all scopes
- Forks. Apart from GITHUB_TOKEN, secrets are not passed to the runner when a workflow is triggered from a forked repository.
- Reusable workflows. Secrets are not automatically passed to them. Pass them on purpose.
- Dependabot. Secrets are not automatically available to Dependabot-triggered workflows.
- Size. Secrets larger than 48 KB need a workaround, and GitHub warns it does not redact secrets printed in logs when you use one.
- Conditions. You cannot reference a secret directly in an if condition. Set it as a job-level environment variable and test that.
- Missing secrets. An expression that references a secret that is not set returns an empty string, not an error. Do not let a silent empty value skip a signing or verification step.
Handling advice from GitHub
Store sensitive data as secrets, never as plaintext in a workflow file. Do not wrap a secret in a JSON, XML or YAML blob, because redaction matches whole values, so store each sensitive value separately. Register derived values, such as a signed token, as secrets too. If a secret shows up unredacted in a log, delete the log and rotate the secret. Remove unused secrets and rotate the rest on a schedule.
Quick check
Does an organization secret reach every repository?
Only those its access policy allows. Pick selected repositories rather than all.
Where should a production deploy key live?
In an environment with required reviewers, or better, replace it with short-lived federated credentials.
Safeguard's policies and gates can block a pull request that fails your checks before a deploy workflow runs. Try the free scan.
Sources
Last reviewed: 19 October 2026.