jobs.<job_id>.secrets

2 minute read

When a job calls a reusable workflow using uses:, you can control which secrets the called workflow can access by configuring jobs.<job_id>.secrets:

  • inherit — Make all secrets in the caller job’s scope available to the reusable workflow.

  • Mapping — Expose only specific secrets by mapping them one-by-one.

Use inherit with trusted reusable workflows only. If a job in the reusable workflow runs in an environment, environment-scoped secrets for that job are resolved and can override inherited or mapped values.

If a job sets environment using an expression (for example, ${{ inputs.env-prod }}), the environment name is resolved first, then environment-scoped secrets are evaluated for that job.

Inherit all secrets

In this example, caller-job invokes a reusable workflow and inherits all secrets from its scope.

Caller workflow
jobs: caller-job: uses: .cloudbees/workflows/a-reusable-workflow.yaml (1) secrets: inherit (2) inputs: env-prod: production (3)
1 Calls a reusable workflow from the current repository.
2 Inherits all secrets from the caller job’s scope.
3 Passes an environment name as input to the reusable workflow (optional).
Reusable workflow
on: workflow_call: inputs: env-prod: type: string required: false jobs: job-rw-1: steps: - name: Use inherited secrets run: | if [ -n "${{ secrets.secret-1 }}" ]; then echo "secret-1 available"; fi job-rw-2: environment: ${{ inputs.env-prod }} (4) steps: - name: Environment may override inherited values run: | # If the environment defines secret-1, it overrides the inherited value. if [ -n "${{ secrets.secret-1 }}" ]; then echo "secret-1 resolved (env may override)"; fi
1 Sets the job’s environment from the input; environment-scoped secrets are resolved for this job.

Map specific secrets

In this example, only two secrets are exposed to the reusable workflow. No other caller secrets are available.

Caller workflow
jobs: caller-job: uses: .cloudbees/workflows/a-reusable-workflow.yaml secrets: (1) secret-1: ${{ secrets.SECRET_A }} (2) secret-2: ${{ secrets.SECRET_B }} (3) inputs: env-prod: production
1 Uses mapping instead of inheritance.
2 Maps caller secret SECRET_A to secret-1 for the reusable workflow.
3 Maps caller secret SECRET_B to secret-2.
Reusable workflow
on: workflow_call: inputs: env-prod: type: string required: false jobs: job-rw-1: steps: - name: Only mapped secrets are available run: | if [ -n "${{ secrets.secret-1 }}" ]; then echo "secret-1 available"; fi if [ -n "${{ secrets.secret-2 }}" ]; then echo "secret-2 available"; fi job-rw-2: environment: ${{ inputs.env-prod }} steps: - name: Environment may override mapped secrets run: | # If the environment defines secret-1/secret-2, those values override the mappings. if [ -n "${{ secrets.secret-1 }}" ]; then echo "secret-1 resolved (env may override)"; fi if [ -n "${{ secrets.secret-2 }}" ]; then echo "secret-2 resolved (env may override)"; fi
  • Do not combine secrets: inherit and secret mappings in the same job. Choose one approach.

  • Inheritance includes secrets available in the caller job’s scope. Environment-scoped secrets apply when a job in the reusable workflow runs in that environment.

  • For passing non-secret values, prefer inputs rather than secrets.