Travis CI secure variables missing in fork-sourced pull request builds
0 reputation · 11 Dec 2022, 06:30 UTC
0 reputation · 11 Dec 2022, 06:30 UTC
Travis CI restricts the injection of secure environment variables to builds triggered by pushes to the repository or pull requests originating from internal branches. This security measure prevents credential leakage when external contributors submit code via forks.
For projects requiring integration testing during the pull request phase, this behavior creates a gap where tests needing API keys or database tokens fail for fork-sourced PRs, while passing for internal branches. There is a need to determine the best architectural approach to facilitate these tests without compromising production secrets.
Given the SaaS platform constraints, what are the recommended strategies for providing limited-scope test credentials to external PR builds? Is there a documented method to conditionally inject non-production secrets specifically for fork-based triggers without exposing them in the build logs?
34775 reputation · 11 Dec 2022, 07:06 UTC
The missing variables are documented, intentional behavior, not a misconfiguration. Travis CI decrypts secure environment variables only for builds it treats as trusted: pushes to the repository and pull requests opened from branches in that same repository. Pull request builds from forks never receive decrypted secure vars, and no .travis.yml option, build condition, or repository setting re-enables decryption for them. The rationale is sound — a fork PR carries untrusted code, and a single env or curl line in it would publish any secret the build holds.
So the answer to your second question is no: there is no documented mechanism that conditionally injects platform-managed secrets into fork-based triggers. Both workable strategies start from detecting the fork case yourself.
Travis sets TRAVIS_REPO_SLUG to the base repository and, for pull request builds, TRAVIS_PULL_REQUEST_SLUG to the repository the PR came from. Check both conditions so push builds are not caught by the comparison:
if [ "$TRAVIS_PULL_REQUEST" != "false" ] && [ "$TRAVIS_PULL_REQUEST_SLUG" != "$TRAVIS_REPO_SLUG" ]; then
echo "fork PR: credential-dependent steps disabled"
export RUN_INTEGRATION=0
fiMove integration tests into their own stage that runs only for same-repo builds:
jobs:
include:
- stage: integration
if: type = push OR (type = pull_request AND fork = false)
script: ./scripts/integration-tests.shVerify the fork attribute against the conditional-builds documentation for your instance; the shell comparison above works regardless. Contributors still get unit tests on every fork PR, and the full suite runs on base-repo branches or after merge. Nothing is exposed.
If fork PRs must execute those tests, store test-only credentials in an external secrets manager and retrieve them in the build script. One assumption must be explicit: anything a fork build can reach, the fork's code can print. Log hygiene (no set -x, quiet CLI output, never echoing values) stops your scripts from leaking secrets, but it is not a security boundary against a malicious PR. Design the credential for a public audience:
On authorization: Travis SaaS gives fork PR builds no per-contributor identity you can exchange for secrets from Vault, AWS Secrets Manager, or similar. Some setups expose a repository-scoped GitHub token in the build environment, but its availability and scopes differ between travis-ci.com and the legacy travis-ci.org service — verify in a throwaway fork build before designing around it. Most projects ship a dedicated minimal CI identity for the test sandbox and accept that it is effectively public.
[ -n "$MY_VAR" ] && echo set || echo unset), never its value. Expect unset.This describes the Travis CI SaaS (travis-ci.com); the legacy travis-ci.org platform applied the same restriction. Self-hosted Travis CI Enterprise may expose policy options that change the picture — confirm against your instance before relying on anything here.
Can the credential-dependent tests tolerate being skipped on fork PRs and run only on base-repo branches or after merge? If yes, take strategy 1 — simpler and leaks nothing. If fork PRs must run them, strategy 2 is the only viable shape, and the engineering effort goes into making the test credential worthless beyond its sandbox.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.