[{"data":1,"prerenderedAt":719},["ShallowReactive",2],{"/en-us/blog/tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies/":3,"navigation-en-us":38,"banner-en-us":465,"footer-en-us":482,"Dan Rabinovitz":691,"next-steps-en-us":704},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":28,"_id":31,"_type":32,"title":33,"_source":34,"_file":35,"_stem":36,"_extension":37},"/en-us/blog/tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Tutorial: Advanced use case for GitLab Pipeline Execution Policies","Learn how new GitLab Ultimate functionality can enforce a standardized pipeline across an organization for improved compliance.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098083/Blog/Hero%20Images/Blog/Hero%20Images/AdobeStock_397632156_3Ldy1urjMStQCl4qnOBvE0_1750098083312.jpg","https://about.gitlab.com/blog/tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Tutorial: Advanced use case for GitLab Pipeline Execution Policies\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Dan Rabinovitz\"}],\n        \"datePublished\": \"2025-01-22\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Dan Rabinovitz","2025-01-22","[Pipeline execution\npolicies](https://docs.gitlab.com/ee/user/application_security/policies/pipeline_execution_policies.html)\nare a newer addition to the GitLab DevSecOps platform and a powerful\nmechanism to enforce CI/CD jobs across applicable projects. They enable\nplatform engineering or security teams to inject jobs into developers’ YAML\npipeline definition files, guaranteeing that certain CI/CD jobs will execute\nno matter what a developer defines in their \\`.gitlab-ci.yml\\` file. \n\n\nThis article will explain how to utilize pipeline execution policies to\ncreate guardrails around the stages or jobs that a developer can use in\ntheir pipeline definition. In regulated environments, this may be necessary\nto ensure developers adhere to a standard set of jobs or stages in their\nGitLab pipeline. Any job or stage that a developer adds to their pipeline\nthat does not adhere to a corporate standard will cause the pipeline to\nfail. \n\n\nOne example use case for pipeline execution policies is ensuring a security\nscanner job runs. Let’s say an organization has made an investment in a\nthird-party security scanner and they have a requirement that the external\nscan runs before any merge is made into the main branch. Without a pipeline\nexecution policy, a developer could easily skip this step by not including\nthe required code in their `.gitlab-ci.yml` file.  With a pipeline execution\npolicy in place, a security team can guarantee the external security\nscanning job executes regardless of how a developer defines their pipeline.\n\n\nTo use pipeline execution policies to enforce these restrictions requires\ntwo parts: a shell script to make calls to the GitLab API and the policy\nitself. This tutorial uses a bash script; if your runner uses a different\nscripting language, it is easy to adapt to other languages.\n\n\nHere is the example shell script I will use for this exercise:\n\n\n``` \n\n#!/bin/bash\n\n\necho \"Checking pipeline stages and jobs...\"\n\n\n# Pull the group access token from the environment variable\n\nGROUP_ACCESS_TOKEN=\"$PIPELINE_TOKEN\"\n\n\necho \"PROJECT_ID: $PROJECT_ID\"\n\necho \"PIPELINE_ID: $PIPELINE_ID\"\n\n\nif [ -z \"$GROUP_ACCESS_TOKEN\" ]; then  \n  echo \"GROUP_ACCESS_TOKEN (MR_GENERATOR) is not set\"\n  exit 1\nfi\n\n\nif [ -z \"$PROJECT_ID\" ]; then\n  echo \"PROJECT_ID is not set\"\n  exit 1\nfi\n\n\nif [ -z \"$PIPELINE_ID\" ]; then\n  echo \"PIPELINE_ID is not set\"\n  exit 1\nfi\n\n\n# Use the group access token for the API request\n\napi_url=\"$GITLAB_API_URL/projects/$PROJECT_ID/pipelines/$PIPELINE_ID/jobs\"\n\necho \"API URL: $api_url\"\n\n\n# Fetch pipeline jobs using the group access token\n\njobs=$(curl --silent --header \"PRIVATE-TOKEN: $GROUP_ACCESS_TOKEN\"\n\"$api_url\")\n\necho \"Fetched Jobs: $jobs\"\n\n\nif [[ \"$jobs\" == *\"404 Project Not Found\"* ]]; then\n  echo \"Failed to authenticate with GitLab API: Project not found\"\n  exit 1\nfi\n\n\n# Extract stages and jobs\n\npipeline_stages=$(echo \"$jobs\" | grep -o '\"stage\":\"[^\"]*\"' | cut -d '\"' -f 4\n| sort | uniq | tr '\\n' ',')\n\npipeline_jobs=$(echo \"$jobs\" | grep -o '\"name\":\"[^\"]*\"' | cut -d '\"' -f 4 |\nsort | uniq | tr '\\n' ',')\n\n\necho \"Pipeline Stages: $pipeline_stages\"  \n\necho \"Pipeline Jobs: $pipeline_jobs\"\n\n\n# Check if pipeline stages are approved\n\nfor stage in $(echo $pipeline_stages | tr ',' ' '); do \n  echo \"Checking stage: $stage\"\n  if ! [[ \",$APPROVED_STAGES,\" =~ \",$stage,\" ]]; then\n    echo \"Stage $stage is not approved.\"\n    exit 1\n  fi\ndone\n\n\n# Check if pipeline jobs are approved \n\nfor job in $(echo $pipeline_jobs | tr ',' ' '); do\n  echo \"Checking job: $job\"\n  if ! [[ \",$APPROVED_JOBS,\" =~ \",$job,\" ]]; then\n    echo \"Job $job is not approve\n```\n\n\nLet’s break this down a bit. \n\n\nThe first few lines of this code perform some sanity checks, ensuring that a\npipeline ID, project ID, and group access token exist.\n\n\n* A GitLab pipeline ID is a unique numerical identifier that GitLab\nautomatically assigns to each pipeline run.\n\n* A GitLab project ID is a unique numerical identifier assigned to each\nproject in GitLab.\n\n* A GitLab group access token is a token that authenticates and authorizes\naccess to resources at the group level in GitLab. This is in contrast to a\nGitLab personal access token (PAT), which is unique to each user.  \n\n\nThe bulk of the work comes from the [GitLab Projects\nAPI](https://docs.gitlab.com/ee/api/projects.html) call where the script\nrequests the jobs for the specified pipeline. Once you have job information\nfor the currently running pipeline, you can use a simple grep command to\nparse out stage and job names, and store them in variables for comparison.\nThe last portion of the script checks to see if pipeline stages and jobs are\non the approved list. Where do these parameters come from?\n\n\nThis is where [GitLab Pipeline Execution\nPolicies](https://docs.gitlab.com/ee/user/application_security/policies/pipeline_execution_policies.html)\ncome into play. They enable injection of YAML code into a pipeline. How can\nwe leverage injected YAML to execute this shell script?  Here’s a code\nsnippet showing how to do this.\n\n\n```\n\n## With this config, the goal is to create a pre-check job that evaluates\nthe pipeline and fails the job/pipeline if any checks do not pass\n\n\nvariables:\n  GITLAB_API_URL: \"https://gitlab.com/api/v4\"\n  PROJECT_ID: $CI_PROJECT_ID\n  PIPELINE_ID: $CI_PIPELINE_ID\n  APPROVED_STAGES: \".pipeline-policy-pre,pre_check,build,test,deploy\"\n  APPROVED_JOBS: \"pre_check,build_job,test_job,deploy_job\"\n\npre_check:\n  stage: .pipeline-policy-pre\n  script:\n    - curl -H \"PRIVATE-TOKEN:${REPO_ACCESS_TOKEN}\" --url \"https://\u003Cgitlab_URL>/api/v4/projects/\u003Cproject_id>/repository/files/check_settings.sh/raw\" -o pre-check.sh\n    - ls -l\n    - chmod +x pre-check.sh\n    - DEBUG_MODE=false ./pre-check.sh  # Set DEBUG_MODE to true or false\n  allow_failure: true\n```\n\n\nIn this YAML snippet, we set a few variables used in the shell script. Most\nimportantly, this is where approved stages and approved jobs are defined.\nAfter the `variables` section, we then add a new job to the\n`.pipeline-policy-pre` stage. This is a reserved stage for pipeline\nexecution policies and is guaranteed to execute before any stages defined in\na `.gitlab-ci.yml` file.  There is a corresponding `.pipeline-policy-post`\nstage as well, though we will not be using it in this scenario.  \n\n\nThe script portion of the job does the actual work. Here, we leverage a curl\ncommand to execute the shell script defined above. This example includes\nauthentication if it’s located in a private repository. However, if it’s\npublicly accessible, you can forgo this authentication. The last line\ncontrols whether or not the pipeline will fail. In this example, the\npipeline will continue. This is useful for testing – in practice, you would\nlikely set `allow_failure: false` to cause the pipeline to fail. This is\ndesired as the goal of this exercise is to not allow pipelines to continue\nexecution if a developer adds a rogue job or stage.\n\n\nTo utilize this YAML, save it to a `.yml` file in a repository of your\nchoice. We’ll see how to connect it to a policy shortly.\n\n\nNow, we have our script and our YAML to inject into a developer’s pipeline.\nNext, let’s see how to put this together using a pipeline execution policy.\n\n\nLike creating other policies in GitLab, start by creating a new Pipeline\nExecution Policy by navigating to **Secure > Policies** in the left hand\nnavigation menu. Then, choose **New Policy** at the top right, and select\n**Pipeline Execution Policy** from the policy creation options.  \n\n\nFor this exercise, you can leave the **Policy Scope** set to the default\noptions. In the **Actions** section, be sure to choose **Inject** and select\nthe project and file where you’ve saved your YAML code snippet. Click on\n**Update via Merge Request** at the very bottom to create an MR that you can\nthen merge into your project.\n\n\nIf this is your first security policy, clicking on **Merge** in the MR will\ncreate a [Security Policy\nProject](https://docs.gitlab.com/ee/user/application_security/policies/vulnerability_management_policy.html),\nwhich is a project to store all security policies. When implementing any\ntype of security policy in a production environment, [access to this project\nshould be restricted](https://docs.gitlab.com/ee/user/project/members/) so\ndevelopers cannot make changes to security policies. In fact, you may also\nwant to consider storing YAML code that’s used by pipeline execution\npolicies in this project to restrict access as well, though this is not a\nrequirement.  \n\nExecuting a pipeline where this pipeline execution policy is enabled should\nresult in the following output when you attempt to add an invalid stage to\nthe project `.gitlab-ci.yml` file.\n\n\n![Output of attempting an invalid stage to project gitlab-ci.yml\nfile](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098102/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098102394.png)\n\n\nWhile this use case is very focused on one aspect of security and compliance\nin your organization, this opens the door to other use cases. For example,\nyou may want to make group-level variables accessible to every project\nwithin a group; this is possible with pipeline execution policies. Or, you\nmay want to create a golden pipeline and have developers add to it. The\npossibilities are endless. GitLab customers are finding new and exciting\nways to use this new functionality every day.\n\n\nIf you’re a GitLab Ultimate customer, try this out today and let us know how\nyou’re using pipeline execution policies. Not a GitLab Ultimate customer?\n[Sign up for a free\ntrial](https://about.gitlab.com/free-trial/devsecops/) to get started.\n\n\n## Read more\n\n- [How to integrate custom security scanners into\nGitLab](https://about.gitlab.com/blog/how-to-integrate-custom-security-scanners-into-gitlab/)\n\n- [Integrate external security scanners into your DevSecOps\nworkflow](https://about.gitlab.com/blog/integrate-external-security-scanners-into-your-devsecops-workflow/)\n\n- [Why GitLab is deprecating compliance pipelines in favor of security\npolicies](https://about.gitlab.com/blog/why-gitlab-is-deprecating-compliance-pipelines-in-favor-of-security-policies/)\n","security",[21,23,24,25,26,27],"tutorial","public sector","DevSecOps platform","CI/CD","features",{"slug":29,"featured":6,"template":30},"tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies","BlogPost","content:en-us:blog:tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies.yml","yaml","Tutorial Advanced Use Case For Gitlab Pipeline Execution Policies","content","en-us/blog/tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies.yml","en-us/blog/tutorial-advanced-use-case-for-gitlab-pipeline-execution-policies","yml",{"_path":39,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":41,"_id":461,"_type":32,"title":462,"_source":34,"_file":463,"_stem":464,"_extension":37},"/shared/en-us/main-navigation","en-us",{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":392,"minimal":423,"duo":442,"pricingDeployment":451},{"config":43},{"href":44,"dataGaName":45,"dataGaLocation":46},"/","gitlab logo","header",{"text":48,"config":49},"Get free trial",{"href":50,"dataGaName":51,"dataGaLocation":46},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":53,"config":54},"Talk to sales",{"href":55,"dataGaName":56,"dataGaLocation":46},"/sales/","sales",{"text":58,"config":59},"Sign in",{"href":60,"dataGaName":61,"dataGaLocation":46},"https://gitlab.com/users/sign_in/","sign in",[63,107,203,208,313,373],{"text":64,"config":65,"cards":67,"footer":90},"Platform",{"dataNavLevelOne":66},"platform",[68,74,82],{"title":64,"description":69,"link":70},"The most comprehensive AI-powered DevSecOps Platform",{"text":71,"config":72},"Explore our Platform",{"href":73,"dataGaName":66,"dataGaLocation":46},"/platform/",{"title":75,"description":76,"link":77},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":78,"config":79},"Meet GitLab Duo",{"href":80,"dataGaName":81,"dataGaLocation":46},"/gitlab-duo/","gitlab duo ai",{"title":83,"description":84,"link":85},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":86,"config":87},"Learn more",{"href":88,"dataGaName":89,"dataGaLocation":46},"/why-gitlab/","why gitlab",{"title":91,"items":92},"Get started with",[93,98,103],{"text":94,"config":95},"Platform Engineering",{"href":96,"dataGaName":97,"dataGaLocation":46},"/solutions/platform-engineering/","platform engineering",{"text":99,"config":100},"Developer Experience",{"href":101,"dataGaName":102,"dataGaLocation":46},"/developer-experience/","Developer experience",{"text":104,"config":105},"MLOps",{"href":106,"dataGaName":104,"dataGaLocation":46},"/topics/devops/the-role-of-ai-in-devops/",{"text":108,"left":109,"config":110,"link":112,"lists":116,"footer":186},"Product",true,{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"View all Solutions",{"href":115,"dataGaName":111,"dataGaLocation":46},"/solutions/",[117,141,165],{"title":118,"description":119,"link":120,"items":125},"Automation","CI/CD and automation to accelerate deployment",{"config":121},{"icon":122,"href":123,"dataGaName":124,"dataGaLocation":46},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[126,129,133,137],{"text":26,"config":127},{"href":128,"dataGaLocation":46,"dataGaName":26},"/solutions/continuous-integration/",{"text":130,"config":131},"AI-Assisted Development",{"href":80,"dataGaLocation":46,"dataGaName":132},"AI assisted development",{"text":134,"config":135},"Source Code Management",{"href":136,"dataGaLocation":46,"dataGaName":134},"/solutions/source-code-management/",{"text":138,"config":139},"Automated Software Delivery",{"href":123,"dataGaLocation":46,"dataGaName":140},"Automated software delivery",{"title":142,"description":143,"link":144,"items":149},"Security","Deliver code faster without compromising security",{"config":145},{"href":146,"dataGaName":147,"dataGaLocation":46,"icon":148},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[150,155,160],{"text":151,"config":152},"Application Security Testing",{"href":153,"dataGaName":154,"dataGaLocation":46},"/solutions/application-security-testing/","Application security testing",{"text":156,"config":157},"Software Supply Chain Security",{"href":158,"dataGaLocation":46,"dataGaName":159},"/solutions/supply-chain/","Software supply chain security",{"text":161,"config":162},"Software Compliance",{"href":163,"dataGaName":164,"dataGaLocation":46},"/solutions/software-compliance/","software compliance",{"title":166,"link":167,"items":172},"Measurement",{"config":168},{"icon":169,"href":170,"dataGaName":171,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[173,177,181],{"text":174,"config":175},"Visibility & Measurement",{"href":170,"dataGaLocation":46,"dataGaName":176},"Visibility and Measurement",{"text":178,"config":179},"Value Stream Management",{"href":180,"dataGaLocation":46,"dataGaName":178},"/solutions/value-stream-management/",{"text":182,"config":183},"Analytics & Insights",{"href":184,"dataGaLocation":46,"dataGaName":185},"/solutions/analytics-and-insights/","Analytics and insights",{"title":187,"items":188},"GitLab for",[189,194,199],{"text":190,"config":191},"Enterprise",{"href":192,"dataGaLocation":46,"dataGaName":193},"/enterprise/","enterprise",{"text":195,"config":196},"Small Business",{"href":197,"dataGaLocation":46,"dataGaName":198},"/small-business/","small business",{"text":200,"config":201},"Public Sector",{"href":202,"dataGaLocation":46,"dataGaName":24},"/solutions/public-sector/",{"text":204,"config":205},"Pricing",{"href":206,"dataGaName":207,"dataGaLocation":46,"dataNavLevelOne":207},"/pricing/","pricing",{"text":209,"config":210,"link":212,"lists":216,"feature":300},"Resources",{"dataNavLevelOne":211},"resources",{"text":213,"config":214},"View all resources",{"href":215,"dataGaName":211,"dataGaLocation":46},"/resources/",[217,250,272],{"title":218,"items":219},"Getting started",[220,225,230,235,240,245],{"text":221,"config":222},"Install",{"href":223,"dataGaName":224,"dataGaLocation":46},"/install/","install",{"text":226,"config":227},"Quick start guides",{"href":228,"dataGaName":229,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":231,"config":232},"Learn",{"href":233,"dataGaLocation":46,"dataGaName":234},"https://university.gitlab.com/","learn",{"text":236,"config":237},"Product documentation",{"href":238,"dataGaName":239,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":241,"config":242},"Best practice videos",{"href":243,"dataGaName":244,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":246,"config":247},"Integrations",{"href":248,"dataGaName":249,"dataGaLocation":46},"/integrations/","integrations",{"title":251,"items":252},"Discover",[253,258,262,267],{"text":254,"config":255},"Customer success stories",{"href":256,"dataGaName":257,"dataGaLocation":46},"/customers/","customer success stories",{"text":259,"config":260},"Blog",{"href":261,"dataGaName":5,"dataGaLocation":46},"/blog/",{"text":263,"config":264},"Remote",{"href":265,"dataGaName":266,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":268,"config":269},"TeamOps",{"href":270,"dataGaName":271,"dataGaLocation":46},"/teamops/","teamops",{"title":273,"items":274},"Connect",[275,280,285,290,295],{"text":276,"config":277},"GitLab Services",{"href":278,"dataGaName":279,"dataGaLocation":46},"/services/","services",{"text":281,"config":282},"Community",{"href":283,"dataGaName":284,"dataGaLocation":46},"/community/","community",{"text":286,"config":287},"Forum",{"href":288,"dataGaName":289,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":291,"config":292},"Events",{"href":293,"dataGaName":294,"dataGaLocation":46},"/events/","events",{"text":296,"config":297},"Partners",{"href":298,"dataGaName":299,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":301,"textColor":302,"text":303,"image":304,"link":308},"#2f2a6b","#fff","Insights for the future of software development",{"altText":305,"config":306},"the source promo card",{"src":307},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":309,"config":310},"Read the latest",{"href":311,"dataGaName":312,"dataGaLocation":46},"/the-source/","the source",{"text":314,"config":315,"lists":317},"Company",{"dataNavLevelOne":316},"company",[318],{"items":319},[320,325,331,333,338,343,348,353,358,363,368],{"text":321,"config":322},"About",{"href":323,"dataGaName":324,"dataGaLocation":46},"/company/","about",{"text":326,"config":327,"footerGa":330},"Jobs",{"href":328,"dataGaName":329,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":329},{"text":291,"config":332},{"href":293,"dataGaName":294,"dataGaLocation":46},{"text":334,"config":335},"Leadership",{"href":336,"dataGaName":337,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":339,"config":340},"Team",{"href":341,"dataGaName":342,"dataGaLocation":46},"/company/team/","team",{"text":344,"config":345},"Handbook",{"href":346,"dataGaName":347,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":349,"config":350},"Investor relations",{"href":351,"dataGaName":352,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":354,"config":355},"Trust Center",{"href":356,"dataGaName":357,"dataGaLocation":46},"/security/","trust center",{"text":359,"config":360},"AI Transparency Center",{"href":361,"dataGaName":362,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":364,"config":365},"Newsletter",{"href":366,"dataGaName":367,"dataGaLocation":46},"/company/contact/","newsletter",{"text":369,"config":370},"Press",{"href":371,"dataGaName":372,"dataGaLocation":46},"/press/","press",{"text":374,"config":375,"lists":376},"Contact us",{"dataNavLevelOne":316},[377],{"items":378},[379,382,387],{"text":53,"config":380},{"href":55,"dataGaName":381,"dataGaLocation":46},"talk to sales",{"text":383,"config":384},"Get help",{"href":385,"dataGaName":386,"dataGaLocation":46},"/support/","get help",{"text":388,"config":389},"Customer portal",{"href":390,"dataGaName":391,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":393,"login":394,"suggestions":401},"Close",{"text":395,"link":396},"To search repositories and projects, login to",{"text":397,"config":398},"gitlab.com",{"href":60,"dataGaName":399,"dataGaLocation":400},"search login","search",{"text":402,"default":403},"Suggestions",[404,406,410,412,416,420],{"text":75,"config":405},{"href":80,"dataGaName":75,"dataGaLocation":400},{"text":407,"config":408},"Code Suggestions (AI)",{"href":409,"dataGaName":407,"dataGaLocation":400},"/solutions/code-suggestions/",{"text":26,"config":411},{"href":128,"dataGaName":26,"dataGaLocation":400},{"text":413,"config":414},"GitLab on AWS",{"href":415,"dataGaName":413,"dataGaLocation":400},"/partners/technology-partners/aws/",{"text":417,"config":418},"GitLab on Google Cloud",{"href":419,"dataGaName":417,"dataGaLocation":400},"/partners/technology-partners/google-cloud-platform/",{"text":421,"config":422},"Why GitLab?",{"href":88,"dataGaName":421,"dataGaLocation":400},{"freeTrial":424,"mobileIcon":429,"desktopIcon":434,"secondaryButton":437},{"text":425,"config":426},"Start free trial",{"href":427,"dataGaName":51,"dataGaLocation":428},"https://gitlab.com/-/trials/new/","nav",{"altText":430,"config":431},"Gitlab Icon",{"src":432,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":430,"config":435},{"src":436,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":438,"config":439},"Get Started",{"href":440,"dataGaName":441,"dataGaLocation":428},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":443,"mobileIcon":447,"desktopIcon":449},{"text":444,"config":445},"Learn more about GitLab Duo",{"href":80,"dataGaName":446,"dataGaLocation":428},"gitlab duo",{"altText":430,"config":448},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":450},{"src":436,"dataGaName":433,"dataGaLocation":428},{"freeTrial":452,"mobileIcon":457,"desktopIcon":459},{"text":453,"config":454},"Back to pricing",{"href":206,"dataGaName":455,"dataGaLocation":428,"icon":456},"back to pricing","GoBack",{"altText":430,"config":458},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":460},{"src":436,"dataGaName":433,"dataGaLocation":428},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":466,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"title":467,"button":468,"image":473,"config":477,"_id":479,"_type":32,"_source":34,"_file":480,"_stem":481,"_extension":37},"/shared/en-us/banner","is now in public beta!",{"text":469,"config":470},"Try the Beta",{"href":471,"dataGaName":472,"dataGaLocation":46},"/gitlab-duo/agent-platform/","duo banner",{"altText":474,"config":475},"GitLab Duo Agent Platform",{"src":476},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":478},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":483,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":484,"_id":687,"_type":32,"title":688,"_source":34,"_file":689,"_stem":690,"_extension":37},"/shared/en-us/main-footer",{"text":485,"source":486,"edit":492,"contribute":497,"config":502,"items":507,"minimal":679},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":487,"config":488},"View page source",{"href":489,"dataGaName":490,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":493,"config":494},"Edit this page",{"href":495,"dataGaName":496,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":498,"config":499},"Please contribute",{"href":500,"dataGaName":501,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":503,"facebook":504,"youtube":505,"linkedin":506},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[508,530,586,615,649],{"title":64,"links":509,"subMenu":513},[510],{"text":25,"config":511},{"href":73,"dataGaName":512,"dataGaLocation":491},"devsecops platform",[514],{"title":204,"links":515},[516,520,525],{"text":517,"config":518},"View plans",{"href":206,"dataGaName":519,"dataGaLocation":491},"view plans",{"text":521,"config":522},"Why Premium?",{"href":523,"dataGaName":524,"dataGaLocation":491},"/pricing/premium/","why premium",{"text":526,"config":527},"Why Ultimate?",{"href":528,"dataGaName":529,"dataGaLocation":491},"/pricing/ultimate/","why ultimate",{"title":531,"links":532},"Solutions",[533,538,540,542,547,552,556,559,563,568,570,573,576,581],{"text":534,"config":535},"Digital transformation",{"href":536,"dataGaName":537,"dataGaLocation":491},"/topics/digital-transformation/","digital transformation",{"text":151,"config":539},{"href":153,"dataGaName":151,"dataGaLocation":491},{"text":140,"config":541},{"href":123,"dataGaName":124,"dataGaLocation":491},{"text":543,"config":544},"Agile development",{"href":545,"dataGaName":546,"dataGaLocation":491},"/solutions/agile-delivery/","agile delivery",{"text":548,"config":549},"Cloud transformation",{"href":550,"dataGaName":551,"dataGaLocation":491},"/topics/cloud-native/","cloud transformation",{"text":553,"config":554},"SCM",{"href":136,"dataGaName":555,"dataGaLocation":491},"source code management",{"text":26,"config":557},{"href":128,"dataGaName":558,"dataGaLocation":491},"continuous integration & delivery",{"text":560,"config":561},"Value stream management",{"href":180,"dataGaName":562,"dataGaLocation":491},"value stream management",{"text":564,"config":565},"GitOps",{"href":566,"dataGaName":567,"dataGaLocation":491},"/solutions/gitops/","gitops",{"text":190,"config":569},{"href":192,"dataGaName":193,"dataGaLocation":491},{"text":571,"config":572},"Small business",{"href":197,"dataGaName":198,"dataGaLocation":491},{"text":574,"config":575},"Public sector",{"href":202,"dataGaName":24,"dataGaLocation":491},{"text":577,"config":578},"Education",{"href":579,"dataGaName":580,"dataGaLocation":491},"/solutions/education/","education",{"text":582,"config":583},"Financial services",{"href":584,"dataGaName":585,"dataGaLocation":491},"/solutions/finance/","financial services",{"title":209,"links":587},[588,590,592,594,597,599,601,603,605,607,609,611,613],{"text":221,"config":589},{"href":223,"dataGaName":224,"dataGaLocation":491},{"text":226,"config":591},{"href":228,"dataGaName":229,"dataGaLocation":491},{"text":231,"config":593},{"href":233,"dataGaName":234,"dataGaLocation":491},{"text":236,"config":595},{"href":238,"dataGaName":596,"dataGaLocation":491},"docs",{"text":259,"config":598},{"href":261,"dataGaName":5,"dataGaLocation":491},{"text":254,"config":600},{"href":256,"dataGaName":257,"dataGaLocation":491},{"text":263,"config":602},{"href":265,"dataGaName":266,"dataGaLocation":491},{"text":276,"config":604},{"href":278,"dataGaName":279,"dataGaLocation":491},{"text":268,"config":606},{"href":270,"dataGaName":271,"dataGaLocation":491},{"text":281,"config":608},{"href":283,"dataGaName":284,"dataGaLocation":491},{"text":286,"config":610},{"href":288,"dataGaName":289,"dataGaLocation":491},{"text":291,"config":612},{"href":293,"dataGaName":294,"dataGaLocation":491},{"text":296,"config":614},{"href":298,"dataGaName":299,"dataGaLocation":491},{"title":314,"links":616},[617,619,621,623,625,627,629,633,638,640,642,644],{"text":321,"config":618},{"href":323,"dataGaName":316,"dataGaLocation":491},{"text":326,"config":620},{"href":328,"dataGaName":329,"dataGaLocation":491},{"text":334,"config":622},{"href":336,"dataGaName":337,"dataGaLocation":491},{"text":339,"config":624},{"href":341,"dataGaName":342,"dataGaLocation":491},{"text":344,"config":626},{"href":346,"dataGaName":347,"dataGaLocation":491},{"text":349,"config":628},{"href":351,"dataGaName":352,"dataGaLocation":491},{"text":630,"config":631},"Sustainability",{"href":632,"dataGaName":630,"dataGaLocation":491},"/sustainability/",{"text":634,"config":635},"Diversity, inclusion and belonging (DIB)",{"href":636,"dataGaName":637,"dataGaLocation":491},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":639},{"href":356,"dataGaName":357,"dataGaLocation":491},{"text":364,"config":641},{"href":366,"dataGaName":367,"dataGaLocation":491},{"text":369,"config":643},{"href":371,"dataGaName":372,"dataGaLocation":491},{"text":645,"config":646},"Modern Slavery Transparency Statement",{"href":647,"dataGaName":648,"dataGaLocation":491},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":650,"links":651},"Contact Us",[652,655,657,659,664,669,674],{"text":653,"config":654},"Contact an expert",{"href":55,"dataGaName":56,"dataGaLocation":491},{"text":383,"config":656},{"href":385,"dataGaName":386,"dataGaLocation":491},{"text":388,"config":658},{"href":390,"dataGaName":391,"dataGaLocation":491},{"text":660,"config":661},"Status",{"href":662,"dataGaName":663,"dataGaLocation":491},"https://status.gitlab.com/","status",{"text":665,"config":666},"Terms of use",{"href":667,"dataGaName":668,"dataGaLocation":491},"/terms/","terms of use",{"text":670,"config":671},"Privacy statement",{"href":672,"dataGaName":673,"dataGaLocation":491},"/privacy/","privacy statement",{"text":675,"config":676},"Cookie preferences",{"dataGaName":677,"dataGaLocation":491,"id":678,"isOneTrustButton":109},"cookie preferences","ot-sdk-btn",{"items":680},[681,683,685],{"text":665,"config":682},{"href":667,"dataGaName":668,"dataGaLocation":491},{"text":670,"config":684},{"href":672,"dataGaName":673,"dataGaLocation":491},{"text":675,"config":686},{"dataGaName":677,"dataGaLocation":491,"id":678,"isOneTrustButton":109},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[692],{"_path":693,"_dir":694,"_draft":6,"_partial":6,"_locale":7,"content":695,"config":699,"_id":701,"_type":32,"title":18,"_source":34,"_file":702,"_stem":703,"_extension":37},"/en-us/blog/authors/dan-rabinovitz","authors",{"name":18,"config":696},{"headshot":697,"ctfId":698},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664796/Blog/Author%20Headshots/dan_rabinovitz_headshot.png","31AXb267jy94budCWQZQyr",{"template":700},"BlogAuthor","content:en-us:blog:authors:dan-rabinovitz.yml","en-us/blog/authors/dan-rabinovitz.yml","en-us/blog/authors/dan-rabinovitz",{"_path":705,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"header":706,"eyebrow":707,"blurb":708,"button":709,"secondaryButton":713,"_id":715,"_type":32,"title":716,"_source":34,"_file":717,"_stem":718,"_extension":37},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":48,"config":710},{"href":711,"dataGaName":51,"dataGaLocation":712},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":53,"config":714},{"href":55,"dataGaName":56,"dataGaLocation":712},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326239160]