Pass named secrets by default. The inherit keyword hands a called workflow every secret the caller can see, so use it only for workflows you own and review. Named secrets make each hand-off visible in the caller file, which is easier to audit and limits what a compromised or careless workflow can reach.
The two ways to pass secrets
A workflow that calls a reusable workflow has two options, both described in GitHub's documentation on reusing workflows.
Explicit: use the secrets keyword to pass named secrets, one by one. The called workflow declares which secrets it accepts, and the caller maps values to them.
Inherit: callers in the same organization or enterprise can use the inherit keyword to implicitly pass the secrets. The called workflow receives what the caller has access to, with no list.
| Named secrets | secrets inherit | |
|---|---|---|
| What is passed | Only the ones you list | All available to the caller |
| Review effort | Visible in the caller file | Requires reading the called workflow |
| Works across organizations | Yes | No, same organization or enterprise |
| Good fit | Third-party or shared workflows | Workflows you own and review |
Why the default matters
When you add a secret later, inherit passes it along silently. A reusable workflow that needed two secrets last year may now receive five, and nobody changed the caller. Named secrets fail loudly in the other direction: if the called workflow needs something new, someone must edit the caller, and that edit shows up in a pull request.
GitHub's security guidance reminds us that anyone with write access to a repository has read access to the secrets configured there. Anything that runs your workflow code can also read them. Fewer secrets in scope means a smaller blast radius if one workflow is compromised.
Secrets do not flow down a chain
The documentation states that secrets are only passed to the directly called workflow. If workflow A calls B and B calls C, then A must not assume C sees anything. B has to pass secrets on explicitly, and it can only pass what it received. This is a helpful property, because each hop is a decision. Reusable workflows can be nested up to ten levels, and loops are not permitted.
Environment secrets are a special case
To use an environment secret in a reusable workflow, you set environment on the job inside the reusable workflow. The job that calls the reusable workflow cannot use the environment keyword. That means approval rules on the environment, such as required reviewers, apply at the job that actually needs the secret, which is what you want. See environment required reviewers and deployment approval.
A simple decision rule
- Is the called workflow in your own organization and reviewed by your team? Inherit is acceptable, but still consider naming.
- Is it from another organization or a public repository? Pass named secrets only, and pin the reference to a full commit SHA.
- Does it need a cloud credential? Prefer short-lived tokens from OIDC over a stored secret.
- Does a second-level call need a secret? Pass it explicitly at each hop.
Quick check
Can I use inherit with a workflow from another organization?
No. Per GitHub's documentation, inherit is for callers in the same organization or enterprise. Across organizations, pass named secrets.
Does a called workflow see the caller's environment secrets?
Not automatically. Environment secrets are available to a job that sets the environment, and for a reusable workflow that has to be set on the job inside the called workflow.
Is inherit a security problem by itself?
It is a wider grant than most workflows need. It is fine when you control and review the called workflow, and a poor choice for anything you do not.
Sources
Last reviewed: 19 October 2026.