Safeguard
Developer Tools•

Why cloud dev secrets are withheld on fork pull requests

Cloud dev environments inject secrets as environment variables, but not for forks or without write access. Why the rule exists and how to work with it.

Safeguard Security Team
4 min read

Cloud dev environments such as GitHub Codespaces expose your development secrets as environment variables, but they are not injected if you lack write access to the repository, or when a codespace is created from a forked pull request branch. The rule exists because code you open can run commands, and untrusted code should never see your secrets.

What the documentation says

GitHub's Codespaces security page states the following about secrets.

  • Development environment secrets are exposed as environment variables.
  • They are refreshed on creation and resume, and synced when changed.
  • Secrets are not injected if you lack write access to the repository.
  • For codespaces created from forked pull request branches, your codespace secrets are also withheld.

It also says to use development environment secrets for sensitive values, instead of hardcoding them in the repository.

The threat behind the rule

Opening a repository in a cloud environment is not a passive act. The same page warns that devcontainer.json can install extensions and run arbitrary commands through postCreateCommand. So when you open a pull request from a stranger's fork in a dev environment, you may be executing their setup script.

If your secrets were present, that script could read them from the environment and send them anywhere with outbound internet access. The documentation notes that outbound internet access from codespaces is allowed. Withholding secrets for forks cuts the attack at its root: the code runs, but there is nothing valuable to steal.

This is the same logic behind restrictions on secrets for fork pull requests in CI systems. Code from outside the trust boundary runs without the keys.

What you lose, and how to work with it

You lose the ability to run integration tests that need real credentials when reviewing an outside contribution. That is the right trade.

Ways to proceed:

  1. Review the change by reading the diff first. Most review does not need a running app.
  2. Test with fake credentials or a local mock of the service.
  3. If a maintainer needs to run it with real keys, copy the changes to a branch in the main repository after you have read every line, including the dev container configuration and any scripts it calls.
  4. Use short lived, narrowly scoped credentials for the cases where you must test against a real service.

Habits that keep secrets safer

  • Keep secrets out of the repository, including old commits. See our guide on rotating SSH keys safely for the rotation habit.
  • Scope each secret to the repositories that need it.
  • Prefer short lived tokens over long lived ones.
  • Do not print environment variables in logs or error pages. A debug page on a public forwarded port can leak them. See port forwarding visibility in cloud dev environments.
  • Read the dev container file in any repository before you open it in an environment that has your secrets.

Token scope is part of the story

GitHub's documentation says each creation or restart of a codespace issues a new GitHub token that expires automatically, and its scope depends on your repository access. With read-only access, committing or pushing triggers an automatic fork with read and write access to the fork. The token for a codespace is bounded by design. Your own secrets are the part you control, so keep them minimal.

For maintainers

  • Document how outside contributors can test without secrets.
  • Provide a fake or sandbox configuration that works out of the box.
  • Do not add secrets to workflows triggered from forks unless you have a deliberate, reviewed design for them.

Quick check

Why did my codespace not get my secrets?

Either you lack write access to the repository, or the codespace was created from a fork pull request branch. Both cases are on purpose, per GitHub's documentation.

Is it safe to open any pull request in a cloud dev environment?

Not automatically. The dev container configuration can run commands during setup. Read it first and open only repositories and branches you trust.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.