Safeguard
Application Security•

Can a pull request steal secrets from Bitbucket Pipelines?

A pull request build runs code its author chose. Keep deploy credentials out of PR pipelines, scope variables by deployment, and prefer OIDC to keys.

Safeguard Security Team
4 min read

It can, if the pull request pipeline can read credentials. The author of a pull request controls the scripts that run in the build, so any variable that build can read can be sent elsewhere. Keep production secrets out of PR builds, scope variables to deployments, and use OIDC instead of stored keys.

Why is a PR build a different trust level?

A pipeline defined under the pull-requests key runs when someone opens or updates a pull request. The steps are plain scripts in a Docker container. Whoever edits the pipeline file or a script it calls, such as a test runner or a package install hook, decides what code runs there.

That is normal for testing. It becomes a problem when the same build can also read a deploy key. Atlassian's documentation describes the places variables live: workspace variables available to all repository builds, repository variables for users with write access, and deployment variables for a named environment that override the other two. The documentation says deployment variables are for different credentials per environment, such as staging and production.

Treat that scoping as your main control. A PR build should see test settings and nothing that can change production.

What does a secured variable protect?

Secured variables are encrypted and shown with a padlock. The docs say they are hidden in build logs, with automatic masking of matching values and detection of URL-encoded variants. They cannot be edited, only replaced or deleted.

Hiding in logs is a different thing from being unreadable to the build. The step still receives the value in its environment, because that is the point of having it. A script that sends it to an outside server never touches the log. So a secured variable defends against accidents, and scoping defends against intent.

Is there a way to avoid stored credentials?

Yes. Bitbucket Pipelines exposes BITBUCKET_STEP_OIDC_TOKEN, an ID token generated by the Bitbucket OIDC provider that identifies the step. A cloud provider can trust that identity and hand out short-lived access, so no long-lived key sits in repository settings. Atlassian's AWS guide walks through the setup. The docs also list integrations with HashiCorp Vault, AWS Secrets Manager, Azure Key Vault and Google Secret Manager that fetch secrets at run time on self-hosted or cloud runners without storing them in Bitbucket.

A constructed example

A team has a repository variable called DEPLOY_KEY, secured, and a pull-requests pipeline that runs tests. A contributor opens a pull request that adds a test helper which reads the environment and posts it to a web address. The log shows nothing odd, because the value was never printed.

The fix is structural. The team deletes the repository variable, creates the key as a deployment variable on the production environment, and limits the production step to the main branch pipeline. They later replace the key with an OIDC role whose trust policy accepts only the production deployment. The pull request build now has nothing worth stealing.

What to do

  1. List workspace, repository and deployment variables and note which builds can read each.
  2. Move any credential that can change production into a deployment variable.
  3. Make PR pipelines run only tests and linting, with no deploy step and no deploy variables.
  4. Replace stored cloud keys with OIDC tokens and a narrow trust policy.
  5. Require review before merging changes to bitbucket-pipelines.yml and to scripts it runs.
  6. Check how your workspace treats forks and which people can trigger builds with write access.
  7. Rotate any secret that a PR build could have read since it was created, and after staff leave.
  8. Pin pipes and base images to a fixed version so a changed upstream cannot alter your build.

You can see a similar gate in the CI/CD actions demo.

Quick check

Does marking a variable secured stop a script reading it?

No. It hides the value in logs and prevents editing. The build step still receives it, so a script can read it.

What is the simplest fix for PR build risk?

Make sure no deployment credential is available to pull request pipelines, and use OIDC for deploys so there is no stored key.

Sources

Last reviewed: 18 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.