[{"data":1,"prerenderedAt":1443},["ShallowReactive",2],{"/blog/integrate-external-security-scanners-into-your-devsecops-workflow":3,"navigation-en-us":657,"banner-en-us":1085,"footer-en-us":1095,"blog-post-authors-en-us-Sam Morris":1340,"blog-related-posts-en-us-integrate-external-security-scanners-into-your-devsecops-workflow":1355,"blog-promotions-en-us":1380,"next-steps-en-us":1433},{"id":4,"title":5,"authors":6,"body":8,"category":637,"date":638,"description":639,"extension":640,"externalUrl":641,"faq":641,"featured":642,"heroImage":643,"meta":644,"navigation":104,"path":645,"seo":646,"slug":650,"stem":651,"tags":652,"template":655,"updatedDate":641,"__hash__":656},"blogPosts/en-us/blog/integrate-external-security-scanners-into-your-devsecops-workflow.md","Integrate external security scanners into your DevSecOps workflow",[7],"Sam Morris",{"type":9,"value":10,"toc":625},"minimark",[11,15,18,23,38,42,45,48,52,67,351,356,361,367,375,378,385,389,392,401,405,408,565,568,574,578,581,592,596,621],[12,13,14],"p",{},"Each day you build software there is another opportunity for security vulnerabilities to creep into production. So it is becoming more important than ever to shift security left and put security tests and the vulnerabilities they detect at the forefront of your software development lifecycle.",[12,16,17],{},"While GitLab offers a wide range of different security scanners, our AI-powered DevSecOps platform provides full visibility into the security of your software. We seek to allow you to not only run scans, but also to view results, bake in approval processes via merge request policies, and display current vulnerabilities in your default branch for future triage in our Vulnerability Report.",[19,20,22],"h2",{"id":21},"how-do-security-scans-run","How do security scans run?",[12,24,25,26,30,31,37],{},"GitLab Ultimate displays your vulnerabilities directly in the merge request widget and it updates on every commit. These scans typically run via jobs in a pipeline, whether in the project’s ",[27,28,29],"code",{},".gitlab-ci.yml"," pipeline or in a separately-controlled compliance pipeline, security policy, or ",[32,33,36],"a",{"href":34,"rel":35},"https://docs.gitlab.com/ci/yaml/includes/",[],"included pipeline configuration"," from a separate .yml file. You can run GitLab’s native security scanners or you can run an external scanner. For this blog post, I took running Snyk scans for a spin to see how I could feed the dependency scan results as vulnerability records back into GitLab. Additionally, I utilized a Static Analysis Results Interchange Format (SARIF) converter to read SAST results directly from Snyk without custom scripting.",[19,39,41],{"id":40},"using-external-scanners","Using external scanners",[12,43,44],{},"GitLab is highly extensible, and the platform allows for you to integrate myriad tools. You can use one of our built-in security scanners, or use an external scanner via a job in a pipeline or policy. GitLab serves as a single platform for governance and enforcement, allowing you to bring your own scanners and see the results early in the DevSecOps lifecycle.",[12,46,47],{},"All you have to do to get started is run a security job, and from there you can obtain the results in the merge request and the vulnerability report.",[19,49,51],{"id":50},"run-an-external-scan-from-gitlab-ci","Run an external scan from GitLab CI",[12,53,54,55,58,59,62,63,66],{},"In this example pipeline, I run a Snyk scan externally in the test stage in a job I overrode called ",[27,56,57],{},"gemnasium-maven-dependency_scanning",". First, I install the required packages (npm, Maven, Python3, and Snyk) and then I authorize with my SNYK_TOKEN variable saved in the variables section of my project. Finally, I run a ",[27,60,61],{},"snyk test"," command with the Snyk CLI and output the results to the JSON. This saves my results to the snyk_data_file.json, which I will parse in a script detailed in the next section and save to the required artifact file ",[27,64,65],{},"gl-dependency-scanning-report.json",".",[68,69,74],"pre",{"className":70,"code":71,"language":72,"meta":73,"style":73},"language-yaml shiki shiki-themes github-light","stages:\n  - test\n\nvariables:\n\ninclude:\n  - template: Jobs/Dependency-Scanning.gitlab-ci.yml  \n\ngemnasium-maven-dependency_scanning:\n  image: node:latest\n  stage: test\n  services:\n  - openjdk:11-jre-slim-buster\n  before_script:\n    - apt-get update\n    - apt-get install default-jdk -y\n  script:\n    # Install npm, snyk, and maven\n    - npm install -g npm@latest\n    - npm install -g snyk\n    - npm install maven\n    - npm install python3\n    # Run snyk auth, snyk monitor, snyk test to break build and out report\n    - snyk auth $SNYK_TOKEN\n    - chmod +x mvnw\n    - snyk test --all-projects --json-file-output=snyk_data_file.json || true\n    - python3 convert-snyk-to-gitlab.py\n\n  # Save report to artifacts\n  artifacts:\n    when: always\n    paths: \n      - gl-dependency-scanning-report.json\n\n","yaml","",[27,75,76,89,99,106,114,119,127,144,149,156,167,177,185,193,201,210,218,226,233,241,249,257,265,271,279,287,295,303,308,314,322,333,342],{"__ignoreMap":73},[77,78,81,85],"span",{"class":79,"line":80},"line",1,[77,82,84],{"class":83},"shJU0","stages",[77,86,88],{"class":87},"sgsFI",":\n",[77,90,92,95],{"class":79,"line":91},2,[77,93,94],{"class":87},"  - ",[77,96,98],{"class":97},"sYBdl","test\n",[77,100,102],{"class":79,"line":101},3,[77,103,105],{"emptyLinePlaceholder":104},true,"\n",[77,107,109,112],{"class":79,"line":108},4,[77,110,111],{"class":83},"variables",[77,113,88],{"class":87},[77,115,117],{"class":79,"line":116},5,[77,118,105],{"emptyLinePlaceholder":104},[77,120,122,125],{"class":79,"line":121},6,[77,123,124],{"class":83},"include",[77,126,88],{"class":87},[77,128,130,132,135,138,141],{"class":79,"line":129},7,[77,131,94],{"class":87},[77,133,134],{"class":83},"template",[77,136,137],{"class":87},": ",[77,139,140],{"class":97},"Jobs/Dependency-Scanning.gitlab-ci.yml",[77,142,143],{"class":87},"  \n",[77,145,147],{"class":79,"line":146},8,[77,148,105],{"emptyLinePlaceholder":104},[77,150,152,154],{"class":79,"line":151},9,[77,153,57],{"class":83},[77,155,88],{"class":87},[77,157,159,162,164],{"class":79,"line":158},10,[77,160,161],{"class":83},"  image",[77,163,137],{"class":87},[77,165,166],{"class":97},"node:latest\n",[77,168,170,173,175],{"class":79,"line":169},11,[77,171,172],{"class":83},"  stage",[77,174,137],{"class":87},[77,176,98],{"class":97},[77,178,180,183],{"class":79,"line":179},12,[77,181,182],{"class":83},"  services",[77,184,88],{"class":87},[77,186,188,190],{"class":79,"line":187},13,[77,189,94],{"class":87},[77,191,192],{"class":97},"openjdk:11-jre-slim-buster\n",[77,194,196,199],{"class":79,"line":195},14,[77,197,198],{"class":83},"  before_script",[77,200,88],{"class":87},[77,202,204,207],{"class":79,"line":203},15,[77,205,206],{"class":87},"    - ",[77,208,209],{"class":97},"apt-get update\n",[77,211,213,215],{"class":79,"line":212},16,[77,214,206],{"class":87},[77,216,217],{"class":97},"apt-get install default-jdk -y\n",[77,219,221,224],{"class":79,"line":220},17,[77,222,223],{"class":83},"  script",[77,225,88],{"class":87},[77,227,229],{"class":79,"line":228},18,[77,230,232],{"class":231},"sAwPA","    # Install npm, snyk, and maven\n",[77,234,236,238],{"class":79,"line":235},19,[77,237,206],{"class":87},[77,239,240],{"class":97},"npm install -g npm@latest\n",[77,242,244,246],{"class":79,"line":243},20,[77,245,206],{"class":87},[77,247,248],{"class":97},"npm install -g snyk\n",[77,250,252,254],{"class":79,"line":251},21,[77,253,206],{"class":87},[77,255,256],{"class":97},"npm install maven\n",[77,258,260,262],{"class":79,"line":259},22,[77,261,206],{"class":87},[77,263,264],{"class":97},"npm install python3\n",[77,266,268],{"class":79,"line":267},23,[77,269,270],{"class":231},"    # Run snyk auth, snyk monitor, snyk test to break build and out report\n",[77,272,274,276],{"class":79,"line":273},24,[77,275,206],{"class":87},[77,277,278],{"class":97},"snyk auth $SNYK_TOKEN\n",[77,280,282,284],{"class":79,"line":281},25,[77,283,206],{"class":87},[77,285,286],{"class":97},"chmod +x mvnw\n",[77,288,290,292],{"class":79,"line":289},26,[77,291,206],{"class":87},[77,293,294],{"class":97},"snyk test --all-projects --json-file-output=snyk_data_file.json || true\n",[77,296,298,300],{"class":79,"line":297},27,[77,299,206],{"class":87},[77,301,302],{"class":97},"python3 convert-snyk-to-gitlab.py\n",[77,304,306],{"class":79,"line":305},28,[77,307,105],{"emptyLinePlaceholder":104},[77,309,311],{"class":79,"line":310},29,[77,312,313],{"class":231},"  # Save report to artifacts\n",[77,315,317,320],{"class":79,"line":316},30,[77,318,319],{"class":83},"  artifacts",[77,321,88],{"class":87},[77,323,325,328,330],{"class":79,"line":324},31,[77,326,327],{"class":83},"    when",[77,329,137],{"class":87},[77,331,332],{"class":97},"always\n",[77,334,336,339],{"class":79,"line":335},32,[77,337,338],{"class":83},"    paths",[77,340,341],{"class":87},": \n",[77,343,345,348],{"class":79,"line":344},33,[77,346,347],{"class":87},"      - ",[77,349,350],{"class":97},"gl-dependency-scanning-report.json\n",[352,353,355],"h3",{"id":354},"parse-the-json","Parse the JSON",[12,357,358,359,66],{},"You can see scan results in the merge request widget from any external scanner as long as the artifact of the successful security job is named appropriately, for example, ",[27,360,65],{},[12,362,363,364,366],{},"Here is an example script that converts the Snyk JSON output to the GitLab JSON output. In this example, I open the Snyk data file and load the vulnerability data. I create a new list of dependency files and a new list of vulnerabilities that contain data GitLab needs to display in the vulnerability records, such as the identifier, severity, category, description, and location. I added a few placeholder sections for required fields that I did not need to display in my record. Finally, I saved the contents I parsed out to a new JSON file called ",[27,365,65],{},", which is the required name for the file to be read by GitLab and have its contents displayed in the widget.",[68,368,373],{"className":369,"code":371,"language":372,"meta":73},[370],"language-text","import json\nfrom types import SimpleNamespace\n\nwith open(\"snyk_data_file.json\") as snyk_data_file:\n    snyk_data = json.load(snyk_data_file, object_hook=lambda d: SimpleNamespace(**d))\n\ngitlab_vulns = []\ndependency_files = []\nfor i in snyk_data:\n    dependency_files.append({\"path\": i.path, \"package_manager\": i.packageManager, \"dependencies\": []})\n    for v in i.vulnerabilities:\n        gitlab_identifiers = []\n        for vuln_type, vuln_names in v.identifiers.__dict__.items():\n            if vuln_names: \n                for vuln_name in vuln_names:\n                    gitlab_identifiers.append({\"type\": vuln_type, \"name\": vuln_name, \"value\": vuln_name.partition(\"-\")[2]})\n                gitlab_vulns.append({\"id\": v.id, \"category\": \"dependency_scanning\", \"severity\": v.severity.capitalize(), \"identifiers\": gitlab_identifiers, \"description\": v.description, \"location\": {\"file\": i.displayTargetFile, \"dependency\": {\"package\": {\"name\": \"PLACEHOLDER\"}, \"version\": \"PLACEHOLDER\"}}})\n\n# Dummy data for scan and dependency files \nfull_json = {\"version\": \"15.0.6\", \"dependency_files\": dependency_files, \"scan\": {\"analyzer\": {\"id\": \"snyk\", \"name\": \"Snyk\", \"vendor\": {\"name\": \"Snyk\"}, \"version\": \"1.0.2\"}, \"scanner\": {\"id\": \"my-snyk-scanner\", \"name\": \"My Snyk Scanner\", \"version\": \"1.0.2\", \"vendor\": {\"name\": \"Snyk\"}}, \"end_time\": \"2022-01-28T03:26:02\", \"start_time\": \"2020-01-28T03:26:02\", \"status\": \"success\", \"type\": \"dependency_scanning\"}, \"vulnerabilities\": gitlab_vulns}\n\nwith open(\"gl-dependency-scanning-report.json\", \"w\") as gitlab_file:\n    json.dump(full_json, gitlab_file, default=vars)\n\n","text",[27,374,371],{"__ignoreMap":73},[12,376,377],{},"Now, the vulnerability findings are visible in the merge request widget.",[12,379,380],{},[381,382],"img",{"alt":383,"src":384},"security scanning detection","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098776/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098776479.png",[19,386,388],{"id":387},"what-are-sarif-and-the-sarif-converter","What are SARIF and the SARIF converter?",[12,390,391],{},"SARIF is a file format for the output of static analysis tools. It is incredibly useful when leveraging different security scanners, as all of their output is formatted the same way. This allows for a generic, repeatable, and scalable approach to application security.",[12,393,394,395,400],{},"There is a community-maintained ",[32,396,399],{"href":397,"rel":398},"https://gitlab.com/ignis-build/sarif-converter",[],"SARIF converter",", which takes SARIF files and converts them into ingestible reports. It supports many scanners, including Snyk. This converter works for both SAST and code quality findings. We are going to focus on SAST for this blog.",[352,402,404],{"id":403},"use-a-sarif-converter-to-get-sast-results","Use a SARIF converter to get SAST results",[12,406,407],{},"To leverage the SARIF results, first I trigger a Snyk scan as we did in the previous example, but I save the output to a SARIF file. After this, I use the aforementioned converter to create a new JSON file that I save as a report.",[68,409,411],{"className":70,"code":410,"language":72,"meta":73,"style":73},"snyk:\n  image: node:latest\n  stage: test\n  services:\n  - openjdk:11-jre-slim-buster\n  before_script:\n    - apt-get update\n    - apt-get install default-jdk -y\n    - wget -O sarif-converter https://gitlab.com/ignis-build/sarif-converter/-/releases/permalink/latest/downloads/bin/sarif-converter-linux\n    - chmod +x sarif-converter\n  script:\n    # Install npm, snyk, and maven\n    - npm install -g npm@latest\n    - npm install -g snyk\n    - npm install maven\n    # Run snyk auth, snyk monitor, snyk test to break build and out report\n    - snyk auth $SNYK_TOKEN\n    - chmod +x mvnw\n    - snyk test --all-projects --sarif-file-output=snyk.sarif  || true\n    - ./sarif-converter --type sast snyk.sarif snyk.json\n\n  artifacts:\n    reports:\n      sast: snyk.json\n\n",[27,412,413,420,428,436,442,448,454,460,466,473,480,486,490,496,502,508,512,518,524,531,538,542,548,555],{"__ignoreMap":73},[77,414,415,418],{"class":79,"line":80},[77,416,417],{"class":83},"snyk",[77,419,88],{"class":87},[77,421,422,424,426],{"class":79,"line":91},[77,423,161],{"class":83},[77,425,137],{"class":87},[77,427,166],{"class":97},[77,429,430,432,434],{"class":79,"line":101},[77,431,172],{"class":83},[77,433,137],{"class":87},[77,435,98],{"class":97},[77,437,438,440],{"class":79,"line":108},[77,439,182],{"class":83},[77,441,88],{"class":87},[77,443,444,446],{"class":79,"line":116},[77,445,94],{"class":87},[77,447,192],{"class":97},[77,449,450,452],{"class":79,"line":121},[77,451,198],{"class":83},[77,453,88],{"class":87},[77,455,456,458],{"class":79,"line":129},[77,457,206],{"class":87},[77,459,209],{"class":97},[77,461,462,464],{"class":79,"line":146},[77,463,206],{"class":87},[77,465,217],{"class":97},[77,467,468,470],{"class":79,"line":151},[77,469,206],{"class":87},[77,471,472],{"class":97},"wget -O sarif-converter https://gitlab.com/ignis-build/sarif-converter/-/releases/permalink/latest/downloads/bin/sarif-converter-linux\n",[77,474,475,477],{"class":79,"line":158},[77,476,206],{"class":87},[77,478,479],{"class":97},"chmod +x sarif-converter\n",[77,481,482,484],{"class":79,"line":169},[77,483,223],{"class":83},[77,485,88],{"class":87},[77,487,488],{"class":79,"line":179},[77,489,232],{"class":231},[77,491,492,494],{"class":79,"line":187},[77,493,206],{"class":87},[77,495,240],{"class":97},[77,497,498,500],{"class":79,"line":195},[77,499,206],{"class":87},[77,501,248],{"class":97},[77,503,504,506],{"class":79,"line":203},[77,505,206],{"class":87},[77,507,256],{"class":97},[77,509,510],{"class":79,"line":212},[77,511,270],{"class":231},[77,513,514,516],{"class":79,"line":220},[77,515,206],{"class":87},[77,517,278],{"class":97},[77,519,520,522],{"class":79,"line":228},[77,521,206],{"class":87},[77,523,286],{"class":97},[77,525,526,528],{"class":79,"line":235},[77,527,206],{"class":87},[77,529,530],{"class":97},"snyk test --all-projects --sarif-file-output=snyk.sarif  || true\n",[77,532,533,535],{"class":79,"line":243},[77,534,206],{"class":87},[77,536,537],{"class":97},"./sarif-converter --type sast snyk.sarif snyk.json\n",[77,539,540],{"class":79,"line":251},[77,541,105],{"emptyLinePlaceholder":104},[77,543,544,546],{"class":79,"line":259},[77,545,319],{"class":83},[77,547,88],{"class":87},[77,549,550,553],{"class":79,"line":267},[77,551,552],{"class":83},"    reports",[77,554,88],{"class":87},[77,556,557,560,562],{"class":79,"line":273},[77,558,559],{"class":83},"      sast",[77,561,137],{"class":87},[77,563,564],{"class":97},"snyk.json\n",[12,566,567],{},"After saving the JSON as an artifact, the results are visible in the merge request widget.",[12,569,570],{},[381,571],{"alt":572,"src":573},"security scanning - image 2","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098776/Blog/Content%20Images/Blog/Content%20Images/image2_aHR0cHM6_1750098776479.png",[19,575,577],{"id":576},"get-started","Get started",[12,579,580],{},"In this blog post, you learned how to use both custom scripting and a SARIF converter to view external scanner vulnerabilities in the GitLab merge request widget. These operations can be completed from the pipeline as shown, but also from compliance pipelines and pipeline execution policies, which allow for the enforcement of external scanners. With GitLab Ultimate. you have access to a full DevSecOps platform that allows you to use our scanners or bring your own, but build a shift-left workflow that empowers developers to remediate vulnerabilities before they hit production.",[582,583,584],"blockquote",{},[12,585,586,591],{},[32,587,590],{"href":588,"rel":589},"https://gitlab.com/-/trials/",[],"Trial GitLab Ultimate today"," to begin merging external scanners.",[19,593,595],{"id":594},"more-security-scanning-resources","More security scanning resources",[597,598,599,607,614],"ul",{},[600,601,602],"li",{},[32,603,606],{"href":604,"rel":605},"https://docs.gitlab.com/development/integrations/secure/",[],"Security scanner integration documentation",[600,608,609],{},[32,610,613],{"href":611,"rel":612},"https://about.gitlab.com/blog/how-to-integrate-custom-security-scanners-into-gitlab/",[],"How to integrate custom security scanners into GitLab",[600,615,616],{},[32,617,620],{"href":618,"rel":619},"https://about.gitlab.com/security/",[],"GitLab Trust Center",[622,623,624],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}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);}",{"title":73,"searchDepth":91,"depth":91,"links":626},[627,628,629,632,635,636],{"id":21,"depth":91,"text":22},{"id":40,"depth":91,"text":41},{"id":50,"depth":91,"text":51,"children":630},[631],{"id":354,"depth":101,"text":355},{"id":387,"depth":91,"text":388,"children":633},[634],{"id":403,"depth":101,"text":404},{"id":576,"depth":91,"text":577},{"id":594,"depth":91,"text":595},"security","2024-04-08","Learn how to bring Snyk scan results into the merge request widget by parsing JSON artifacts and leveraging the SARIF file format.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098768/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%282%29_1khno1AUtxuL6zzmEmjK7v_1750098768560.png",{},"/en-us/blog/integrate-external-security-scanners-into-your-devsecops-workflow",{"title":5,"description":639,"ogTitle":5,"ogDescription":639,"noIndex":642,"ogImage":643,"ogUrl":647,"ogSiteName":648,"ogType":649,"canonicalUrls":647},"https://about.gitlab.com/blog/integrate-external-security-scanners-into-your-devsecops-workflow","https://about.gitlab.com","article","integrate-external-security-scanners-into-your-devsecops-workflow","en-us/blog/integrate-external-security-scanners-into-your-devsecops-workflow",[637,653,654],"tutorial","testing","BlogPost","Zr1Tbf-YVcfRxlfz-NkYJzo0-H8IZB9gbcZDexRcqVA",{"logo":658,"freeTrial":663,"sales":668,"login":673,"items":678,"search":1005,"minimal":1036,"duo":1055,"switchNav":1064,"pricingDeployment":1075},{"config":659},{"href":660,"dataGaName":661,"dataGaLocation":662},"/","gitlab logo","header",{"text":664,"config":665},"Get free trial",{"href":666,"dataGaName":667,"dataGaLocation":662},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":669,"config":670},"Request a demo",{"href":671,"dataGaName":672,"dataGaLocation":662},"/sales/?contact-topic=request-demo","sales",{"text":674,"config":675},"Sign in",{"href":676,"dataGaName":677,"dataGaLocation":662},"https://gitlab.com/users/sign_in/","sign in",[679,708,808,813,927,983],{"text":680,"config":681,"menu":683},"Platform",{"dataNavLevelOne":682},"platform",{"type":684,"columns":685},"cards",[686,692,700],{"title":680,"description":687,"link":688},"The intelligent orchestration platform for DevSecOps",{"text":689,"config":690},"Explore our Platform",{"href":691,"dataGaName":682,"dataGaLocation":662},"/platform/",{"title":693,"description":694,"link":695},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":696,"config":697},"Meet GitLab Duo",{"href":698,"dataGaName":699,"dataGaLocation":662},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":701,"description":702,"link":703},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":704,"config":705},"Learn more",{"href":706,"dataGaName":707,"dataGaLocation":662},"/why-gitlab/","why gitlab",{"text":709,"left":104,"config":710,"menu":712},"Product",{"dataNavLevelOne":711},"solutions",{"type":713,"link":714,"columns":718,"feature":787},"lists",{"text":715,"config":716},"View all Solutions",{"href":717,"dataGaName":711,"dataGaLocation":662},"/solutions/",[719,743,766],{"title":720,"description":721,"link":722,"items":727},"Automation","CI/CD and automation to accelerate deployment",{"config":723},{"icon":724,"href":725,"dataGaName":726,"dataGaLocation":662},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[728,732,735,739],{"text":729,"config":730},"CI/CD",{"href":731,"dataGaLocation":662,"dataGaName":729},"/solutions/continuous-integration/",{"text":693,"config":733},{"href":698,"dataGaLocation":662,"dataGaName":734},"gitlab duo agent platform - product menu",{"text":736,"config":737},"Source Code Management",{"href":738,"dataGaLocation":662,"dataGaName":736},"/solutions/source-code-management/",{"text":740,"config":741},"Automated Software Delivery",{"href":725,"dataGaLocation":662,"dataGaName":742},"Automated software delivery",{"title":744,"description":745,"link":746,"items":751},"Security","Deliver code faster without compromising security",{"config":747},{"href":748,"dataGaName":749,"dataGaLocation":662,"icon":750},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[752,756,761],{"text":753,"config":754},"Application Security Testing",{"href":748,"dataGaName":755,"dataGaLocation":662},"Application security testing",{"text":757,"config":758},"Software Supply Chain Security",{"href":759,"dataGaLocation":662,"dataGaName":760},"/solutions/supply-chain/","Software supply chain security",{"text":762,"config":763},"Software Compliance",{"href":764,"dataGaName":765,"dataGaLocation":662},"/solutions/software-compliance/","software compliance",{"title":767,"link":768,"items":773},"Measurement",{"config":769},{"icon":770,"href":771,"dataGaName":772,"dataGaLocation":662},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[774,778,782],{"text":775,"config":776},"Visibility & Measurement",{"href":771,"dataGaLocation":662,"dataGaName":777},"Visibility and Measurement",{"text":779,"config":780},"Value Stream Management",{"href":781,"dataGaLocation":662,"dataGaName":779},"/solutions/value-stream-management/",{"text":783,"config":784},"Analytics & Insights",{"href":785,"dataGaLocation":662,"dataGaName":786},"/solutions/analytics-and-insights/","Analytics and insights",{"title":788,"type":713,"items":789},"GitLab for",[790,796,802],{"text":791,"config":792},"Enterprise",{"icon":793,"href":794,"dataGaLocation":662,"dataGaName":795},"Building","/enterprise/","enterprise",{"text":797,"config":798},"Small Business",{"icon":799,"href":800,"dataGaLocation":662,"dataGaName":801},"Work","/small-business/","small business",{"text":803,"config":804},"Public Sector",{"icon":805,"href":806,"dataGaLocation":662,"dataGaName":807},"Organization","/solutions/public-sector/","public sector",{"text":809,"config":810},"Pricing",{"href":811,"dataGaName":812,"dataGaLocation":662,"dataNavLevelOne":812},"/pricing/","pricing",{"text":814,"config":815,"menu":817},"Resources",{"dataNavLevelOne":816},"resources",{"type":713,"link":818,"columns":822,"feature":916},{"text":819,"config":820},"View all resources",{"href":821,"dataGaName":816,"dataGaLocation":662},"/resources/",[823,856,883],{"title":824,"items":825},"Getting started",[826,831,836,841,846,851],{"text":827,"config":828},"Install",{"href":829,"dataGaName":830,"dataGaLocation":662},"/install/","install",{"text":832,"config":833},"Quick start guides",{"href":834,"dataGaName":835,"dataGaLocation":662},"/get-started/","quick setup checklists",{"text":837,"config":838},"Learn",{"href":839,"dataGaLocation":662,"dataGaName":840},"https://university.gitlab.com/","learn",{"text":842,"config":843},"Product documentation",{"href":844,"dataGaName":845,"dataGaLocation":662},"https://docs.gitlab.com/","product documentation",{"text":847,"config":848},"Best practice videos",{"href":849,"dataGaName":850,"dataGaLocation":662},"/getting-started-videos/","best practice videos",{"text":852,"config":853},"Integrations",{"href":854,"dataGaName":855,"dataGaLocation":662},"/integrations/","integrations",{"title":857,"items":858},"Discover",[859,864,869,874,878],{"text":860,"config":861},"Customer success stories",{"href":862,"dataGaName":863,"dataGaLocation":662},"/customers/","customer success stories",{"text":865,"config":866},"Blog",{"href":867,"dataGaName":868,"dataGaLocation":662},"/blog/","blog",{"text":870,"config":871},"Demo Hub",{"href":872,"dataGaName":873,"dataGaLocation":662},"/demo-hub/","demo hub",{"text":875,"config":876},"The Source",{"href":877,"dataGaName":868,"dataGaLocation":662},"/the-source/",{"text":879,"config":880},"Remote",{"href":881,"dataGaName":882,"dataGaLocation":662},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":884,"items":885},"Connect",[886,891,896,901,906,911],{"text":887,"config":888},"GitLab Services",{"href":889,"dataGaName":890,"dataGaLocation":662},"/services/","services",{"text":892,"config":893},"Contribute",{"href":894,"dataGaName":895,"dataGaLocation":662},"https://contributors.gitlab.com","contribute",{"text":897,"config":898},"Community",{"href":899,"dataGaName":900,"dataGaLocation":662},"/community/","community",{"text":902,"config":903},"Forum",{"href":904,"dataGaName":905,"dataGaLocation":662},"https://forum.gitlab.com/","forum",{"text":907,"config":908},"Events",{"href":909,"dataGaName":910,"dataGaLocation":662},"/events/","events",{"text":912,"config":913},"Partners",{"href":914,"dataGaName":915,"dataGaLocation":662},"/partners/","partners",{"config":917,"title":920,"text":921,"link":922},{"background":918,"textColor":919},"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":923,"config":924},"Read the latest",{"href":925,"dataGaName":926,"dataGaLocation":662},"/whats-new/","whats new",{"text":928,"config":929,"menu":931},"Company",{"dataNavLevelOne":930},"company",{"type":713,"columns":932},[933],{"items":934},[935,940,946,948,953,958,963,968,973,978],{"text":936,"config":937},"About",{"href":938,"dataGaName":939,"dataGaLocation":662},"/company/","about",{"text":941,"config":942,"footerGa":945},"Jobs",{"href":943,"dataGaName":944,"dataGaLocation":662},"/jobs/","jobs",{"dataGaName":944},{"text":907,"config":947},{"href":909,"dataGaName":910,"dataGaLocation":662},{"text":949,"config":950},"Leadership",{"href":951,"dataGaName":952,"dataGaLocation":662},"/company/team/e-group/","leadership",{"text":954,"config":955},"Handbook",{"href":956,"dataGaName":957,"dataGaLocation":662},"https://handbook.gitlab.com/","handbook",{"text":959,"config":960},"Investor relations",{"href":961,"dataGaName":962,"dataGaLocation":662},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":964,"config":965},"Trust Center",{"href":966,"dataGaName":967,"dataGaLocation":662},"/security/","trust center",{"text":969,"config":970},"AI Transparency Center",{"href":971,"dataGaName":972,"dataGaLocation":662},"/ai-transparency-center/","ai transparency center",{"text":974,"config":975},"Newsletter",{"href":976,"dataGaName":977,"dataGaLocation":662},"/company/contact/#contact-forms","newsletter",{"text":979,"config":980},"Press",{"href":981,"dataGaName":982,"dataGaLocation":662},"/press/","press",{"text":984,"config":985,"menu":986},"Contact us",{"dataNavLevelOne":930},{"type":713,"columns":987},[988],{"items":989},[990,995,1000],{"text":991,"config":992},"Talk to sales",{"href":993,"dataGaName":994,"dataGaLocation":662},"/sales/","talk to sales",{"text":996,"config":997},"Support portal",{"href":998,"dataGaName":999,"dataGaLocation":662},"https://support.gitlab.com/hc/en-us","support portal",{"text":1001,"config":1002},"Customer portal",{"href":1003,"dataGaName":1004,"dataGaLocation":662},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":1006,"login":1007,"suggestions":1014},"Close",{"text":1008,"link":1009},"To search repositories and projects, login to",{"text":1010,"config":1011},"gitlab.com",{"href":676,"dataGaName":1012,"dataGaLocation":1013},"search login","search",{"text":1015,"default":1016},"Suggestions",[1017,1019,1023,1025,1029,1033],{"text":693,"config":1018},{"href":698,"dataGaName":693,"dataGaLocation":1013},{"text":1020,"config":1021},"Code Suggestions (AI)",{"href":1022,"dataGaName":1020,"dataGaLocation":1013},"/solutions/code-suggestions/",{"text":729,"config":1024},{"href":731,"dataGaName":729,"dataGaLocation":1013},{"text":1026,"config":1027},"GitLab on AWS",{"href":1028,"dataGaName":1026,"dataGaLocation":1013},"/partners/technology-partners/aws/",{"text":1030,"config":1031},"GitLab on Google Cloud",{"href":1032,"dataGaName":1030,"dataGaLocation":1013},"/partners/technology-partners/google-cloud-platform/",{"text":1034,"config":1035},"Why GitLab?",{"href":706,"dataGaName":1034,"dataGaLocation":1013},{"freeTrial":1037,"mobileIcon":1042,"desktopIcon":1047,"secondaryButton":1050},{"text":1038,"config":1039},"Start free trial",{"href":1040,"dataGaName":667,"dataGaLocation":1041},"https://gitlab.com/-/trials/new/","nav",{"altText":1043,"config":1044},"Gitlab Icon",{"src":1045,"dataGaName":1046,"dataGaLocation":1041},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":1043,"config":1048},{"src":1049,"dataGaName":1046,"dataGaLocation":1041},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":1051,"config":1052},"Get Started",{"href":1053,"dataGaName":1054,"dataGaLocation":1041},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":1056,"mobileIcon":1060,"desktopIcon":1062},{"text":1057,"config":1058},"Learn more about GitLab Duo",{"href":698,"dataGaName":1059,"dataGaLocation":1041},"gitlab duo",{"altText":1043,"config":1061},{"src":1045,"dataGaName":1046,"dataGaLocation":1041},{"altText":1043,"config":1063},{"src":1049,"dataGaName":1046,"dataGaLocation":1041},{"button":1065,"mobileIcon":1070,"desktopIcon":1072},{"text":1066,"config":1067},"/switch",{"href":1068,"dataGaName":1069,"dataGaLocation":1041},"#contact","switch",{"altText":1043,"config":1071},{"src":1045,"dataGaName":1046,"dataGaLocation":1041},{"altText":1043,"config":1073},{"src":1074,"dataGaName":1046,"dataGaLocation":1041},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":1076,"mobileIcon":1081,"desktopIcon":1083},{"text":1077,"config":1078},"Back to pricing",{"href":811,"dataGaName":1079,"dataGaLocation":1041,"icon":1080},"back to pricing","GoBack",{"altText":1043,"config":1082},{"src":1045,"dataGaName":1046,"dataGaLocation":1041},{"altText":1043,"config":1084},{"src":1049,"dataGaName":1046,"dataGaLocation":1041},{"title":1086,"titleMobile":1087,"button":1088,"config":1093},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":704,"config":1089},{"href":1090,"dataGaName":1091,"dataGaLocation":1092},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":1094,"disabled":642},"release",{"data":1096},{"text":1097,"source":1098,"edit":1104,"contribute":1109,"config":1114,"items":1119,"minimal":1329},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1099,"config":1100},"View page source",{"href":1101,"dataGaName":1102,"dataGaLocation":1103},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1105,"config":1106},"Edit this page",{"href":1107,"dataGaName":1108,"dataGaLocation":1103},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1110,"config":1111},"Please contribute",{"href":1112,"dataGaName":1113,"dataGaLocation":1103},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1115,"facebook":1116,"youtube":1117,"linkedin":1118},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1120,1167,1221,1265,1297],{"title":809,"links":1121,"subMenu":1136},[1122,1126,1131],{"text":1123,"config":1124},"View plans",{"href":811,"dataGaName":1125,"dataGaLocation":1103},"view plans",{"text":1127,"config":1128},"Why Premium?",{"href":1129,"dataGaName":1130,"dataGaLocation":1103},"/pricing/premium/","why premium",{"text":1132,"config":1133},"Why Ultimate?",{"href":1134,"dataGaName":1135,"dataGaLocation":1103},"/pricing/ultimate/","why ultimate",[1137],{"title":1138,"links":1139},"Contact Us",[1140,1143,1145,1147,1152,1157,1162],{"text":1141,"config":1142},"Contact sales",{"href":993,"dataGaName":672,"dataGaLocation":1103},{"text":996,"config":1144},{"href":998,"dataGaName":999,"dataGaLocation":1103},{"text":1001,"config":1146},{"href":1003,"dataGaName":1004,"dataGaLocation":1103},{"text":1148,"config":1149},"Status",{"href":1150,"dataGaName":1151,"dataGaLocation":1103},"https://status.gitlab.com/","status",{"text":1153,"config":1154},"Terms of use",{"href":1155,"dataGaName":1156,"dataGaLocation":1103},"/terms/","terms of use",{"text":1158,"config":1159},"Privacy statement",{"href":1160,"dataGaName":1161,"dataGaLocation":1103},"/privacy/","privacy statement",{"text":1163,"config":1164},"Cookie preferences",{"dataGaName":1165,"dataGaLocation":1103,"id":1166,"isOneTrustButton":104},"cookie preferences","ot-sdk-btn",{"title":709,"links":1168,"subMenu":1177},[1169,1173],{"text":1170,"config":1171},"DevSecOps platform",{"href":691,"dataGaName":1172,"dataGaLocation":1103},"devsecops platform",{"text":1174,"config":1175},"AI-Assisted Development",{"href":698,"dataGaName":1176,"dataGaLocation":1103},"ai-assisted development",[1178],{"title":1179,"links":1180},"Topics",[1181,1186,1191,1196,1201,1206,1211,1216],{"text":1182,"config":1183},"CICD",{"href":1184,"dataGaName":1185,"dataGaLocation":1103},"/topics/ci-cd/","cicd",{"text":1187,"config":1188},"GitOps",{"href":1189,"dataGaName":1190,"dataGaLocation":1103},"/topics/gitops/","gitops",{"text":1192,"config":1193},"DevOps",{"href":1194,"dataGaName":1195,"dataGaLocation":1103},"/topics/devops/","devops",{"text":1197,"config":1198},"Version Control",{"href":1199,"dataGaName":1200,"dataGaLocation":1103},"/topics/version-control/","version control",{"text":1202,"config":1203},"DevSecOps",{"href":1204,"dataGaName":1205,"dataGaLocation":1103},"/topics/devsecops/","devsecops",{"text":1207,"config":1208},"Cloud Native",{"href":1209,"dataGaName":1210,"dataGaLocation":1103},"/topics/cloud-native/","cloud native",{"text":1212,"config":1213},"AI for Coding",{"href":1214,"dataGaName":1215,"dataGaLocation":1103},"/topics/devops/ai-for-coding/","ai for coding",{"text":1217,"config":1218},"Agentic AI",{"href":1219,"dataGaName":1220,"dataGaLocation":1103},"/topics/agentic-ai/","agentic ai",{"title":1222,"links":1223},"Solutions",[1224,1226,1228,1233,1237,1240,1244,1247,1249,1252,1255,1260],{"text":753,"config":1225},{"href":748,"dataGaName":753,"dataGaLocation":1103},{"text":742,"config":1227},{"href":725,"dataGaName":726,"dataGaLocation":1103},{"text":1229,"config":1230},"Agile development",{"href":1231,"dataGaName":1232,"dataGaLocation":1103},"/solutions/agile-delivery/","agile delivery",{"text":1234,"config":1235},"SCM",{"href":738,"dataGaName":1236,"dataGaLocation":1103},"source code management",{"text":1182,"config":1238},{"href":731,"dataGaName":1239,"dataGaLocation":1103},"continuous integration & delivery",{"text":1241,"config":1242},"Value stream management",{"href":781,"dataGaName":1243,"dataGaLocation":1103},"value stream management",{"text":1187,"config":1245},{"href":1246,"dataGaName":1190,"dataGaLocation":1103},"/solutions/gitops/",{"text":791,"config":1248},{"href":794,"dataGaName":795,"dataGaLocation":1103},{"text":1250,"config":1251},"Small business",{"href":800,"dataGaName":801,"dataGaLocation":1103},{"text":1253,"config":1254},"Public sector",{"href":806,"dataGaName":807,"dataGaLocation":1103},{"text":1256,"config":1257},"Education",{"href":1258,"dataGaName":1259,"dataGaLocation":1103},"/solutions/education/","education",{"text":1261,"config":1262},"Financial services",{"href":1263,"dataGaName":1264,"dataGaLocation":1103},"/solutions/finance/","financial services",{"title":814,"links":1266},[1267,1269,1271,1273,1276,1278,1281,1283,1285,1287,1289,1291,1293,1295],{"text":827,"config":1268},{"href":829,"dataGaName":830,"dataGaLocation":1103},{"text":832,"config":1270},{"href":834,"dataGaName":835,"dataGaLocation":1103},{"text":837,"config":1272},{"href":839,"dataGaName":840,"dataGaLocation":1103},{"text":842,"config":1274},{"href":844,"dataGaName":1275,"dataGaLocation":1103},"docs",{"text":865,"config":1277},{"href":867,"dataGaName":868,"dataGaLocation":1103},{"text":1279,"config":1280},"What's new",{"href":925,"dataGaName":926,"dataGaLocation":1103},{"text":860,"config":1282},{"href":862,"dataGaName":863,"dataGaLocation":1103},{"text":879,"config":1284},{"href":881,"dataGaName":882,"dataGaLocation":1103},{"text":887,"config":1286},{"href":889,"dataGaName":890,"dataGaLocation":1103},{"text":892,"config":1288},{"href":894,"dataGaName":895,"dataGaLocation":1103},{"text":897,"config":1290},{"href":899,"dataGaName":900,"dataGaLocation":1103},{"text":902,"config":1292},{"href":904,"dataGaName":905,"dataGaLocation":1103},{"text":907,"config":1294},{"href":909,"dataGaName":910,"dataGaLocation":1103},{"text":912,"config":1296},{"href":914,"dataGaName":915,"dataGaLocation":1103},{"title":928,"links":1298},[1299,1301,1303,1305,1307,1309,1313,1318,1320,1322,1324],{"text":936,"config":1300},{"href":938,"dataGaName":930,"dataGaLocation":1103},{"text":941,"config":1302},{"href":943,"dataGaName":944,"dataGaLocation":1103},{"text":949,"config":1304},{"href":951,"dataGaName":952,"dataGaLocation":1103},{"text":954,"config":1306},{"href":956,"dataGaName":957,"dataGaLocation":1103},{"text":959,"config":1308},{"href":961,"dataGaName":962,"dataGaLocation":1103},{"text":1310,"config":1311},"Sustainability",{"href":1312,"dataGaName":1310,"dataGaLocation":1103},"/sustainability/",{"text":1314,"config":1315},"Diversity, inclusion and belonging (DIB)",{"href":1316,"dataGaName":1317,"dataGaLocation":1103},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":964,"config":1319},{"href":966,"dataGaName":967,"dataGaLocation":1103},{"text":974,"config":1321},{"href":976,"dataGaName":977,"dataGaLocation":1103},{"text":979,"config":1323},{"href":981,"dataGaName":982,"dataGaLocation":1103},{"text":1325,"config":1326},"Modern Slavery Transparency Statement",{"href":1327,"dataGaName":1328,"dataGaLocation":1103},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1330},[1331,1334,1337],{"text":1332,"config":1333},"Terms",{"href":1155,"dataGaName":1156,"dataGaLocation":1103},{"text":1335,"config":1336},"Cookies",{"dataGaName":1165,"dataGaLocation":1103,"id":1166,"isOneTrustButton":104},{"text":1338,"config":1339},"Privacy",{"href":1160,"dataGaName":1161,"dataGaLocation":1103},[1341],{"id":1342,"title":7,"body":641,"config":1343,"content":1345,"description":641,"extension":1349,"meta":1350,"navigation":104,"path":1351,"seo":1352,"stem":1353,"__hash__":1354},"blogAuthors/en-us/blog/authors/sam-morris.yml",{"template":1344},"BlogAuthor",{"name":7,"config":1346},{"headshot":1347,"ctfId":1348},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749660148/Blog/Author%20Headshots/sam_morris.png","6JTrhUIqSCU30Y9KZOaan8","yml",{},"/en-us/blog/authors/sam-morris",{},"en-us/blog/authors/sam-morris","DfL241G6FQ5wNU6XYJLCEQLvnWBnyKnAi3wCPxOqBzE",[1356,1364,1372],{"title":1357,"description":1358,"heroImage":1359,"category":637,"date":1360,"authors":1361,"slug":1363,"externalUrl":641},"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",[1362],"Julian Thome","improved-scope-offset-fingerprinting",{"title":1365,"description":1366,"heroImage":1359,"category":637,"date":1367,"authors":1368,"slug":1371,"externalUrl":641},"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",[1369,1370],"Erick Bajao","Joe Randazzo","gitlab-secrets-manager-add-eso-terraform-api-support",{"title":1373,"description":1374,"heroImage":1375,"category":637,"date":1376,"authors":1377,"slug":1379,"externalUrl":641},"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",[1378],"Alisa Ho","claude-security-and-gitlab",{"promotions":1381},[1382,1396,1408,1419],{"id":1383,"categories":1384,"header":1386,"text":1387,"button":1388,"image":1393},"ai-modernization",[1385],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1389,"config":1390},"Get your AI maturity score",{"href":1391,"dataGaName":1392,"dataGaLocation":868},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1394},{"src":1395},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1397,"categories":1398,"header":1400,"text":1387,"button":1401,"image":1405},"devops-modernization",[1399,1205],"product","Are you just managing tools or shipping innovation?",{"text":1402,"config":1403},"Get your DevOps maturity score",{"href":1404,"dataGaName":1392,"dataGaLocation":868},"/assessments/devops-modernization-assessment/",{"config":1406},{"src":1407},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1409,"categories":1410,"header":1411,"text":1387,"button":1412,"image":1416},"security-modernization",[637],"Are you trading speed for security?",{"text":1413,"config":1414},"Get your security maturity score",{"href":1415,"dataGaName":1392,"dataGaLocation":868},"/assessments/security-modernization-assessment/",{"config":1417},{"src":1418},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1420,"paths":1421,"header":1424,"text":1425,"button":1426,"image":1431},"github-azure-migration",[1422,1423],"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":1427,"config":1428},"See how GitLab compares to GitHub",{"href":1429,"dataGaName":1430,"dataGaLocation":868},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1432},{"src":1407},{"header":1434,"blurb":1435,"button":1436,"secondaryButton":1441},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1437,"config":1438},"Get your free trial",{"href":1439,"dataGaName":667,"dataGaLocation":1440},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1141,"config":1442},{"href":993,"dataGaName":672,"dataGaLocation":1440},1786803762969]