Safeguard
Developer Tools•

When can a GitLab merge request pipeline use protected variables?

A merge request pipeline gets protected variables and runners only when three conditions hold. Here they are, why forks never qualify, and how to check.

Safeguard Security Team
3 min read

A merge request pipeline can use protected variables and protected runners when both the source and target branches are protected, the person who triggered it has push or merge access to the target branch, and both branches are in the same project. Pipelines from forks never get them. A project Maintainer can switch the behavior off.

The three conditions

GitLab's merge request pipeline documentation lists them directly. All must be true.

ConditionWhat it blocks
Source and target branches are both protectedOrdinary feature branches
Triggering user can push or merge to the targetContributors without rights
Both branches live in the same projectFork merge requests

If any one fails, protected variables are not injected, and a job that needs one will usually fail or run with an empty value.

What a merge request pipeline actually tests

These pipelines run on the contents of the source branch and ignore the target branch. They start when you open a merge request from a branch with commits, push to the source branch, or press Run pipeline on the merge request. To get them, rules in .gitlab-ci.yml must match merge_request_event. Rules that arrive through include do not count for this purpose, so write the matching rule in the main file.

workflow:
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

If you want to test the combined result of source and target, GitLab offers merged results pipelines, which test a temporary merged commit. They need the Maintainer or Owner role to enable and a project hosted on GitLab.

Forks are different

A merge request from a fork runs in the fork, with the fork's configuration, runners and variables. A parent project member can trigger a pipeline in the parent instead, which uses the parent's runners and variables with the fork's branch configuration. GitLab warns that fork code may try to steal parent secrets, so review the changes first. Our post on fork merge request pipelines and secret safety covers that decision.

Steps to check your own setup

  1. Open Settings, CI/CD, Variables and note which variables are marked protected.
  2. Check that your default and release branches are protected. See protected branches setup.
  3. Review who has push or merge rights on those branches.
  4. Decide whether merge request pipelines should see protected variables at all. A test job rarely needs a deploy key.
  5. Keep deploy secrets in jobs that only run on the protected branch after merge.

Try it yourself

Click through it at your own pace, or open it full screen. Watch where the gate sits relative to the merge, since that is where a check should block.

Safeguard policies and gates can block a merge when a pull or merge request introduces a finding, and you can try a free scan at https://gold.safeguard.sh/scan.

Quick check

Why not give every pipeline the variables?

A branch pipeline runs code from whoever pushed it. Protected variables limit secrets to code that passed review.

Does masking replace protection?

No. GitLab says masking is not a guaranteed way to stop a malicious user from reading a value.

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.