{"id":49512,"date":"2025-05-28T01:54:48","date_gmt":"2025-05-28T01:54:48","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=49512"},"modified":"2026-02-21T07:28:58","modified_gmt":"2026-02-21T07:28:58","slug":"gitlab-pipeline-enforce-compliance-in-pipeline-code","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/gitlab-pipeline-enforce-compliance-in-pipeline-code\/","title":{"rendered":"Gitlab Pipeline &#8211; Enforce Compliance in pipeline code"},"content":{"rendered":"\n<p>here&#8217;s the <strong>fully updated and GitLab 18.x Cloud\u2013compliant<\/strong> answer to your original question:<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">\u2705 Enforcing Pipeline Standards with Limited Flexibility in GitLab 18.x Cloud (2026)<\/h2>\n\n\n\n<p>GitLab 18.x provides <strong>modern, centralized tools<\/strong> to enforce strict CI\/CD standards while still allowing controlled customization across your projects.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 1. Create <strong>Standardized CI\/CD Templates<\/strong><\/h3>\n\n\n\n<p>Use <strong>central CI\/CD templates<\/strong> to define reusable pipeline logic that can be <strong>included<\/strong> in other projects.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u2705 How:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Store templates in a <strong>central project<\/strong>, e.g., <code>devops\/pipeline-templates<\/code><\/li>\n\n\n\n<li>Reference using <code>include:<\/code> in <code>.gitlab-ci.yml<\/code> of any project<\/li>\n<\/ul>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">include<\/span>:\n  - project: <span class=\"hljs-string\">'devops\/pipeline-templates'<\/span>\n    file: <span class=\"hljs-string\">'\/secure-pipeline.yml'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">\ud83d\udd10 Tip:<\/h4>\n\n\n\n<p>You can <strong>lock template jobs<\/strong> by:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using <code>rules:<\/code> to control when they run<\/li>\n\n\n\n<li>Marking them as <strong>required via Pipeline Execution Policies<\/strong> (see below)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 2. Implement Compliance Checks for Pipelines<\/h3>\n\n\n\n<p>GitLab 18.x replaces &#8220;compliance pipelines&#8221; with <strong>Pipeline Execution Policies<\/strong> \u2014 the official and enforced way to run <strong>compliance-required jobs<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u2705 Where:<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Go to: <strong>Group \u2192 Secure \u2192 Compliance Center \u2192 Policies Tab<\/strong><\/li>\n\n\n\n<li>Click <strong>\u201cNew Policy \u2192 Pipeline\u201d<\/strong><\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">\u2705 Example Policy YAML:<\/h4>\n\n\n\n<p>Enforce <strong>SAST<\/strong> and <strong>Secret Detection<\/strong> on every push in all projects:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">type: pipeline\nname: enforce-sast-<span class=\"hljs-keyword\">and<\/span>-secrets\nenabled: <span class=\"hljs-keyword\">true<\/span>\nrules:\n  - type: pipeline\n    branches:\n      <span class=\"hljs-keyword\">include<\/span>:\n        - <span class=\"hljs-string\">\"*\"<\/span>\n    project_filter:\n      <span class=\"hljs-keyword\">include<\/span>:\n        - <span class=\"hljs-string\">\"*\"<\/span>\nactions:\n  - scan: sast\n  - scan: secret_detection\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>You can also use:<br><code>action: job: job_name@group\/project<\/code><br>to enforce your <strong>custom job templates<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udd39 3. Define <strong>Allowed Customization Options<\/strong><\/h3>\n\n\n\n<p>Limit what project teams can customize by:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Strategy<\/th><th>How to Apply<\/th><\/tr><\/thead><tbody><tr><td>\u2705 Use <code>include:<\/code> for central logic<\/td><td>Forces all teams to inherit your base pipeline<\/td><\/tr><tr><td>\u2705 Lock jobs via Execution Policies<\/td><td>Enforced jobs <strong>cannot be overridden<\/strong> by project maintainers<\/td><\/tr><tr><td>\u2705 Set global variables at group level<\/td><td>Use <strong>Group CI\/CD variables<\/strong> to prevent secrets\/config drift<\/td><\/tr><tr><td>\u2705 Use <code>rules:<\/code> in templates<\/td><td>Control when jobs run based on branches, tags, etc.<\/td><\/tr><tr><td>\u2705 Optional stages for teams<\/td><td>Let teams extend pipelines via <code>extends:<\/code> or <code>workflow: rules:<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Example: Central job with team-controlled overrides<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">.default_security_job:\n  script: <span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Running standard security scan\"<\/span>\n\nsecurity_scan:\n  extends: .default_security_job\n  rules:\n    - <span class=\"hljs-keyword\">if<\/span>: <span class=\"hljs-string\">'$CI_PROJECT_NAME =~ \/internal.*\/'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">\u2705 Summary<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Goal<\/th><th>GitLab 18.x Feature<\/th><\/tr><\/thead><tbody><tr><td>Standard templates<\/td><td><code>include:<\/code> from shared CI\/CD projects<\/td><\/tr><tr><td>Pipeline compliance enforcement<\/td><td>\u2705 <strong>Pipeline Execution Policies<\/strong> (via Compliance Center)<\/td><\/tr><tr><td>Central control with limited flexibility<\/td><td><code>rules<\/code>, <code>extends<\/code>, group variables, protected jobs<\/td><\/tr><tr><td>Custom job enforcement<\/td><td><code>job@group\/project<\/code> in execution policy<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<p>Here\u2019s your <strong>complete GitLab policy project<\/strong> setup, designed for rollout across an entire group. It includes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u2705 A <strong>Pipeline Execution Policy<\/strong> YAML<\/li>\n\n\n\n<li>\u2705 Centralized <strong>CI template project<\/strong> (<code>secure-ci-templates<\/code>)<\/li>\n\n\n\n<li>\u2705 Enforced security scans (<code>SAST<\/code>, <code>Secret Detection<\/code>)<\/li>\n\n\n\n<li>\u2705 A compliance approval check<\/li>\n\n\n\n<li>\u2705 A deploy guard to prevent unreviewed changes to <code>main<\/code><\/li>\n<\/ul>\n\n\n\n<p>Use this with:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>GitLab Group \u2192 Secure \u2192 Compliance Center \u2192 Policies \u2192 New Policy<\/strong><\/li>\n\n\n\n<li>Paste the <code>pipeline<\/code> YAML from the top section<\/li>\n\n\n\n<li>Reference the central project in your teams\u2019 <code>.gitlab-ci.yml<\/code> as shown<\/li>\n<\/ol>\n\n\n\n<script src=\"https:\/\/gist.github.com\/devops-school\/ab38d768294768a31470491130f54562.js\"><\/script>\n","protected":false},"excerpt":{"rendered":"<p>here&#8217;s the fully updated and GitLab 18.x Cloud\u2013compliant answer to your original question: \u2705 Enforcing Pipeline Standards with Limited Flexibility in GitLab 18.x Cloud (2026) GitLab 18.x provides modern, centralized&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-49512","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49512","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=49512"}],"version-history":[{"count":2,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49512\/revisions"}],"predecessor-version":[{"id":58991,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/49512\/revisions\/58991"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=49512"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=49512"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=49512"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}