Self-Hosted Runner and GitHub-Hosted Runner: Secret Mapping Interoperability
0 reputation · 26 Jul 2020, 09:45 UTC
0 reputation · 26 Jul 2020, 09:45 UTC
The goal is to guarantee that a secret defined in the repository is accessible as an environment variable in every job step, irrespective of whether the workflow runs on a self-hosted or GitHub-hosted runner.
Constraints include the requirement to explicitly map secrets to env vars in the workflow YAML, the potential for self-hosted runners to retain stale environment variables between runs, and regional variations in the timing of GitHub-hosted runner image updates that may affect default tooling.
Does GitHub Actions guarantee that a secret mapped to an environment variable is available at the start of every job step regardless of runner type?
Is there a recommended practice to enforce a clean environment on self-hosted runners that mirrors the ephemeral nature of GitHub-hosted runners for secret consumption?
What verification steps can be added early in a workflow to confirm that all required secrets are present before proceeding with build steps?
34775 reputation · 26 Jul 2020, 10:52 UTC
Yes. When you map a secret with the env key at the job or step level, the runner software injects it into the process environment before the first step executes. It remains available to every subsequent step in that job on both GitHub-hosted and self-hosted runners.
The guarantee covers the runner's injection mechanism, not OS-level isolation. Self-hosted runners can inherit host environment variables or shell profile state that may shadow or conflict with mapped secrets.
To mirror ephemeral behavior on self-hosted runners, run jobs inside a container using the container: job key, or use ephemeral/just-in-time runner instances so each job starts with a fresh filesystem and process environment.
Add a fail-fast verification step as the first step in the job. For example:
- name: Verify required secrets
run: |
if [ -z "$MY_SECRET" ]; then
echo "Missing MY_SECRET"
exit 1
fi
Prefer job-level env mapping over step-level mapping when the same secret is needed across multiple steps, reducing duplication and the chance of omission.
Confirmed: the runner injects mapped secrets before step execution, and they persist across steps in the same job. This behavior is identical across runner types.
Likely explanation for failures: on self-hosted runners, stale environment variables from prior jobs can persist if the runner process is not restarted between jobs. Host-level shell profiles or inherited variables can also shadow mapped values. These are OS-level issues, not runner injection failures.
Not a factor: GitHub-hosted runner image update timing varies by region and can change default tool versions. This does not affect secret environment-variable availability.
env | sort and confirm the mapped secret variable name appears with a non-empty value before build steps.env inside a container job versus a bare-metal job to confirm that stale host variables are not leaking into the job environment.Do not echo secret values in logs. Use masked variables or length checks instead of printing the secret itself.
Do your self-hosted runners execute jobs directly on the host or inside containers? This determines whether the container: job key or ephemeral runner instances are the appropriate clean-environment strategy.
Because runner behavior and image tooling evolve, verify these patterns against current GitHub Actions documentation for your runner version before relying on them in production.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.