[{"data":1,"prerenderedAt":1360},["ShallowReactive",2],{"/blog/improve-security-auditing-with-gitlab-operational-container-scanning":3,"navigation-en-us":576,"banner-en-us":1004,"footer-en-us":1014,"blog-post-authors-en-us-Daniel Helfand":1258,"blog-related-posts-en-us-improve-security-auditing-with-gitlab-operational-container-scanning":1273,"blog-promotions-en-us":1298,"next-steps-en-us":1350},{"id":4,"title":5,"authors":6,"body":8,"category":554,"date":555,"description":556,"extension":557,"externalUrl":558,"faq":558,"featured":559,"heroImage":560,"meta":561,"navigation":154,"path":562,"seo":563,"slug":567,"stem":568,"tags":569,"template":574,"updatedDate":558,"__hash__":575},"blogPosts/en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning.md","Improve security auditing with GitLab Operational Container Scanning",[7],"Daniel Helfand",{"type":9,"value":10,"toc":543},"minimark",[11,22,31,39,42,47,50,83,98,102,114,188,195,221,224,232,235,239,248,253,265,269,309,313,319,326,348,351,357,364,368,387,398,416,467,474,488,491,494,507,511,520,539],[12,13,14,15,21],"p",{},"Conducting security scans is a regular part of any software development process. Whether scanning source code (e.g., Java, Python, or other languages), configuration files (e.g., YAML files), or ",[16,17,20],"a",{"href":18,"rel":19},"https://cloudnativenow.com/kubecon-cnc-na-2024/unlocking-the-full-potential-of-container-vulnerability-scans/",[],"container images",", these scanning tools help development teams be proactive about understanding and addressing security threats.",[12,23,24,25,30],{},"Traditionally, developers run these ",[16,26,29],{"href":27,"rel":28},"https://docs.gitlab.com/user/application_security/container_scanning/",[],"security scans as part of CI/CD pipelines",". By including these scans in CI/CD, every change to a project will be reviewed to see if any vulnerabilities are introduced. Understanding security concerns during development helps to assure that changes are addressed before they are deployed to a live environment, but there are many additional benefits to conducting container vulnerability scans post deployment as well.",[12,32,33,38],{},[16,34,37],{"href":35,"rel":36},"https://docs.gitlab.com/user/clusters/agent/vulnerabilities/",[],"GitLab's Operational Container Scanning"," feature allows DevSecOps practitioners to run container vulnerability scans against containers running in a Kubernetes environment. The benefits of conducting a vulnerability scan on deployed containers include regularly scanning the images for new vulnerabilities that are discovered, tracking which environments certain vulnerabilities are deployed to, and also tracking the progress of resolving these vulnerabilities.",[12,40,41],{},"The scans can be configured to run on a regular cadence and on containers in specific namespaces on a Kubernetes cluster. The results of these scans are then sent back to GitLab projects to be viewed via the GitLab UI. To show exactly how the feature works, the next steps in this article will demonstrate how to apply the Operational Container Scanning feature using a GitLab project, sample application, and a Kubernetes cluster.",[43,44,46],"h2",{"id":45},"prerequisites","Prerequisites",[12,48,49],{},"To get started, you will need the following:",[51,52,53,61,69,76],"ul",{},[54,55,56],"li",{},[16,57,60],{"href":58,"rel":59},"https://about.gitlab.com/free-trial/",[],"GitLab Ultimate account",[54,62,63,64],{},"Kubernetes cluster that meets ",[16,65,68],{"href":66,"rel":67},"https://docs.gitlab.com/user/clusters/agent/#supported-kubernetes-versions-for-gitlab-features",[],"GitLab’s Kubernetes version requirements",[54,70,71],{},[16,72,75],{"href":73,"rel":74},"https://kubernetes.io/docs/tasks/tools/#kubectl",[],"kubectl CLI",[54,77,78],{},[16,79,82],{"href":80,"rel":81},"https://helm.sh/docs/intro/install/",[],"helm CLI",[12,84,85,86,91,92,97],{},"Additionally, the walkthrough below will use a ",[16,87,90],{"href":88,"rel":89},"https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial",[],"GitLab project"," that can be forked into a ",[16,93,96],{"href":94,"rel":95},"https://docs.gitlab.com/user/group/",[],"GitLab group"," where you have appropriate permissions to carry out the steps that follow.",[43,99,101],{"id":100},"deploy-a-sample-application","Deploy a sample application",[12,103,104,105,109,110,113],{},"The first action we will carry out is to deploy a sample application to the Kubernetes cluster you will use in this tutorial. Before running the ",[106,107,108],"code",{},"kubectl"," command to deploy a sample application, take a moment to make sure your ",[106,111,112],{},"KUBECONFIG"," is set to the cluster you would like to use. Once you are set up to use your cluster, run the following command:",[115,116,121],"pre",{"className":117,"code":118,"language":119,"meta":120,"style":120},"language-bash shiki shiki-themes github-light","$ kubectl apply -f\nhttps://gitlab.com/gitlab-da/tutorials/cloud-native/go-web-server/-/raw/main/manifests/go-web-server-manifests.yaml\n\nnamespace/go-web-server-dev created  \ndeployment.apps/go-web-server created  \nservice/go-web-server created  \n","bash","",[106,122,123,143,149,156,169,179],{"__ignoreMap":120},[124,125,128,132,136,139],"span",{"class":126,"line":127},"line",1,[124,129,131],{"class":130},"s7eDp","$",[124,133,135],{"class":134},"sYBdl"," kubectl",[124,137,138],{"class":134}," apply",[124,140,142],{"class":141},"sYu0t"," -f\n",[124,144,146],{"class":126,"line":145},2,[124,147,148],{"class":130},"https://gitlab.com/gitlab-da/tutorials/cloud-native/go-web-server/-/raw/main/manifests/go-web-server-manifests.yaml\n",[124,150,152],{"class":126,"line":151},3,[124,153,155],{"emptyLinePlaceholder":154},true,"\n",[124,157,159,162,165],{"class":126,"line":158},4,[124,160,161],{"class":130},"namespace/go-web-server-dev",[124,163,164],{"class":134}," created",[124,166,168],{"class":167},"sgsFI","  \n",[124,170,172,175,177],{"class":126,"line":171},5,[124,173,174],{"class":130},"deployment.apps/go-web-server",[124,176,164],{"class":134},[124,178,168],{"class":167},[124,180,182,185],{"class":126,"line":181},6,[124,183,184],{"class":130},"service/go-web-server",[124,186,187],{"class":134}," created\n",[12,189,190,191,194],{},"Wait for all the pods to be running in the ",[106,192,193],{},"go-web-server-dev"," namespace by running the command below:",[115,196,198],{"className":117,"code":197,"language":119,"meta":120,"style":120},"$ kubectl get pods -n go-web-server-dev -w  \n",[106,199,200],{"__ignoreMap":120},[124,201,202,204,206,209,212,215,218],{"class":126,"line":127},[124,203,131],{"class":130},[124,205,135],{"class":134},[124,207,208],{"class":134}," get",[124,210,211],{"class":134}," pods",[124,213,214],{"class":141}," -n",[124,216,217],{"class":134}," go-web-server-dev",[124,219,220],{"class":141}," -w\n",[12,222,223],{},"You should see output similar to what is shown below:",[115,225,230],{"className":226,"code":228,"language":229,"meta":120},[227],"language-text","NAME                            READY   STATUS    RESTARTS   AGE  \ngo-web-server-f6b8767dc-57269   1/1     Running   0          18m  \ngo-web-server-f6b8767dc-fkct2   1/1     Running   0          18m  \ngo-web-server-f6b8767dc-j4qwg   1/1     Running   0          18m  \n","text",[106,231,228],{"__ignoreMap":120},[12,233,234],{},"Once everything is running, you can set up your forked GitLab project to connect to your Kubernetes cluster and configure the Operational Container Scanning properties.",[43,236,238],{"id":237},"connect-kubernetes-cluster","Connect Kubernetes cluster",[12,240,241,242,247],{},"In this section, you will learn how to connect a Kubernetes cluster to your GitLab project via the ",[16,243,246],{"href":244,"rel":245},"https://docs.gitlab.com/user/clusters/agent/",[],"GitLab Agent for Kubernetes",". By configuring and installing the agent on your Kubernetes cluster, you will be able to also configure Operational Container Scanning.",[249,250,252],"h3",{"id":251},"change-the-id-property-for-gitlabs-kubernetes-agent","Change the id property for GitLab’s Kubernetes agent",[12,254,255,256,264],{},"In the forked GitLab project you are using, change the ",[16,257,260,263],{"href":258,"rel":259},"https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial/-/blob/main/.gitlab/agents/k8s-agent/config.yaml?ref_type=heads#L5",[],[106,261,262],{},"id"," property in the config.yaml file"," to match the group where you have forked the project. By doing this, you will configure the GitLab Agent for Kubernetes to pass information about your cluster back to your GitLab project. Make sure to commit and push this change back to the main branch of the forked project.",[249,266,268],{"id":267},"navigate-to-kubernetes-clusters-page-of-the-project","Navigate to Kubernetes clusters page of the project",[12,270,271,272,276,277,280,281,284,285,288,289,292,293,296,297,299,300,305,306,308],{},"In the GitLab UI, select the ",[273,274,275],"strong",{},"Operate > Kubernetes clusters"," tab of the forked project. Click the ",[273,278,279],{},"Connect a cluster (agent)"," button. Add the name of the agent to the input box under ",[106,282,283],{},"Option 2: Create and register an agent with the UI"," and then click ",[273,286,287],{},"Create and register",". In this case, the name of the agent is ",[106,290,291],{},"k8s-agent"," since the folder under agents with the ",[106,294,295],{},"config.yaml"," file is named ",[106,298,291],{},". Note that this folder can have any name that follows ",[16,301,304],{"href":302,"rel":303},"https://docs.gitlab.com/user/clusters/agent/install/#create-an-agent-configuration-file",[],"Kubernetes naming restrictions"," and that ",[106,307,291],{}," is just being used for simplicity.",[249,310,312],{"id":311},"install-the-gitlab-kubernetes-agent","Install the GitLab Kubernetes agent",[12,314,315,316,318],{},"After registering the agent, you will be asked to run a helm command shown in the GitLab UI from your command line against your Kubernetes cluster. Before running the command, make sure your ",[106,317,112],{}," is still connected to the same cluster where you deployed the sample application.",[12,320,321,322,325],{},"After running the helm command successfully, wait for all pods to be running in the ",[106,323,324],{},"gitlab-agent-k8s-agent"," namespace on your cluster. You can wait for everything to be running using the following command:",[115,327,329],{"className":117,"code":328,"language":119,"meta":120,"style":120},"$ kubectl get pods -n gitlab-agent-k8s-agent -w  \n",[106,330,331],{"__ignoreMap":120},[124,332,333,335,337,339,341,343,346],{"class":126,"line":127},[124,334,131],{"class":130},[124,336,135],{"class":134},[124,338,208],{"class":134},[124,340,211],{"class":134},[124,342,214],{"class":141},[124,344,345],{"class":134}," gitlab-agent-k8s-agent",[124,347,220],{"class":141},[12,349,350],{},"You should see similar output to what is shown below:",[115,352,355],{"className":353,"code":354,"language":229,"meta":120},[227],"NAME                                         READY   STATUS    RESTARTS   AGE  \nk8s-agent-gitlab-agent-v2-6bb676b6bf-v4qml   1/1     Running   0          10m  \nk8s-agent-gitlab-agent-v2-6bb676b6bf-xt7xh   1/1     Running   0          10m  \n",[106,356,354],{"__ignoreMap":120},[12,358,359,360,363],{},"Once the pods are running, your GitLab project should be connected to your Kubernetes cluster and ready to use the Operational Container Scanning feature. Before proceeding, continue running the ",[106,361,362],{},"kubectl get pods -n gitlab-agent-k8s-agent -w"," command to help explain concepts in the next section.",[43,365,367],{"id":366},"operational-container-scanning","Operational Container Scanning",[12,369,370,371,373,374,377,378,383,384,386],{},"In addition to the pods for the GitLab agent running in the ",[106,372,324],{}," namespace, there should eventually be another pod named ",[106,375,376],{},"trivy-scan-go-web-server-dev",". This pod will start and run on a regular cadence and conduct a container vulnerability scan using a tool named ",[16,379,382],{"href":380,"rel":381},"https://trivy.dev/latest/",[],"trivy"," against the ",[106,385,193],{}," namespace where the sample application deployed earlier is running.",[12,388,389,390,397],{},"The Operational Container Scanning properties are defined in the ",[16,391,394,396],{"href":392,"rel":393},"https://gitlab.com/gitlab-da/tutorials/cloud-native/operational-container-scanning-tutorial/-/blob/main/.gitlab/agents/k8s-agent/config.yaml?ref_type=heads#L6-L10",[],[106,395,295],{}," file"," used to set up the GitLab agent for Kubernetes on your cluster.",[12,399,400,401,404,405,408,409,412,413,415],{},"The two main properties to define are ",[106,402,403],{},"cadence",", which specifies how frequently to run the container vulnerability scan, and also the ",[106,406,407],{},"namespaces"," property nested under ",[106,410,411],{},"vulnerability_report",", which defines one or more namespaces to conduct the scan on. You can see how this looks in ",[106,414,295],{}," below:",[115,417,421],{"className":418,"code":419,"language":420,"meta":120,"style":120},"language-yaml shiki shiki-themes github-light","container_scanning:  \n  cadence: '*/5 * * * *'  \n  vulnerability_report:  \n    namespaces:  \n      - go-web-server-dev  \n\n","yaml",[106,422,423,432,445,452,459],{"__ignoreMap":120},[124,424,425,429],{"class":126,"line":127},[124,426,428],{"class":427},"shJU0","container_scanning",[124,430,431],{"class":167},":  \n",[124,433,434,437,440,443],{"class":126,"line":145},[124,435,436],{"class":427},"  cadence",[124,438,439],{"class":167},": ",[124,441,442],{"class":134},"'*/5 * * * *'",[124,444,168],{"class":167},[124,446,447,450],{"class":126,"line":151},[124,448,449],{"class":427},"  vulnerability_report",[124,451,431],{"class":167},[124,453,454,457],{"class":126,"line":158},[124,455,456],{"class":427},"    namespaces",[124,458,431],{"class":167},[124,460,461,464],{"class":126,"line":171},[124,462,463],{"class":167},"      - ",[124,465,466],{"class":134},"go-web-server-dev\n",[12,468,469,470,473],{},"The cadence follows a cron format. In this case, ",[106,471,472],{},"*/5 * * * *"," means the scan will be run every five minutes, but this can be changed to any amount of time (e.g., every 24 hours).",[12,475,476,477,479,480,483,484,487],{},"The vulnerabilities revealed by the scan for containers running in the ",[106,478,193],{}," namespace are sent back to your GitLab project. To see the results, go to the GitLab UI and select your forked project. Select the ",[273,481,482],{},"Secure > Vulnerability report"," option for the project and then select the ",[273,485,486],{},"Operational vulnerabilities"," tab to view scan results.",[12,489,490],{},"The scan results will include information on the severity of the common vulnerabilities and exposures (CVEs), along with the name of the image. By using the tag of the image to include the version of the deployed software along with what environment it is deployed to, you can begin to audit what known vulnerabilities exist in your Kubernetes environments and keep track of how they are being addressed by engineering teams.",[12,492,493],{},"Watch this demo for more information:",[495,496,499,500],"figure",{"className":497},[498],"video_container","\n  ",[501,502,506],"iframe",{"src":503,"frameBorder":504,"allowFullScreen":505},"https://www.youtube.com/embed/2FVQec2J-Ew?si=T6kwPMnPAGwKlkfP","0","true"," ",[43,508,510],{"id":509},"share-your-feedback","Share your feedback",[12,512,513,514,519],{},"Adding GitLab’s Operational Container Scanning to your Kubernetes environments can help development, security, and infrastructure teams have a consistent picture of container security in Kubernetes environments across an organization. In addition to GitLab’s CI container scanning capabilities and the ability to ",[16,515,518],{"href":516,"rel":517},"https://www.youtube.com/watch?v=Zuk7Axs-CRw",[],"scan containers pushed to GitLab’s container registry",", GitLab has solutions at every phase of the software development lifecycle to address container security concerns.",[12,521,522,523,528,529,533,534,538],{},"You can share your feedback on Operational Container Scanning in this ",[16,524,527],{"href":525,"rel":526},"https://forum.gitlab.com/t/operational-container-scanning-feedback/119479",[],"forum post",", which we will share with our product and engineering teams supporting this feature. You can get started with Operational Container Scanning by reading the ",[16,530,532],{"href":35,"rel":531},[],"documentation on the feature"," and ",[16,535,537],{"href":58,"rel":536},[],"starting a free trial of GitLab Ultimate",".",[540,541,542],"style",{},"html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}",{"title":120,"searchDepth":145,"depth":145,"links":544},[545,546,547,552,553],{"id":45,"depth":145,"text":46},{"id":100,"depth":145,"text":101},{"id":237,"depth":145,"text":238,"children":548},[549,550,551],{"id":251,"depth":151,"text":252},{"id":267,"depth":151,"text":268},{"id":311,"depth":151,"text":312},{"id":366,"depth":145,"text":367},{"id":509,"depth":145,"text":510},"security","2025-01-29","Learn how to conduct container vulnerability scans post-deployment to raise awareness of existing threats and to track resolution of vulnerabilities.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664654/Blog/Hero%20Images/AdobeStock_1172300481.jpg",{},"/en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning",{"title":5,"description":556,"ogTitle":5,"ogDescription":556,"noIndex":559,"ogImage":560,"ogUrl":564,"ogSiteName":565,"ogType":566,"canonicalUrls":564},"https://about.gitlab.com/blog/improve-security-auditing-with-gitlab-operational-container-scanning","https://about.gitlab.com","article","improve-security-auditing-with-gitlab-operational-container-scanning","en-us/blog/improve-security-auditing-with-gitlab-operational-container-scanning",[570,571,572,554,573],"features","DevSecOps","tutorial","product","BlogPost","i-y5iCghiRD_0VoM59ZVfrFfbNzoPLBU9seP7J7wDd0",{"logo":577,"freeTrial":582,"sales":587,"login":592,"items":597,"search":924,"minimal":955,"duo":974,"switchNav":983,"pricingDeployment":994},{"config":578},{"href":579,"dataGaName":580,"dataGaLocation":581},"/","gitlab logo","header",{"text":583,"config":584},"Get free trial",{"href":585,"dataGaName":586,"dataGaLocation":581},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":588,"config":589},"Request a demo",{"href":590,"dataGaName":591,"dataGaLocation":581},"/sales/?contact-topic=request-demo","sales",{"text":593,"config":594},"Sign in",{"href":595,"dataGaName":596,"dataGaLocation":581},"https://gitlab.com/users/sign_in/","sign in",[598,627,727,732,846,902],{"text":599,"config":600,"menu":602},"Platform",{"dataNavLevelOne":601},"platform",{"type":603,"columns":604},"cards",[605,611,619],{"title":599,"description":606,"link":607},"The intelligent orchestration platform for DevSecOps",{"text":608,"config":609},"Explore our Platform",{"href":610,"dataGaName":601,"dataGaLocation":581},"/platform/",{"title":612,"description":613,"link":614},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":615,"config":616},"Meet GitLab Duo",{"href":617,"dataGaName":618,"dataGaLocation":581},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":620,"description":621,"link":622},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":623,"config":624},"Learn more",{"href":625,"dataGaName":626,"dataGaLocation":581},"/why-gitlab/","why gitlab",{"text":628,"left":154,"config":629,"menu":631},"Product",{"dataNavLevelOne":630},"solutions",{"type":632,"link":633,"columns":637,"feature":706},"lists",{"text":634,"config":635},"View all Solutions",{"href":636,"dataGaName":630,"dataGaLocation":581},"/solutions/",[638,662,685],{"title":639,"description":640,"link":641,"items":646},"Automation","CI/CD and automation to accelerate deployment",{"config":642},{"icon":643,"href":644,"dataGaName":645,"dataGaLocation":581},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[647,651,654,658],{"text":648,"config":649},"CI/CD",{"href":650,"dataGaLocation":581,"dataGaName":648},"/solutions/continuous-integration/",{"text":612,"config":652},{"href":617,"dataGaLocation":581,"dataGaName":653},"gitlab duo agent platform - product menu",{"text":655,"config":656},"Source Code Management",{"href":657,"dataGaLocation":581,"dataGaName":655},"/solutions/source-code-management/",{"text":659,"config":660},"Automated Software Delivery",{"href":644,"dataGaLocation":581,"dataGaName":661},"Automated software delivery",{"title":663,"description":664,"link":665,"items":670},"Security","Deliver code faster without compromising security",{"config":666},{"href":667,"dataGaName":668,"dataGaLocation":581,"icon":669},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[671,675,680],{"text":672,"config":673},"Application Security Testing",{"href":667,"dataGaName":674,"dataGaLocation":581},"Application security testing",{"text":676,"config":677},"Software Supply Chain Security",{"href":678,"dataGaLocation":581,"dataGaName":679},"/solutions/supply-chain/","Software supply chain security",{"text":681,"config":682},"Software Compliance",{"href":683,"dataGaName":684,"dataGaLocation":581},"/solutions/software-compliance/","software compliance",{"title":686,"link":687,"items":692},"Measurement",{"config":688},{"icon":689,"href":690,"dataGaName":691,"dataGaLocation":581},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[693,697,701],{"text":694,"config":695},"Visibility & Measurement",{"href":690,"dataGaLocation":581,"dataGaName":696},"Visibility and Measurement",{"text":698,"config":699},"Value Stream Management",{"href":700,"dataGaLocation":581,"dataGaName":698},"/solutions/value-stream-management/",{"text":702,"config":703},"Analytics & Insights",{"href":704,"dataGaLocation":581,"dataGaName":705},"/solutions/analytics-and-insights/","Analytics and insights",{"title":707,"type":632,"items":708},"GitLab for",[709,715,721],{"text":710,"config":711},"Enterprise",{"icon":712,"href":713,"dataGaLocation":581,"dataGaName":714},"Building","/enterprise/","enterprise",{"text":716,"config":717},"Small Business",{"icon":718,"href":719,"dataGaLocation":581,"dataGaName":720},"Work","/small-business/","small business",{"text":722,"config":723},"Public Sector",{"icon":724,"href":725,"dataGaLocation":581,"dataGaName":726},"Organization","/solutions/public-sector/","public sector",{"text":728,"config":729},"Pricing",{"href":730,"dataGaName":731,"dataGaLocation":581,"dataNavLevelOne":731},"/pricing/","pricing",{"text":733,"config":734,"menu":736},"Resources",{"dataNavLevelOne":735},"resources",{"type":632,"link":737,"columns":741,"feature":835},{"text":738,"config":739},"View all resources",{"href":740,"dataGaName":735,"dataGaLocation":581},"/resources/",[742,775,802],{"title":743,"items":744},"Getting started",[745,750,755,760,765,770],{"text":746,"config":747},"Install",{"href":748,"dataGaName":749,"dataGaLocation":581},"/install/","install",{"text":751,"config":752},"Quick start guides",{"href":753,"dataGaName":754,"dataGaLocation":581},"/get-started/","quick setup checklists",{"text":756,"config":757},"Learn",{"href":758,"dataGaLocation":581,"dataGaName":759},"https://university.gitlab.com/","learn",{"text":761,"config":762},"Product documentation",{"href":763,"dataGaName":764,"dataGaLocation":581},"https://docs.gitlab.com/","product documentation",{"text":766,"config":767},"Best practice videos",{"href":768,"dataGaName":769,"dataGaLocation":581},"/getting-started-videos/","best practice videos",{"text":771,"config":772},"Integrations",{"href":773,"dataGaName":774,"dataGaLocation":581},"/integrations/","integrations",{"title":776,"items":777},"Discover",[778,783,788,793,797],{"text":779,"config":780},"Customer success stories",{"href":781,"dataGaName":782,"dataGaLocation":581},"/customers/","customer success stories",{"text":784,"config":785},"Blog",{"href":786,"dataGaName":787,"dataGaLocation":581},"/blog/","blog",{"text":789,"config":790},"Demo Hub",{"href":791,"dataGaName":792,"dataGaLocation":581},"/demo-hub/","demo hub",{"text":794,"config":795},"The Source",{"href":796,"dataGaName":787,"dataGaLocation":581},"/the-source/",{"text":798,"config":799},"Remote",{"href":800,"dataGaName":801,"dataGaLocation":581},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":803,"items":804},"Connect",[805,810,815,820,825,830],{"text":806,"config":807},"GitLab Services",{"href":808,"dataGaName":809,"dataGaLocation":581},"/services/","services",{"text":811,"config":812},"Contribute",{"href":813,"dataGaName":814,"dataGaLocation":581},"https://contributors.gitlab.com","contribute",{"text":816,"config":817},"Community",{"href":818,"dataGaName":819,"dataGaLocation":581},"/community/","community",{"text":821,"config":822},"Forum",{"href":823,"dataGaName":824,"dataGaLocation":581},"https://forum.gitlab.com/","forum",{"text":826,"config":827},"Events",{"href":828,"dataGaName":829,"dataGaLocation":581},"/events/","events",{"text":831,"config":832},"Partners",{"href":833,"dataGaName":834,"dataGaLocation":581},"/partners/","partners",{"config":836,"title":839,"text":840,"link":841},{"background":837,"textColor":838},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":842,"config":843},"Read the latest",{"href":844,"dataGaName":845,"dataGaLocation":581},"/whats-new/","whats new",{"text":847,"config":848,"menu":850},"Company",{"dataNavLevelOne":849},"company",{"type":632,"columns":851},[852],{"items":853},[854,859,865,867,872,877,882,887,892,897],{"text":855,"config":856},"About",{"href":857,"dataGaName":858,"dataGaLocation":581},"/company/","about",{"text":860,"config":861,"footerGa":864},"Jobs",{"href":862,"dataGaName":863,"dataGaLocation":581},"/jobs/","jobs",{"dataGaName":863},{"text":826,"config":866},{"href":828,"dataGaName":829,"dataGaLocation":581},{"text":868,"config":869},"Leadership",{"href":870,"dataGaName":871,"dataGaLocation":581},"/company/team/e-group/","leadership",{"text":873,"config":874},"Handbook",{"href":875,"dataGaName":876,"dataGaLocation":581},"https://handbook.gitlab.com/","handbook",{"text":878,"config":879},"Investor relations",{"href":880,"dataGaName":881,"dataGaLocation":581},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":883,"config":884},"Trust Center",{"href":885,"dataGaName":886,"dataGaLocation":581},"/security/","trust center",{"text":888,"config":889},"AI Transparency Center",{"href":890,"dataGaName":891,"dataGaLocation":581},"/ai-transparency-center/","ai transparency center",{"text":893,"config":894},"Newsletter",{"href":895,"dataGaName":896,"dataGaLocation":581},"/company/contact/#contact-forms","newsletter",{"text":898,"config":899},"Press",{"href":900,"dataGaName":901,"dataGaLocation":581},"/press/","press",{"text":903,"config":904,"menu":905},"Contact us",{"dataNavLevelOne":849},{"type":632,"columns":906},[907],{"items":908},[909,914,919],{"text":910,"config":911},"Talk to sales",{"href":912,"dataGaName":913,"dataGaLocation":581},"/sales/","talk to sales",{"text":915,"config":916},"Support portal",{"href":917,"dataGaName":918,"dataGaLocation":581},"https://support.gitlab.com/hc/en-us","support portal",{"text":920,"config":921},"Customer portal",{"href":922,"dataGaName":923,"dataGaLocation":581},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":925,"login":926,"suggestions":933},"Close",{"text":927,"link":928},"To search repositories and projects, login to",{"text":929,"config":930},"gitlab.com",{"href":595,"dataGaName":931,"dataGaLocation":932},"search login","search",{"text":934,"default":935},"Suggestions",[936,938,942,944,948,952],{"text":612,"config":937},{"href":617,"dataGaName":612,"dataGaLocation":932},{"text":939,"config":940},"Code Suggestions (AI)",{"href":941,"dataGaName":939,"dataGaLocation":932},"/solutions/code-suggestions/",{"text":648,"config":943},{"href":650,"dataGaName":648,"dataGaLocation":932},{"text":945,"config":946},"GitLab on AWS",{"href":947,"dataGaName":945,"dataGaLocation":932},"/partners/technology-partners/aws/",{"text":949,"config":950},"GitLab on Google Cloud",{"href":951,"dataGaName":949,"dataGaLocation":932},"/partners/technology-partners/google-cloud-platform/",{"text":953,"config":954},"Why GitLab?",{"href":625,"dataGaName":953,"dataGaLocation":932},{"freeTrial":956,"mobileIcon":961,"desktopIcon":966,"secondaryButton":969},{"text":957,"config":958},"Start free trial",{"href":959,"dataGaName":586,"dataGaLocation":960},"https://gitlab.com/-/trials/new/","nav",{"altText":962,"config":963},"Gitlab Icon",{"src":964,"dataGaName":965,"dataGaLocation":960},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":962,"config":967},{"src":968,"dataGaName":965,"dataGaLocation":960},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":970,"config":971},"Get Started",{"href":972,"dataGaName":973,"dataGaLocation":960},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":975,"mobileIcon":979,"desktopIcon":981},{"text":976,"config":977},"Learn more about GitLab Duo",{"href":617,"dataGaName":978,"dataGaLocation":960},"gitlab duo",{"altText":962,"config":980},{"src":964,"dataGaName":965,"dataGaLocation":960},{"altText":962,"config":982},{"src":968,"dataGaName":965,"dataGaLocation":960},{"button":984,"mobileIcon":989,"desktopIcon":991},{"text":985,"config":986},"/switch",{"href":987,"dataGaName":988,"dataGaLocation":960},"#contact","switch",{"altText":962,"config":990},{"src":964,"dataGaName":965,"dataGaLocation":960},{"altText":962,"config":992},{"src":993,"dataGaName":965,"dataGaLocation":960},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":995,"mobileIcon":1000,"desktopIcon":1002},{"text":996,"config":997},"Back to pricing",{"href":730,"dataGaName":998,"dataGaLocation":960,"icon":999},"back to pricing","GoBack",{"altText":962,"config":1001},{"src":964,"dataGaName":965,"dataGaLocation":960},{"altText":962,"config":1003},{"src":968,"dataGaName":965,"dataGaLocation":960},{"title":1005,"titleMobile":1006,"button":1007,"config":1012},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":623,"config":1008},{"href":1009,"dataGaName":1010,"dataGaLocation":1011},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1013,"disabled":559},"release",{"data":1015},{"text":1016,"source":1017,"edit":1023,"contribute":1028,"config":1033,"items":1038,"minimal":1247},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1018,"config":1019},"View page source",{"href":1020,"dataGaName":1021,"dataGaLocation":1022},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1024,"config":1025},"Edit this page",{"href":1026,"dataGaName":1027,"dataGaLocation":1022},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1029,"config":1030},"Please contribute",{"href":1031,"dataGaName":1032,"dataGaLocation":1022},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1034,"facebook":1035,"youtube":1036,"linkedin":1037},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1039,1086,1139,1183,1215],{"title":728,"links":1040,"subMenu":1055},[1041,1045,1050],{"text":1042,"config":1043},"View plans",{"href":730,"dataGaName":1044,"dataGaLocation":1022},"view plans",{"text":1046,"config":1047},"Why Premium?",{"href":1048,"dataGaName":1049,"dataGaLocation":1022},"/pricing/premium/","why premium",{"text":1051,"config":1052},"Why Ultimate?",{"href":1053,"dataGaName":1054,"dataGaLocation":1022},"/pricing/ultimate/","why ultimate",[1056],{"title":1057,"links":1058},"Contact Us",[1059,1062,1064,1066,1071,1076,1081],{"text":1060,"config":1061},"Contact sales",{"href":912,"dataGaName":591,"dataGaLocation":1022},{"text":915,"config":1063},{"href":917,"dataGaName":918,"dataGaLocation":1022},{"text":920,"config":1065},{"href":922,"dataGaName":923,"dataGaLocation":1022},{"text":1067,"config":1068},"Status",{"href":1069,"dataGaName":1070,"dataGaLocation":1022},"https://status.gitlab.com/","status",{"text":1072,"config":1073},"Terms of use",{"href":1074,"dataGaName":1075,"dataGaLocation":1022},"/terms/","terms of use",{"text":1077,"config":1078},"Privacy statement",{"href":1079,"dataGaName":1080,"dataGaLocation":1022},"/privacy/","privacy statement",{"text":1082,"config":1083},"Cookie preferences",{"dataGaName":1084,"dataGaLocation":1022,"id":1085,"isOneTrustButton":154},"cookie preferences","ot-sdk-btn",{"title":628,"links":1087,"subMenu":1096},[1088,1092],{"text":1089,"config":1090},"DevSecOps platform",{"href":610,"dataGaName":1091,"dataGaLocation":1022},"devsecops platform",{"text":1093,"config":1094},"AI-Assisted Development",{"href":617,"dataGaName":1095,"dataGaLocation":1022},"ai-assisted development",[1097],{"title":1098,"links":1099},"Topics",[1100,1105,1110,1115,1120,1124,1129,1134],{"text":1101,"config":1102},"CICD",{"href":1103,"dataGaName":1104,"dataGaLocation":1022},"/topics/ci-cd/","cicd",{"text":1106,"config":1107},"GitOps",{"href":1108,"dataGaName":1109,"dataGaLocation":1022},"/topics/gitops/","gitops",{"text":1111,"config":1112},"DevOps",{"href":1113,"dataGaName":1114,"dataGaLocation":1022},"/topics/devops/","devops",{"text":1116,"config":1117},"Version Control",{"href":1118,"dataGaName":1119,"dataGaLocation":1022},"/topics/version-control/","version control",{"text":571,"config":1121},{"href":1122,"dataGaName":1123,"dataGaLocation":1022},"/topics/devsecops/","devsecops",{"text":1125,"config":1126},"Cloud Native",{"href":1127,"dataGaName":1128,"dataGaLocation":1022},"/topics/cloud-native/","cloud native",{"text":1130,"config":1131},"AI for Coding",{"href":1132,"dataGaName":1133,"dataGaLocation":1022},"/topics/devops/ai-for-coding/","ai for coding",{"text":1135,"config":1136},"Agentic AI",{"href":1137,"dataGaName":1138,"dataGaLocation":1022},"/topics/agentic-ai/","agentic ai",{"title":1140,"links":1141},"Solutions",[1142,1144,1146,1151,1155,1158,1162,1165,1167,1170,1173,1178],{"text":672,"config":1143},{"href":667,"dataGaName":672,"dataGaLocation":1022},{"text":661,"config":1145},{"href":644,"dataGaName":645,"dataGaLocation":1022},{"text":1147,"config":1148},"Agile development",{"href":1149,"dataGaName":1150,"dataGaLocation":1022},"/solutions/agile-delivery/","agile delivery",{"text":1152,"config":1153},"SCM",{"href":657,"dataGaName":1154,"dataGaLocation":1022},"source code management",{"text":1101,"config":1156},{"href":650,"dataGaName":1157,"dataGaLocation":1022},"continuous integration & delivery",{"text":1159,"config":1160},"Value stream management",{"href":700,"dataGaName":1161,"dataGaLocation":1022},"value stream management",{"text":1106,"config":1163},{"href":1164,"dataGaName":1109,"dataGaLocation":1022},"/solutions/gitops/",{"text":710,"config":1166},{"href":713,"dataGaName":714,"dataGaLocation":1022},{"text":1168,"config":1169},"Small business",{"href":719,"dataGaName":720,"dataGaLocation":1022},{"text":1171,"config":1172},"Public sector",{"href":725,"dataGaName":726,"dataGaLocation":1022},{"text":1174,"config":1175},"Education",{"href":1176,"dataGaName":1177,"dataGaLocation":1022},"/solutions/education/","education",{"text":1179,"config":1180},"Financial services",{"href":1181,"dataGaName":1182,"dataGaLocation":1022},"/solutions/finance/","financial services",{"title":733,"links":1184},[1185,1187,1189,1191,1194,1196,1199,1201,1203,1205,1207,1209,1211,1213],{"text":746,"config":1186},{"href":748,"dataGaName":749,"dataGaLocation":1022},{"text":751,"config":1188},{"href":753,"dataGaName":754,"dataGaLocation":1022},{"text":756,"config":1190},{"href":758,"dataGaName":759,"dataGaLocation":1022},{"text":761,"config":1192},{"href":763,"dataGaName":1193,"dataGaLocation":1022},"docs",{"text":784,"config":1195},{"href":786,"dataGaName":787,"dataGaLocation":1022},{"text":1197,"config":1198},"What's new",{"href":844,"dataGaName":845,"dataGaLocation":1022},{"text":779,"config":1200},{"href":781,"dataGaName":782,"dataGaLocation":1022},{"text":798,"config":1202},{"href":800,"dataGaName":801,"dataGaLocation":1022},{"text":806,"config":1204},{"href":808,"dataGaName":809,"dataGaLocation":1022},{"text":811,"config":1206},{"href":813,"dataGaName":814,"dataGaLocation":1022},{"text":816,"config":1208},{"href":818,"dataGaName":819,"dataGaLocation":1022},{"text":821,"config":1210},{"href":823,"dataGaName":824,"dataGaLocation":1022},{"text":826,"config":1212},{"href":828,"dataGaName":829,"dataGaLocation":1022},{"text":831,"config":1214},{"href":833,"dataGaName":834,"dataGaLocation":1022},{"title":847,"links":1216},[1217,1219,1221,1223,1225,1227,1231,1236,1238,1240,1242],{"text":855,"config":1218},{"href":857,"dataGaName":849,"dataGaLocation":1022},{"text":860,"config":1220},{"href":862,"dataGaName":863,"dataGaLocation":1022},{"text":868,"config":1222},{"href":870,"dataGaName":871,"dataGaLocation":1022},{"text":873,"config":1224},{"href":875,"dataGaName":876,"dataGaLocation":1022},{"text":878,"config":1226},{"href":880,"dataGaName":881,"dataGaLocation":1022},{"text":1228,"config":1229},"Sustainability",{"href":1230,"dataGaName":1228,"dataGaLocation":1022},"/sustainability/",{"text":1232,"config":1233},"Diversity, inclusion and belonging (DIB)",{"href":1234,"dataGaName":1235,"dataGaLocation":1022},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":883,"config":1237},{"href":885,"dataGaName":886,"dataGaLocation":1022},{"text":893,"config":1239},{"href":895,"dataGaName":896,"dataGaLocation":1022},{"text":898,"config":1241},{"href":900,"dataGaName":901,"dataGaLocation":1022},{"text":1243,"config":1244},"Modern Slavery Transparency Statement",{"href":1245,"dataGaName":1246,"dataGaLocation":1022},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1248},[1249,1252,1255],{"text":1250,"config":1251},"Terms",{"href":1074,"dataGaName":1075,"dataGaLocation":1022},{"text":1253,"config":1254},"Cookies",{"dataGaName":1084,"dataGaLocation":1022,"id":1085,"isOneTrustButton":154},{"text":1256,"config":1257},"Privacy",{"href":1079,"dataGaName":1080,"dataGaLocation":1022},[1259],{"id":1260,"title":7,"body":558,"config":1261,"content":1263,"description":558,"extension":1267,"meta":1268,"navigation":154,"path":1269,"seo":1270,"stem":1271,"__hash__":1272},"blogAuthors/en-us/blog/authors/daniel-helfand.yml",{"template":1262},"BlogAuthor",{"name":7,"config":1264},{"headshot":1265,"ctfId":1266},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662418/Blog/Author%20Headshots/dhelfand.png","b9sRP0HJhdPsOEruWUfih","yml",{},"/en-us/blog/authors/daniel-helfand",{},"en-us/blog/authors/daniel-helfand","U_csW5bNItyLp5wX6zV8xvC4yi-USG4wFxbnBMasIFw",[1274,1282,1290],{"title":1275,"description":1276,"heroImage":1277,"category":554,"date":1278,"authors":1279,"slug":1281,"externalUrl":558},"How GitLab tracks vulnerabilities through refactors and reformatting","Learn how GitLab's improved Scope+Offset fingerprinting keeps vulnerability tracking stable across comments, blank lines, and reformatting.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1759320418/xjmqcozxzt4frx0hori3.png","2026-08-12",[1280],"Julian Thome","improved-scope-offset-fingerprinting",{"title":1283,"description":1284,"heroImage":1277,"category":554,"date":1285,"authors":1286,"slug":1289,"externalUrl":558},"GitLab Secrets Manager adds ESO, Terraform, API support","Simplify credential management across your stack. GitLab Secrets Manager provides secure retrieval in Kubernetes, Terraform, and external workflows.","2026-08-06",[1287,1288],"Erick Bajao","Joe Randazzo","gitlab-secrets-manager-add-eso-terraform-api-support",{"title":1291,"description":1292,"heroImage":1293,"category":554,"date":1294,"authors":1295,"slug":1297,"externalUrl":558},"Secure every commit to production with Claude and GitLab","Claude Security catches vulnerabilities inside a coding session. GitLab picks up from there, scanning, enforcing policy, and producing audit evidence for the software lifecycle. ","https://res.cloudinary.com/about-gitlab-com/image/upload/v1756122536/akivvcnafog9c4dhhzkp.png","2026-08-03",[1296],"Alisa Ho","claude-security-and-gitlab",{"promotions":1299},[1300,1314,1325,1336],{"id":1301,"categories":1302,"header":1304,"text":1305,"button":1306,"image":1311},"ai-modernization",[1303],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1307,"config":1308},"Get your AI maturity score",{"href":1309,"dataGaName":1310,"dataGaLocation":787},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1312},{"src":1313},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1315,"categories":1316,"header":1317,"text":1305,"button":1318,"image":1322},"devops-modernization",[573,1123],"Are you just managing tools or shipping innovation?",{"text":1319,"config":1320},"Get your DevOps maturity score",{"href":1321,"dataGaName":1310,"dataGaLocation":787},"/assessments/devops-modernization-assessment/",{"config":1323},{"src":1324},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1326,"categories":1327,"header":1328,"text":1305,"button":1329,"image":1333},"security-modernization",[554],"Are you trading speed for security?",{"text":1330,"config":1331},"Get your security maturity score",{"href":1332,"dataGaName":1310,"dataGaLocation":787},"/assessments/security-modernization-assessment/",{"config":1334},{"src":1335},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1337,"paths":1338,"header":1341,"text":1342,"button":1343,"image":1348},"github-azure-migration",[1339,1340],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1344,"config":1345},"See how GitLab compares to GitHub",{"href":1346,"dataGaName":1347,"dataGaLocation":787},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1349},{"src":1324},{"header":1351,"blurb":1352,"button":1353,"secondaryButton":1358},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1354,"config":1355},"Get your free trial",{"href":1356,"dataGaName":586,"dataGaLocation":1357},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1060,"config":1359},{"href":912,"dataGaName":591,"dataGaLocation":1357},1786803772056]