Chapter 27Lesson 05~340 minutes

Checkpoint Lab — Security Policies, Scan Execution, Pipeline Execution, Approval Policies, and Compliance Controls

Design a synthetic top-level-group policy set, predict its scope and enforcement, inject a violation and a legitimate exception, prove ownership boundaries, and clean up verified training resources.

CheckpointPolicy setViolationExceptionGovernance

Learning objectives

  • Map synthetic organizational requirements to one enforcement or evidence mechanism each.
  • Predict inherited and scoped project coverage before evaluating policy fixtures.
  • Inject one policy violation and diagnose it without weakening the baseline.
  • Document one legitimate exception with ownership, expiry, compensating control, and evidence.
  • Prove separation of duties and perform verified cleanup of temporary policy artifacts.
Availability baseline — verified 2026-08-22 against GitLab 19.3. Security policies (scan execution, pipeline execution, merge request approval, scheduled pipeline execution, vulnerability management) and security policy projects are currently Ultimate across GitLab.com, Self-Managed, and Dedicated. Compliance frameworks are Premium/Ultimate; using frameworks as policy-enforcement scope and broader security/compliance controls is an Ultimate operating model. Instance-wide compliance and security policy groups are Ultimate on Self-Managed/Dedicated and administrator-controlled. Therefore the mandatory chapter path is a Free-compatible local/CI fixture simulation; live enforcement is optional only when a disposable Ultimate/trial environment and required roles already exist.

1. Checkpoint scenario: govern a synthetic top-level group

You are the platform/security architect for a fictional group training/platform with three projects:

ID Project Classification Owner
101 payments-api regulated payments-team
102 docs-site standard docs-team
103 legacy-worker regulated but temporary exception legacy-team

The security team owns training/security-policy-management. Application teams do not own or merge changes to that repository. The mandatory exercise is local; any live Ultimate/trial step is optional and disposable.

2. Map requirements before writing policy

Write the mapping first:

Requirement Mechanism Evidence
R1: regulated projects run Secret Detection on main Scan execution policy scoped by compliance framework Policy commit + target pipeline scanner job/report.
R2: projects 101/102 run provenance preflight before normal jobs Pipeline execution policy, inject_policy Policy job log + target pipeline SHA.
R3: security violations on protected target branch require independent approval Merge request approval policy (Ultimate live/fixture here) MR approval rule/violation + completed scanner evidence.
R4: policy changes require independent security review Protected policy-project default branch + MR approval/change process Policy MR + approver + commit SHA + audit event where available.
R5: legacy exception expires External exception register plus narrow technical scope/bypass only if needed Owner + expiry + compensating control + removal proof.

3. Make two predictions before creating files

Prediction A: if the policy project is linked to training/platform, all three descendants are candidates through inheritance; individual policy scopes then select the effective set.

Prediction B: the provenance policy below targets project IDs 101 and 102 only. Project 103 does not receive that job unless policy scope changes. Write these expected sets into evidence/predictions.txt.

4. Build the policy and evidence fixtures

---
scan_execution_policy:
  - name: Regulated secret detection
    description: Synthetic Chapter 27 policy
    enabled: true
    rules:
      - type: pipeline
        branches: [main]
    actions:
      - scan: secret_detection
    policy_scope:
      compliance_frameworks:
        - id: 27

pipeline_execution_policy:
  - name: Required provenance preflight
    description: Synthetic Chapter 27 policy
    enabled: true
    pipeline_config_strategy: inject_policy
    content:
      include:
        - project: training/security-policy-ci
          file: provenance.yml
          ref: v1.0.0
    suffix: on_conflict
    policy_scope:
      projects:
        including:
          - id: 101
          - id: 102
provenance-preflight:
  stage: .pipeline-policy-pre
  script:
    - echo "synthetic provenance gate"
    - test -f provenance.attested

Also create a synthetic MR evaluation record for R3 rather than claiming Free can enforce it:

{
  "merge_request": 27,
  "target_branch": "main",
  "protected": true,
  "scanner_reports_complete": true,
  "new_high_findings": 1,
  "policy_result": "approval_required",
  "required_approvals": 1,
  "synthetic": true
}

5. Validate provenance and scope locally

mkdir -p .gitlab/security-policies policy-ci evidence
# Save policy.yml and provenance.yml exactly as shown.
git add .
git commit -m "Add Chapter 27 checkpoint policy fixtures"
POLICY_SHA=$(git rev-parse HEAD)
printf 'policy_sha=%s
' "$POLICY_SHA" | tee evidence/policy-identity.txt
sha256sum .gitlab/security-policies/policy.yml policy-ci/provenance.yml | tee evidence/policy-hashes.txt
# Verify intended project IDs appear exactly where expected:
grep -nE 'id: (101|102|103)|compliance_frameworks|pipeline_execution_policy|scan_execution_policy' .gitlab/security-policies/policy.yml

6. Inject one violation and preserve the original cause

Project 101 has no provenance.attested. Simulate the policy job:

set +e
test -f provenance.attested
rc=$?
printf 'policy_job=provenance-preflight exit_code=%s cause=%s
' "$rc" 'provenance.attested missing' | tee evidence/violation.txt
test "$rc" -ne 0 || exit 1
set -e

Do not “fix” this by removing the policy. For project 101, create the expected synthetic attestation only after confirming the requirement is legitimate:

printf 'sha256:synthetic-ch27
' > provenance.attested
test -f provenance.attested
printf '%s
' 'policy_job=provenance-preflight result=pass' | tee evidence/repair.txt

7. Process one legitimate exception instead of a hidden bypass

Project 103 cannot yet produce the attestation. Record an exception:

{
  "exception_id": "EX-27-001",
  "project_id": 103,
  "requirement": "provenance-preflight",
  "owner": "legacy-team-owner",
  "approved_by": "security-governance",
  "reason": "training fixture: legacy build lacks marker",
  "expires_on": "2026-09-30",
  "compensating_control": "manual provenance verification before release",
  "status": "approved-training-fixture"
}

The expiry date is outside the policy syntax on purpose. Technical bypass settings do not replace governance lifecycle metadata. In a real system, schedule review before expiry and record the evidence that the exclusion/bypass was removed.

8. Prove separation-of-duties assumptions

Write an ownership matrix and challenge each row:

Action Security governance App Maintainer Why
Merge policy.yml change Required independent owner/reviewer Should not be sole authority Policy subject cannot silently rewrite control.
Change application source No routine ownership required Yes Developers remain productive inside constraints.
Link/unlink security policy project Owner / manage_security_policy_link No unless explicitly delegated Assignment is governance-sensitive.
Approve documented exception Security/compliance owner Requester may supply evidence, not self-approve Maintains separation between request and authorization.

On a live Ultimate sandbox, verify actual role memberships and protected-branch rules rather than assuming the matrix matches reality.

9. Optional Ultimate/trial validation

If you already have a disposable Ultimate/trial group, create a disabled or narrowly scoped test policy first. Use a merge request to change policy YAML, merge it, record the policy commit, then trigger one tiny project pipeline/MR. Verify policy-originated jobs/approval state and audit events. Never enable broad group scope until the one-project test behaves as predicted.

10. Evidence packet

Retain only sanitized evidence:

  • GitLab version/offering/tier assumption;
  • synthetic group/project IDs and expected scope;
  • policy commit SHA and file hashes;
  • policy-type-to-requirement map;
  • violation and repaired result;
  • exception owner/expiry/compensating control;
  • separation-of-duties matrix;
  • optional live pipeline/MR/audit IDs—but no tokens or complete environment dumps.

11. Cleanup and rollback

git status --short
git log --oneline --decorate -3
# After retaining sanitized evidence, remove local training files/repository as appropriate.
# In a live Ultimate sandbox: unlink policies first, verify enforcement/link removal,
# then delete only disposable policy/target projects after proving no other targets depend on them.

Policy deletion and unlinking are not interchangeable: deleting a target project removes the lab target, while unlinking changes enforcement relationships. Verify both through read-back.

12. Final verification checklist

  • Each requirement maps to exactly one primary enforcement/evidence mechanism.
  • Expected project scope is written before enforcement.
  • Policy file identity is pinned by commit/hash.
  • The violation retains its original reason and exit state.
  • The repair satisfies the control without disabling it.
  • The legitimate exception has owner, rationale, expiry, compensating control, and approval.
  • Policy owners are separate from application maintainers for critical control changes.
  • Cleanup is verified rather than assumed.

Knowledge check

Why does the checkpoint separate requirement mapping from policy YAML?

Project 103 is under the linked group but excluded from one policy. Is inheritance broken?

Why is exception expiry kept in an explicit register even if GitLab has a technical bypass setting?

The provenance job fails on project 101. What is the safer correction?

What does this chapter add to a production GitLab operating model?

What is the natural next topic after central policy enforcement?

13. Chapter close and bridge to Chapter 28

Chapter 27 turns project-level security evidence into organization-level governance. You can now distinguish policy intent from execution, scope from inheritance, enforcement from evidence, and bypass from a governed exception. Chapter 28 moves this operating model to Kubernetes: how GitLab’s Agent, CI/CD identities, environments, and GitOps workflows cross the trust boundary into a cluster.

Primary sources and version notes

These lessons were finalized against current official GitLab documentation on 2026-08-22. Re-check tier, feature status, policy schema, permission, audit-event, and Self-Managed-version behavior before applying the same design later.

Next chapter

Kubernetes Agent, GitOps Workflows, Cluster Access, Environments, and Deployment Integration

Carry the governance and identity model into GitLab-to-Kubernetes trust boundaries and GitOps deployment workflows.

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
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.