Chapter 21Lesson 03~170 minutes

Protected Environments, Deployment Approvals, Freeze Windows, Manual Gates, and Separation of Duties: Configuration, Design Choices, and Tradeoffs

Choose between manual jobs, protected-environment approvals, separation of duties, freeze policies, emergency exceptions, and narrow deploy roles using explicit trust, audit, tier, and operational tradeoffs.

Design tradeoffsLeast privilegeSelf-approvalExceptionsAuditability

Learning objectives

  • Choose a manual gate or deployment approval based on the assurance required rather than UI preference.
  • Evaluate self-approval, role separation, hard freezes, emergency exceptions, and narrow deployment authority.
  • Understand when protected variables and environment scopes do or do not align with authorization timing.
  • Map each design choice to tier prerequisites, affected GitLab/external state, and observable evidence.
  • Document current assumptions so a future GitLab upgrade cannot silently change the authorization contract.

1. Design from the control objective, not from the button

A manual Play button, a protected environment, and an approval rule can all “look like gates,” but they answer different questions. The right design begins with the control objective: who may request, who may authorize, who may execute, what must be frozen, and which evidence must survive?

Keep CI_PIPELINE_SOURCE, CI_COMMIT_SHA, compiled job rules, candidate digest, and external target identity in the decision because authorization without candidate identity is not reproducible.

2. Manual job versus environment approval

Choice Strength Weakness Tier
Blocking manual job Simple, visible pipeline pause; Free. Who can play it may be broad unless combined with paid protected-environment controls. Free+
Protected manual job Limits who may play a deployment job to protected-environment deployers. Requires protected environments. Premium/Ultimate
Deployment approval Creates explicit eligible approvers and approval history separate from deployment execution. Paid feature; approval still does not prove rollout health. Premium/Ultimate
Local/simulated approval contract Good teaching/test path for policy logic. Not a substitute for GitLab authorization in production. Free/local

3. Self-approval versus separation of duties

By default, current GitLab deployment approvals do not let the pipeline triggerer approve the same deployment. A project option can allow this. That option is useful in low-risk workflows, but it changes the assurance: the requester and approver become one identity.

Scenario Recommended posture Evidence
Low-risk internal preview Self-approval may be acceptable if documented. Actor + candidate + deployment record.
Production with compliance requirement Separate triggerer, approver, and deployer where practical. Approval identity/history + deploy actor + health.
Emergency recovery Permit bounded exceptional authority only with reason/incident reference and after-action review. Exception record + exact digest/SHA + health + reviewer.

4. Hard freeze versus emergency exception

A freeze is most useful when it is deterministic and visible before job execution. CI_DEPLOY_FREEZE is pre-pipeline, so rules can prevent normal production jobs from being included or can transform them into an explicit emergency path. Avoid relying on a shell check at the end of a privileged deployment job after secrets and target credentials have already been exposed.

rules:
  - if: '$CI_DEPLOY_FREEZE'
    when: manual
    allow_failure: false
  - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    when: manual
    allow_failure: false
  - when: never

For stricter organizations, the emergency job can be defined in a separately controlled include or deployment project so ordinary developers cannot rewrite the bypass condition.

5. Broad deploy role versus narrow authorization

Granting every Maintainer production deployment authority is easy but couples source administration, CI configuration, variable access, and production actions. A narrower protected-environment deployer set—or a separate deployment project introduced in Chapter 15—reduces blast radius.

Do not compensate for a broad role with secret masking. Masking protects logs, not authorization. Least privilege is about whether the identity can receive or use the credential at all.

6. Secrets and gate timing: do not expose production credentials before authorization

A common design error is to load a production credential in a preparation job, then place the manual or approval gate later. The credential has already crossed the trust boundary. Prefer environment-scoped/protected variables and structure the pipeline so the first job requiring the production credential is the actual authorized deployment job.

State Before authorization After authorization
Candidate artifact Readable as required by build/review roles Same immutable candidate
Production credential Not exposed to ordinary preparation/test jobs Available only to authorized deployment context
External target write access None Narrow, time/job-scoped where possible

7. Auditability: record both normal and exceptional paths

The environment UI and Deployments API provide deployment IDs, SHA/ref, actor, status, and—on Premium/Ultimate—approval summaries. Freeze-period APIs provide policy schedule evidence. Those are useful but incomplete without external health evidence and any emergency-exception reason.

Do not make “administrator did it” the end of an incident narrative. Administrator authority is a fact; the audit packet still needs candidate identity, action, reason, target effect, and verification.

8. Worked decision table

Requirement Recommended control Prerequisite Observe
Human acknowledgement only Blocking manual job + confirmation Free Job creator/player, pipeline/job IDs
Only a small ops group may deploy Protected environment Allowed to deploy Premium/Ultimate Environment protection config + deploy actor
Independent authorization Deployment approval rules; self-approval disabled Premium/Ultimate Eligible approvers + approval history
Holiday/change freeze Freeze period + CI_DEPLOY_FREEZE-aware rules Free Freeze schedule + compiled job decision
Emergency during freeze Dedicated exception path with narrow actor set and reason Policy-specific Exception ID, actor, exact candidate, post-health

9. Current behavior assumptions to pin in operating documentation

  • Protected environments: Premium/Ultimate; Maintainer or Owner can configure project protection; administrators retain access.
  • Deployment approvals: Premium/Ultimate; default self-approval by pipeline triggerer is disabled; eligible approvers can approve/reject; approvals are separate from actual deployment execution.
  • Manual jobs: available on Free; explicit allow_failure: false makes blocking intent clear. Inside rules, manual jobs default to blocking behavior.
  • Manual confirmation: supported for manual jobs; current docs also support environment stop-job confirmation.
  • Freeze periods: Free+; CI_DEPLOY_FREEZE is pre-pipeline when active; maintainers/owners manage freeze periods through API/UI.
Assumption timestamp: 2026-09-12. Re-verify these version-sensitive points before adopting the examples as production policy.

10. Failure isolation: authorization should not hide execution failures

If approval is correct but the deployment script fails, do not reopen or weaken the approval rule first. If the candidate digest is wrong, fix artifact flow. If the job cannot obtain a runner, fix scheduling. If the target is unhealthy after a successful job, investigate the provider/application. Layered evidence prevents policy controls from becoming a generic troubleshooting hammer.

11. Design review checklist

  • State the control objective and tier prerequisite before choosing a gate.
  • Tie approval to exact source SHA and candidate digest.
  • Keep protected credentials out of pre-authorization jobs.
  • Make freeze behavior visible in compiled configuration, not only in operator memory.
  • Treat emergency bypass as a separately auditable workflow.
  • Verify post-deployment target state independently of GitLab job/approval state.

Knowledge check

A team wants only a human acknowledgement before a low-risk internal deployment. Is Premium deployment approval required?

Why can a shell-only freeze check be weaker than a rules-based gate?

What assurance is lost when pipeline triggerers can self-approve?

Where should production credentials first appear in a gated design?

A deployment was approved but no runner is available. Which layer is failing?

Next lesson

Diagnostics, failure modes, security, and performance

Preserve evidence while diagnosing self-approval, approval/rollout confusion, freeze bypass, early secret exposure, and undocumented administrator overrides.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-12. The mandatory learning path uses only disposable/local simulation plus GitLab Free features. Protected environments and deployment approvals are treated as Premium/Ultimate and are simulated unless the learner already has an authorized eligible project.

Current assumptions used in this chapter: Version-sensitive YAML, Runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations must be verified against the exact GitLab, GitLab Runner, tool, and external-system versions used in production. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for reproducible work.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.