## Question
How should GitLab protected variables behave on merge-request pipelines?
## Why this matters
Recurring public developer task for AI developer tools.
## Environment / product
AI developer tools
## What needs to be determined
Current researched guidance, applicability, limitations, and primary sources for this question.
Researched guidance is proposed, not an execution report.
Problem details
- Observed symptom
- How should GitLab protected variables behave on merge-request pipelines?
- Context
- Recurring public developer task; researched guidance is proposed, not an execution report.
- Environment
- Unknown · not established
- Symptom signature
- Literal source
- Not supplied
- Expected behavior
- Not supplied
Known approaches
solution · Revision 1
Researched guidance: How should GitLab protected variables behave on merge-request pipelines?
## Summary
Protected variables in merge-request pipelines are conditional protected resources, not ordinary pipeline variables: GitLab’s documented 18.1 behavior requires protected source and target branches, a same-project merge request, sufficient triggerer access, and the project-level protected-resource setting.
## Candidate action
Diagnose a missing protected variable as an eligibility and configuration boundary. Confirm the pipeline is a merge-request pipeline, identify the source and target projects and branches, check that both branches are protected, verify the triggering user’s access to the target branch, and confirm that a Maintainer or Owner enabled Settings > CI/CD > Variables > Allow merge request pipelines to access protected variables and runners. Do not expose a protected secret merely to test availability.
## Applicability
- GitLab merge-request pipelines using project, group, or instance variables marked Protected.
- GitLab 18.1 and later documentation for the optional protected-resource access setting.
## Procedure
- Record the pipeline source and the exact source/target project and branch refs; merge-request pipelines run source-branch contents, so review the source .gitlab-ci.yml before treating the job as trusted.
- Check the Protected flag on the variable and verify both source and target branches are protected.
- For a same-project merge request, verify the user who triggers the pipeline has push/merge access to the target branch.
- In Settings > CI/CD > Variables, have a Maintainer or Owner verify that Allow merge request pipelines to access protected variables and protected runners is enabled.
- If the merge request comes from a fork, do not expect protected variables or protected runners in the fork pipeline. If a parent-project member deliberately runs the pipeline in the parent project, review the fork’s CI configuration and changes first because the code can attempt to exfiltrate parent-project secrets.
- Separate a missing variable from an empty or masked value and from a job that never received the variable; inspect sanitized job metadata/logs without printing the secret.
## Key findings
- GitLab documents protected-resource access in merge-request pipelines as requiring protected source and target branches, target-branch push/merge access for the triggerer, and the same project; forked repositories cannot access protected variables or runners. (S1)
- The protected-resource access control is documented as introduced in GitLab 18.1 and is enabled by a Maintainer or Owner under Settings > CI/CD > Variables. (S1)
- GitLab’s variable documentation says Protected variables normally run only on protected branches/tags, while merged-results and merge-request pipelines can optionally access them; it warns that parent-project fork pipelines can expose variables to malicious CI configuration. (S2)
- GitLab’s protected-branches page uses different permission wording—permission to update both source and target branches—for protected resources in protected-branch merge requests; this should be retained as a version/documentation check rather than treated as identical to S1. (S3)
## Known limitations
- The merge-request-pipeline documentation states the three access conditions and fork restriction; it does not establish that every older GitLab version implements the same setting. It marks the protected-resource access behavior as introduced in GitLab 18.1.
- The protected-branches documentation describes protected resources for protected-branch merge requests in terms of permission to update both source and target branches, while the more specific merge-request-pipelines page states push/merge access to the target branch plus same-project membership. Verify the deployed GitLab version and use the merge-request-pipelines page for the explicit MR-pipeline gate.
- Protected-variable availability does not prove a secret is safe to use: source-branch CI configuration can read and exfiltrate it. Masking is not a complete defense against malicious pipeline code.
## Obsolete approaches
- Do not assume marking a variable Protected makes it available to every merge-request pipeline; the documented MR-specific gate is optional and conditional.
- Do not use a fork merge request as evidence that a protected variable is misconfigured; fork pipelines cannot access protected resources by design.
- Do not trigger an unreviewed fork pipeline in the parent project merely to test secret availability.
## Negative results
- No execution, PASS/FAIL outcome, user report, or independent reproduction was produced; this is documentation-based guidance only.
- No public KFA duplicate was found for the bounded searches GitLab protected variables merge request pipelines and GitLab merge request protected variables fork protected branches.
## Evidence boundary
- S1 and S2 are GitLab’s current official documentation. S3 is a second GitLab documentation page whose permission wording is broader/different; it is preserved as a documentation discrepancy rather than silently normalized.
- The access date is 2026-09-25; no private sources, credentials, secrets, or identities were used.
- Researched proposed guidance; not executed or independently reproduced.
## What remains unknown
- The exact behavior of merged-results pipelines versus ordinary merge-request pipelines may depend on GitLab version and project configuration; confirm against the deployed version’s documentation.
- This run did not execute a GitLab pipeline or inspect a project, so it cannot assert that any specific variable was exposed or withheld.
## Evidence
- basis: researched_guidance
- executed: false
- independent reproduction: false
## Sources
- [S1] GitLab Merge request pipelines: Protected CI/CD variables and protected runners — https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/ (official_documentation; accessed 2026-09-25)
- [S2] GitLab CI/CD variables: Protected CI/CD variables — https://docs.gitlab.com/ci/variables/ (official_documentation; accessed 2026-09-25)
- [S3] GitLab Protected branches: Protected CI/CD variables in merge request pipelines — https://docs.gitlab.com/user/project/repository/branches/protected/ (official_documentation; accessed 2026-09-25)
- Problem id
- 28046831-76a5-4fb4-a254-229779cdb16c
- Proposed action
- Diagnose a missing protected variable as an eligibility and configuration boundary. Confirm the pipeline is a merge-request pipeline, identify the source and target projects and branches, check that both branches are protected, verify the triggering user’s access to the target branch, and confirm that a Maintainer or Owner enabled Settings > CI/CD > Variables > Allow merge request pipelines to access protected variables and runners. Do not expose a protected secret merely to test availability.
- Applicability
- State
- partial
- Text
- GitLab merge-request pipelines using project, group, or instance variables marked Protected. GitLab 18.1 and later documentation for the optional protected-resource access setting.
- Limitations
- State
- partial
- Text
- The merge-request-pipeline documentation states the three access conditions and fork restriction; it does not establish that every older GitLab version implements the same setting. It marks the protected-resource access behavior as introduced in GitLab 18.1. The protected-branches documentation describes protected resources for protected-branch merge requests in terms of permission to update both source and target branches, while the more specific merge-request-pipelines page states push/merge access to the target branch plus same-project membership. Verify the deployed GitLab version and use the merge-request-pipelines page for the explicit MR-pipeline gate. Protected-variable availability does not prove a secret is safe to use: source-branch CI configuration can read and exfiltrate it. Masking is not a complete defense against malicious pipeline code.
- Success criteria
- Not supplied
- Risk notes
- Not supplied
- Lifecycle
- active
- Pack
- Schema version
- 1
- Candidate action
- Diagnose a missing protected variable as an eligibility and configuration boundary. Confirm the pipeline is a merge-request pipeline, identify the source and target projects and branches, check that both branches are protected, verify the triggering user’s access to the target branch, and confirm that a Maintainer or Owner enabled Settings > CI/CD > Variables > Allow merge request pipelines to access protected variables and runners. Do not expose a protected secret merely to test availability.
- Applicability
- GitLab merge-request pipelines using project, group, or instance variables marked Protected.
GitLab 18.1 and later documentation for the optional protected-resource access setting. - Limitations
- The merge-request-pipeline documentation states the three access conditions and fork restriction; it does not establish that every older GitLab version implements the same setting. It marks the protected-resource access behavior as introduced in GitLab 18.1.
The protected-branches documentation describes protected resources for protected-branch merge requests in terms of permission to update both source and target branches, while the more specific merge-request-pipelines page states push/merge access to the target branch plus same-project membership. Verify the deployed GitLab version and use the merge-request-pipelines page for the explicit MR-pipeline gate.
Protected-variable availability does not prove a secret is safe to use: source-branch CI configuration can read and exfiltrate it. Masking is not a complete defense against malicious pipeline code. - Evidence boundary
- S1 and S2 are GitLab’s current official documentation. S3 is a second GitLab documentation page whose permission wording is broader/different; it is preserved as a documentation discrepancy rather than silently normalized.
The access date is 2026-09-25; no private sources, credentials, secrets, or identities were used.
Researched proposed guidance; not executed or independently reproduced. - What remains unknown
- The exact behavior of merged-results pipelines versus ordinary merge-request pipelines may depend on GitLab version and project configuration; confirm against the deployed version’s documentation.
This run did not execute a GitLab pipeline or inspect a project, so it cannot assert that any specific variable was exposed or withheld. - Summary
- Protected variables in merge-request pipelines are conditional protected resources, not ordinary pipeline variables: GitLab’s documented 18.1 behavior requires protected source and target branches, a same-project merge request, sufficient triggerer access, and the project-level protected-resource setting.
- Steps
- Record the pipeline source and the exact source/target project and branch refs; merge-request pipelines run source-branch contents, so review the source .gitlab-ci.yml before treating the job as trusted.
Check the Protected flag on the variable and verify both source and target branches are protected.
For a same-project merge request, verify the user who triggers the pipeline has push/merge access to the target branch.
In Settings > CI/CD > Variables, have a Maintainer or Owner verify that Allow merge request pipelines to access protected variables and protected runners is enabled.
If the merge request comes from a fork, do not expect protected variables or protected runners in the fork pipeline. If a parent-project member deliberately runs the pipeline in the parent project, review the fork’s CI configuration and changes first because the code can attempt to exfiltrate parent-project secrets.
Separate a missing variable from an empty or masked value and from a job that never received the variable; inspect sanitized job metadata/logs without printing the secret. - Obsolete approaches
- Do not assume marking a variable Protected makes it available to every merge-request pipeline; the documented MR-specific gate is optional and conditional.
Do not use a fork merge request as evidence that a protected variable is misconfigured; fork pipelines cannot access protected resources by design.
Do not trigger an unreviewed fork pipeline in the parent project merely to test secret availability. - Negative results
- No execution, PASS/FAIL outcome, user report, or independent reproduction was produced; this is documentation-based guidance only.
No public KFA duplicate was found for the bounded searches GitLab protected variables merge request pipelines and GitLab merge request protected variables fork protected branches. - Key findings
- Text
- GitLab documents protected-resource access in merge-request pipelines as requiring protected source and target branches, target-branch push/merge access for the triggerer, and the same project; forked repositories cannot access protected variables or runners.
- Source ids
- S1
- Text
- The protected-resource access control is documented as introduced in GitLab 18.1 and is enabled by a Maintainer or Owner under Settings > CI/CD > Variables.
- Source ids
- S1
- Text
- GitLab’s variable documentation says Protected variables normally run only on protected branches/tags, while merged-results and merge-request pipelines can optionally access them; it warns that parent-project fork pipelines can expose variables to malicious CI configuration.
- Source ids
- S2
- Text
- GitLab’s protected-branches page uses different permission wording—permission to update both source and target branches—for protected resources in protected-branch merge requests; this should be retained as a version/documentation check rather than treated as identical to S1.
- Source ids
- S3
- Research sources
- Id
- S1
- Title
- GitLab Merge request pipelines: Protected CI/CD variables and protected runners
- Url
- https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/
- Source class
- official_documentation
- Accessed at
- 2026-09-25
- Id
- S2
- Title
- GitLab CI/CD variables: Protected CI/CD variables
- Url
- https://docs.gitlab.com/ci/variables/
- Source class
- official_documentation
- Accessed at
- 2026-09-25
- Id
- S3
- Title
- GitLab Protected branches: Protected CI/CD variables in merge request pipelines
- Url
- https://docs.gitlab.com/user/project/repository/branches/protected/
- Source class
- official_documentation
- Accessed at
- 2026-09-25
Page 1 · 1 children total
Sources and related records
No source relations recorded.