Security Policies, Scan Execution, Pipeline Execution, Approval Policies, and Compliance Controls: Configuration, Design Choices, and Tradeoffs
Choose deliberately between project-owned CI and central policy, preventive and detective controls, policy types, scope strategies, exceptions, and compliance-framework integration.
Learning objectives
- Choose among YAML reuse, project CI, scan execution, pipeline execution, approval policies, and compliance frameworks based on control intent.
- Evaluate centralization, enforceability, developer autonomy, auditability, latency, and failure blast radius.
- Design narrow exceptions without turning bypass into permanent policy.
- Use scope/inheritance safely, including the empty-collection and match-mode pitfalls.
- Justify a production policy architecture with maintainability, security, reliability, compatibility, performance, and cost tradeoffs.
1. Central policy versus project-owned configuration
Project-owned CI is the simplest choice when the project team legitimately owns both the requirement and implementation. Central policy is justified when the control must survive project edits, must be consistent across many projects, or must be owned by a separate security/compliance function.
| Approach | Strength | Weakness | Use when |
|---|---|---|---|
| Project .gitlab-ci.yml | Fast feedback, team autonomy, easy customization. | Project maintainers can remove or weaken the job unless separately protected. | The check is a team-owned engineering practice. |
| Shared include/component | Central reuse with explicit consumer dependency. | Consumer may still remove/change the include. | You want reuse more than hard enforcement. |
| Security policy | Central assignment and protected enforcement. | Ultimate-only; larger blast radius; policy interactions require governance. | The requirement must not be optional for target projects. |
2. Preventive enforcement versus detective reporting
A preventive control blocks or changes delivery behavior before an unsafe action completes. An MR approval policy that requires approval before merge is preventive. A detective control records a violation and lets the workflow continue, such as a warn-mode policy or compliance report that creates review evidence.
Do not make every signal blocking. If a low-confidence scanner frequently fails, a hard gate can train developers to seek bypasses. Conversely, a critical separation-of-duties requirement should not be implemented as an informational dashboard only.
3. Scan execution versus pipeline execution versus approval policy
The decision is about what must happen and when GitLab can know the answer.
| Requirement | Preferred control | Why |
|---|---|---|
| Run a supported GitLab scanner with standard options | Scan execution policy | Purpose-built, concise, centrally enforced scanner execution. |
| Run arbitrary internal validation or third-party tooling | Pipeline execution policy | Enforces custom CI/CD jobs/configuration. |
| Require human review when completed scan evidence crosses a threshold | MR approval policy | Acts on completed MR/pipeline evidence and approval state. |
| Run policy CI on calendar cadence independent of commits | Scheduled pipeline execution policy | Creates independent scheduled policy pipelines; GA 19.2. |
4. Pipeline execution strategy is an architectural choice
Current GitLab pipeline execution policies support
inject_policy and override_project_ci;
inject_ci is deprecated.
inject_policy adds policy jobs while retaining project
CI. override_project_ci gives policy authors much
stronger control and must deliberately include any project
configuration that should remain.
For organization baselines, prefer the least invasive strategy that
satisfies the requirement. Reserve
override_project_ci for cases where
replacement/controlled merging is an explicit governance decision,
because stage-order and duplicate-job mistakes can break delivery.
5. Strict global baseline versus scoped exceptions
Start with the broadest requirement that is actually universal, then narrow exceptions explicitly. Policy scope can target projects, groups, and compliance frameworks. Inheritance lowers administrative overhead, but incorrect scope can either leave gaps or break unrelated projects.
Use warn mode where supported to measure impact before strict enforcement. Current merge request approval-policy warn mode is GA and creates auditable bypass behavior when a user dismisses a violation.
6. Scope logic needs the same rigor as firewall rules
policy_scope conditions can interact. The default
matching behavior is restrictive all; current GitLab
also supports match_mode: any. Combining broad
exclusions with any can unexpectedly widen scope. Treat
scope changes as code and calculate the affected project set before
merging.
# Synthetic scope review table, not GitLab API output
projects:
101 payments-api regulated INCLUDE
102 docs-site none EXCLUDE
103 legacy-worker exception EXCLUDE until 2026-09-30
# Review output should name concrete project IDs/paths, not only labels.
7. Compliance framework versus security policy
Compliance frameworks (Premium/Ultimate) identify projects that share requirements and can carry controls. In Ultimate, security policies can scope enforcement by compliance framework. This yields a clean separation: project/framework classification is maintained by governance owners; enforcement logic remains in security policy projects.
Do not assume a framework label is itself a complete control. A label says “this project is in scope.” You still need enforceable settings/policies and evidence that controls are operating.
8. Worked production scenario
A platform team owns 80 services. Twenty process regulated data; ten are legacy systems with a temporary exception. Choose an architecture:
| Decision dimension | Chosen design | Justification |
|---|---|---|
| Classification | Apply a compliance framework to the 20 regulated projects. | Central, auditable scope rather than naming 20 projects in every policy. |
| Baseline scan | Scan execution policy for supported scanner. | Low customization and consistent scanner execution. |
| Custom provenance gate |
Pipeline execution policy with inject_policy.
|
Custom internal job must run before project jobs without replacing project CI. |
| Merge risk gate | MR approval policy on protected default branches. | Human approval is needed only after completed evidence is evaluated. |
| Legacy exception | Explicit exclusion + exception register with owner/expiry/compensating control. | Avoid hidden permanent bypass; maintain a reviewable sunset. |
| Rollout | One project → subgroup → framework scope. | Limits outage blast radius and validates assumptions. |
9. Reliability, performance, and cost are policy properties
Central jobs add runner queue time, compute, network use, artifact/report storage, and possible external-system pressure. Avoid “more scans everywhere” without understanding pipeline critical paths. Scheduled policies create additional pipelines even without commits. Policy failure behavior should be designed so deterministic misconfiguration fails visibly rather than creating retry storms.
10. Decision checklist
- What exact requirement is being enforced?
- Who owns the requirement, policy code, and target project?
- What is the smallest policy type that can enforce it?
- What linked unit and scope produce the intended project set?
- What evidence proves enforcement worked?
- What happens if the policy CI file is unavailable?
- How are exceptions owned, expired, and audited?
- What is the rollout and rollback plan?
- What compute/latency/storage impact will central enforcement add?
Knowledge check
Why is a shared include not equivalent to a security policy?
A consumer can usually remove or change an ordinary include; a security policy is centrally assigned/enforced outside ordinary project-owned CI.
When is scan execution preferable to pipeline execution?
When a supported GitLab scanner with standard configuration is the requirement; pipeline execution is better for custom jobs and more complex CI behavior.
What governance metadata is missing from a bare technical bypass?
At minimum owner, rationale, scope, expiry/review date, compensating control, and linked evidence/ticket.
Why can match_mode:any plus an exclusion be dangerous?
An exclusion condition can match most projects, and OR logic can broaden policy reach beyond the explicitly included targets.
What does a compliance framework label prove?
Project classification/scope. It does not by itself prove that required controls executed successfully.
Summary and bridge
A production policy architecture balances central enforceability with developer autonomy, fail-safe behavior, explicit scope, and auditable exceptions. Lesson 4 stress-tests that design with realistic failure modes and diagnostics.
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.
- GitLab 19.3 release
- Security policies
- Policy enforcement
- Security policy projects
- Scan execution policies
- Pipeline execution policies
- Scheduled pipeline execution policies
- Merge request approval policies
- Compliance frameworks
- Compliance and security policy groups
- Compliance and policy settings API
- Audit event types
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.