[{"data":1,"prerenderedAt":1089},["ShallowReactive",2],{"/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd":3,"navigation-en-us":305,"banner-en-us":732,"footer-en-us":742,"blog-post-authors-en-us-Mitra Jozenazemian":985,"blog-related-posts-en-us-automating-cybersecurity-threat-detections-with-gitlab-ci-cd":1000,"blog-promotions-en-us":1026,"next-steps-en-us":1079},{"id":4,"title":5,"authors":6,"body":8,"category":283,"date":284,"description":285,"extension":286,"externalUrl":287,"faq":287,"featured":288,"heroImage":289,"meta":290,"navigation":184,"path":291,"seo":292,"slug":296,"stem":297,"tags":298,"template":303,"updatedDate":287,"__hash__":304},"blogPosts/en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd.md","Automating cybersecurity threat detections with GitLab CI/CD",[7],"Mitra Jozenazemian",{"type":9,"value":10,"toc":275},"minimark",[11,25,28,33,48,52,61,66,72,75,80,83,88,91,107,112,121,126,129,137,149,157,167,170,235,239,242,259,263,271],[12,13,14],"p",{},[15,16,17,18,24],"em",{},"This blog post is the second post in a series about ",[19,20,23],"a",{"href":21,"rel":22},"https://about.gitlab.com/blog/unveiling-the-guard-framework-to-automate-security-detections-at-gitlab/",[],"GitLab Universal\nAutomated Response and Detection (GUARD)",".",[12,26,27],{},"Writing and deploying security threat detections in an organization’s security information event management platform (SIEM) is a critical component of a successful cybersecurity program. Moving from manual detection engineering to a fully automated process by implementing\nDetections as Code (DaC) ensures detection consistency, quality, auditing, and automated testing. At GitLab, we’ve embedded DaC capabilities into\nGUARD, our fully automated detection and response framework.",[29,30,32],"h2",{"id":31},"the-problem-source-control-and-automated-tests","The problem: Source control and automated tests",[12,34,35,36,41,42,47],{},"The ",[19,37,40],{"href":38,"rel":39},"https://handbook.gitlab.com/handbook/security/security-operations/signals-engineering/",[],"Signals\nEngineering","\nand ",[19,43,46],{"href":44,"rel":45},"https://handbook.gitlab.com/handbook/security/security-operations/sirt/",[],"SIRT","\nteam at GitLab share the responsibility to create, update, and decommission threat detections in our SIEM. Maintaining a single source of truth for detections is critical to ensure detection consistency and quality standards are met. Our teams made the conscious decision to abstract the detection creation process from our SIEM, improving our issue tracking, consistency, roll-back process, and metrics. Additionally, conducting pre-commit detection tests outside of our SIEM ensured that newly created detections didn’t introduce overly false positive heavy alerts, which would require tuning or disablement while the alert was fixed.",[29,49,51],{"id":50},"the-solution-leverage-gitlab-cicd-for-detection-testing-and-validation","The Solution: Leverage GitLab CI/CD for detection testing and validation",[12,53,54,55,60],{},"To address these challenges, we developed an efficient workflow using GitLab ",[19,56,59],{"href":57,"rel":58},"https://about.gitlab.com/topics/ci-cd/",[],"CI/CD",", resulting in a streamlined and secure SIEM detection deployment process.",[62,63,65],"h3",{"id":64},"key-components-of-the-guard-dac-pipeline","Key components of the GUARD DaC pipeline",[12,67,68],{},[69,70,71],"strong",{},"1. Detections stored in JSON format in a GitLab project",[12,73,74],{},"GitLab uses the JSON format for our threat detections. The template includes essential information such as SIEM query logic, detection title, and description along with runbook page link, MITRE tactic and technique related to the detection, and other necessary details.",[12,76,77],{},[69,78,79],{},"2. Initiating merge requests",[12,81,82],{},"When a GitLab team member intends to create a new threat detection, update an existing one, or delete a current detection, they initiate the process by submitting a merge request (MR) in the DaC project containing the detection\nJSON template. Creating the MR automatically triggers a CI/CD pipeline.",[12,84,85],{},[69,86,87],{},"3. Automated validation with CI/CD jobs",[12,89,90],{},"Each MR contains a number of automated checks via GitLab CI/CD:",[92,93,94,98,101,104],"ul",{},[95,96,97],"li",{},"Query format validation queries SIEM API to ensure detection query is\nvalid",[95,99,100],{},"JSON Detection fields validation validates all required fields are\npresent, and are in the correct format",[95,102,103],{},"New detections and detection modification trigger a number of SIEM API\ncalls to ensure the detection does not have any errors and that no issues will be introduced into our production detection rules",[95,105,106],{},"Detection deletion MRs trigger the pipeline to issue a SIEM API query to\nensure the detection to be deleted is still active and can be deleted",[12,108,109],{},[69,110,111],{},"4. Peer review and approval",[12,113,114,115,120],{},"When a detection MR job completes successfully, a peer review is required to review and confirm the MR meets required quality and content standards before the detection MR can be merged. ",[19,116,119],{"href":117,"rel":118},"https://docs.gitlab.com/user/project/merge_requests/approvals/rules/",[],"Merge request approval rules","\nare used to trigger the peer review process.",[12,122,123],{},[69,124,125],{},"5. Merge and final deployment",[12,127,128],{},"After the MR is approved, it is merged into the main branch. As part of the\nCI/CD pipeline, an automated job executes a SIEM API command in order to perform two tasks:",[92,130,131,134],{},[95,132,133],{},"Create the new detection or update/delete the existing detection if\nneeded.",[95,135,136],{},"Extract the MITRE ATT&CK tactic and technique information related to the\nalert from the JSON files and transmit these details to a lookup table within the SIEM. This lookup table plays an important role in mapping our alerts to MITRE tactics and techniques, helping us improve our threat analysis and identify gaps in our detection capabilities in alignment with the MITRE framework.",[12,138,139,142,143,148],{},[69,140,141],{},"Note:"," The necessary credentials for these actions are securely stored in ",[19,144,147],{"href":145,"rel":146},"https://docs.gitlab.com/ci/variables/",[],"CI/CD variables"," to ensure the process remains confidential and secure.",[12,150,151,152,156],{},"Below is a template GitLab CI/CD ",[153,154,155],"code",{},"gitlab-ci.yml"," configuration file for a\nDaC pipeline:",[158,159,165],"pre",{"className":160,"code":162,"language":163,"meta":164},[161],"language-text","\n\n#\n---------------------------------------------------------------------------\n#\n\n# GitLab CI/CD Pipeline for SIEM Detection Management\n\n#\n---------------------------------------------------------------------------\n#\n\n\nimage: python:3.12\n\n\n#\n---------------------------------------------------------------------------\n#\n\n# Global Configuration\n\n#\n---------------------------------------------------------------------------\n#\n\n\nbefore_script:\n  - apt-get update && apt-get install -y jq\n  - pip install --upgrade pip\n  - pip install -r requirements.txt\n\n#\n---------------------------------------------------------------------------\n#\n\n\nstages:\n  - fetch\n  - test\n  - process\n  - upload\n\n#\n---------------------------------------------------------------------------\n#\n\n# Fetch Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nfetch_changed_files:\n  stage: fetch\n  Script:\n    - echo \"Fetching changed files...\"\n    - git branch\n    - git fetch origin $CI_DEFAULT_BRANCH:$CI_DEFAULT_BRANCH --depth 2000\n    - |\n      if [[ \"$CI_COMMIT_BRANCH\" == \"$CI_DEFAULT_BRANCH\" ]]; then\n        git diff --name-status HEAD^1...HEAD > changed-files-temp.txt\n      else\n        git fetch origin $CI_COMMIT_BRANCH:$CI_COMMIT_BRANCH --depth 2000\n        git diff --name-status ${CI_DEFAULT_BRANCH}...${CI_COMMIT_SHA} > changed-files-temp.txt\n      fi\n    - grep -E '\\.json$' changed-files-temp.txt > changed-files.txt || true\n    - flake8 .\n    - pytest\n  artifacts:\n    paths:\n      - changed-files.txt\n    expose_as: 'changed_files'\n\n#\n---------------------------------------------------------------------------\n#\n\n# Test Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nflake8:\n  stage: test\n  script:\n    - echo \"Running Flake8 for linting...\"\n    - flake8 .\n\npytest:\n  stage: test\n  script:\n    - echo \"Running Pytest for unit tests...\"\n    - pytest\n  artifacts:\n    when: always\n    reports:\n      junit: report.xml\n\n#\n---------------------------------------------------------------------------\n#\n\n# Process Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nprocess_files:\n  stage: process\n  script:\n    - echo \"Processing changed files...\"\n    - git clone --depth 2000 --branch $CI_DEFAULT_BRANCH $CI_REPOSITORY_URL\n    - mkdir -p modified_rules delete_file new_file\n    - python3 move-files.py -x changed-files.txt\n    - python3 check-alerts-format.py\n  artifacts:\n    paths:\n      - modified_rules\n      - delete_file\n      - new_file\n#\n---------------------------------------------------------------------------\n#\n\n# Upload Stage\n\n#\n---------------------------------------------------------------------------\n#\n\n\nupdate_rules:\n  stage: upload\n  script:\n    - echo \"Uploading updated rules and lookup tables...\"\n    - git fetch origin $CI_DEFAULT_BRANCH:$CI_DEFAULT_BRANCH --depth 2000\n    - git clone --depth 2000 --branch $CI_DEFAULT_BRANCH $CI_REPOSITORY_URL \n    - python3 update-rules.py\n    - python3 update-exceptions.py\n    - python3 create_ttps_layers.py\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\" && $CI_PIPELINE_SOURCE != \"schedule\"\n      changes:\n        - detections/**/*\n        - exceptions/**/*\n","text","",[153,166,162],{"__ignoreMap":164},[12,168,169],{},"The diagram below illustrates the workflow of the CI/CD process described above.",[158,171,175],{"className":172,"code":173,"language":174,"meta":164,"style":164},"language-mermaid shiki shiki-themes github-light","\ngraph TD;\n    fetch[Fetch Stage: Identify Changed Files] --> test[Test Stage: Run Linting and Tests];\n    test --> process[Process Stage: Categorize Files];\n    process --> upload[Upload Stage: Update Rules and Lookup Tables];\n    fetch --> fetch_details[Details: Filter JSON files, Output 'changed-files.txt'];\n    test --> test_details[Details: Run Flake8 for linting, Pytest for testing];\n    process --> process_details[Details: Categorize into 'modified', 'new', 'deleted', Prepare for upload];\n    upload --> upload_details[Details: Update repo, Update detections in SIEM and SIEM lookup table];\n","mermaid",[153,176,177,186,193,199,205,211,217,223,229],{"__ignoreMap":164},[178,179,182],"span",{"class":180,"line":181},"line",1,[178,183,185],{"emptyLinePlaceholder":184},true,"\n",[178,187,189],{"class":180,"line":188},2,[178,190,192],{"class":191},"sgsFI","graph TD;\n",[178,194,196],{"class":180,"line":195},3,[178,197,198],{"class":191},"    fetch[Fetch Stage: Identify Changed Files] --> test[Test Stage: Run Linting and Tests];\n",[178,200,202],{"class":180,"line":201},4,[178,203,204],{"class":191},"    test --> process[Process Stage: Categorize Files];\n",[178,206,208],{"class":180,"line":207},5,[178,209,210],{"class":191},"    process --> upload[Upload Stage: Update Rules and Lookup Tables];\n",[178,212,214],{"class":180,"line":213},6,[178,215,216],{"class":191},"    fetch --> fetch_details[Details: Filter JSON files, Output 'changed-files.txt'];\n",[178,218,220],{"class":180,"line":219},7,[178,221,222],{"class":191},"    test --> test_details[Details: Run Flake8 for linting, Pytest for testing];\n",[178,224,226],{"class":180,"line":225},8,[178,227,228],{"class":191},"    process --> process_details[Details: Categorize into 'modified', 'new', 'deleted', Prepare for upload];\n",[178,230,232],{"class":180,"line":231},9,[178,233,234],{"class":191},"    upload --> upload_details[Details: Update repo, Update detections in SIEM and SIEM lookup table];\n",[29,236,238],{"id":237},"benefits-and-outcomes","Benefits and outcomes",[12,240,241],{},"Automating our detections lifecycle through a DaC CI/CD-powered workflow introduces numerous benefits to our threat detection deployment process:",[92,243,244,247,250,253,256],{},[95,245,246],{},"Automation: Automating the creation and validation of SIEM detections\nreduces manual errors and saves time.",[95,248,249],{},"Enhanced security: The CI-driven workflow enforces a \"least privilege\"\npolicy, ensuring consistency, peer reviews, and quality standards for creating, updating, or deleting threat detections.",[95,251,252],{},"Efficiency: The standardized JSON detection format and automated creation\nexpedite the deployment process.",[95,254,255],{},"Collaboration: The MR and review process fosters collaboration and\nknowledge sharing among GitLab team members.",[95,257,258],{},"Version control: Treating threat detection as code abstracts the\ndetections from the SIEM platform they are ultimately stored in. This abstraction provides a historical record of changes, facilitates collaboration, and enables rollbacks to previous configurations if issues arise.",[29,260,262],{"id":261},"get-started-with-dac","Get started with DaC",[12,264,265,266,24],{},"Using GitLab CI/CD and a \"least privilege\" policy has made our SIEM detection and alert management easier and more secure. Automation has improved efficiency and reduced risks, providing a helpful example for others wanting to improve their security and compliance. You can try this tutorial by signing up for a ",[19,267,270],{"href":268,"rel":269},"https://about.gitlab.com/free-trial/",[],"free trial of GitLab\nUltimate",[272,273,274],"style",{},"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);}",{"title":164,"searchDepth":188,"depth":188,"links":276},[277,278,281,282],{"id":31,"depth":188,"text":32},{"id":50,"depth":188,"text":51,"children":279},[280],{"id":64,"depth":195,"text":65},{"id":237,"depth":188,"text":238},{"id":261,"depth":188,"text":262},"security-labs","2025-01-29","Discover how GUARD automates cybersecurity threat detections through the use\nof GitLab CI/CD and how it ensures high-quality detections.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663239/Blog/Hero%20Images/AdobeStock_1023776629.jpg",{},"/en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd",{"ogTitle":5,"ogImage":289,"ogDescription":285,"ogSiteName":293,"noIndex":288,"ogType":294,"ogUrl":295,"title":5,"canonicalUrls":295,"description":285},"https://about.gitlab.com","article","https://about.gitlab.com/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd","automating-cybersecurity-threat-detections-with-gitlab-ci-cd","en-us/blog/automating-cybersecurity-threat-detections-with-gitlab-ci-cd",[299,300,301,302,59],"security","tutorial","DevSecOps","DevSecOps platform","BlogPost","jSZK7NzOrRGJ-itT-uXS8MhKuH57lA9h9lTUU6QPm4o",{"logo":306,"freeTrial":311,"sales":316,"login":321,"items":326,"search":652,"minimal":683,"duo":702,"switchNav":711,"pricingDeployment":722},{"config":307},{"href":308,"dataGaName":309,"dataGaLocation":310},"/","gitlab logo","header",{"text":312,"config":313},"Get free trial",{"href":314,"dataGaName":315,"dataGaLocation":310},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":317,"config":318},"Request a demo",{"href":319,"dataGaName":320,"dataGaLocation":310},"/sales/?contact-topic=request-demo","sales",{"text":322,"config":323},"Sign in",{"href":324,"dataGaName":325,"dataGaLocation":310},"https://gitlab.com/users/sign_in/","sign in",[327,356,455,460,574,630],{"text":328,"config":329,"menu":331},"Platform",{"dataNavLevelOne":330},"platform",{"type":332,"columns":333},"cards",[334,340,348],{"title":328,"description":335,"link":336},"The intelligent orchestration platform for DevSecOps",{"text":337,"config":338},"Explore our Platform",{"href":339,"dataGaName":330,"dataGaLocation":310},"/platform/",{"title":341,"description":342,"link":343},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":344,"config":345},"Meet GitLab Duo",{"href":346,"dataGaName":347,"dataGaLocation":310},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":349,"description":350,"link":351},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":352,"config":353},"Learn more",{"href":354,"dataGaName":355,"dataGaLocation":310},"/why-gitlab/","why gitlab",{"text":357,"left":184,"config":358,"menu":360},"Product",{"dataNavLevelOne":359},"solutions",{"type":361,"link":362,"columns":366,"feature":434},"lists",{"text":363,"config":364},"View all Solutions",{"href":365,"dataGaName":359,"dataGaLocation":310},"/solutions/",[367,390,413],{"title":368,"description":369,"link":370,"items":375},"Automation","CI/CD and automation to accelerate deployment",{"config":371},{"icon":372,"href":373,"dataGaName":374,"dataGaLocation":310},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[376,379,382,386],{"text":59,"config":377},{"href":378,"dataGaLocation":310,"dataGaName":59},"/solutions/continuous-integration/",{"text":341,"config":380},{"href":346,"dataGaLocation":310,"dataGaName":381},"gitlab duo agent platform - product menu",{"text":383,"config":384},"Source Code Management",{"href":385,"dataGaLocation":310,"dataGaName":383},"/solutions/source-code-management/",{"text":387,"config":388},"Automated Software Delivery",{"href":373,"dataGaLocation":310,"dataGaName":389},"Automated software delivery",{"title":391,"description":392,"link":393,"items":398},"Security","Deliver code faster without compromising security",{"config":394},{"href":395,"dataGaName":396,"dataGaLocation":310,"icon":397},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[399,403,408],{"text":400,"config":401},"Application Security Testing",{"href":395,"dataGaName":402,"dataGaLocation":310},"Application security testing",{"text":404,"config":405},"Software Supply Chain Security",{"href":406,"dataGaLocation":310,"dataGaName":407},"/solutions/supply-chain/","Software supply chain security",{"text":409,"config":410},"Software Compliance",{"href":411,"dataGaName":412,"dataGaLocation":310},"/solutions/software-compliance/","software compliance",{"title":414,"link":415,"items":420},"Measurement",{"config":416},{"icon":417,"href":418,"dataGaName":419,"dataGaLocation":310},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[421,425,429],{"text":422,"config":423},"Visibility & Measurement",{"href":418,"dataGaLocation":310,"dataGaName":424},"Visibility and Measurement",{"text":426,"config":427},"Value Stream Management",{"href":428,"dataGaLocation":310,"dataGaName":426},"/solutions/value-stream-management/",{"text":430,"config":431},"Analytics & Insights",{"href":432,"dataGaLocation":310,"dataGaName":433},"/solutions/analytics-and-insights/","Analytics and insights",{"title":435,"type":361,"items":436},"GitLab for",[437,443,449],{"text":438,"config":439},"Enterprise",{"icon":440,"href":441,"dataGaLocation":310,"dataGaName":442},"Building","/enterprise/","enterprise",{"text":444,"config":445},"Small Business",{"icon":446,"href":447,"dataGaLocation":310,"dataGaName":448},"Work","/small-business/","small business",{"text":450,"config":451},"Public Sector",{"icon":452,"href":453,"dataGaLocation":310,"dataGaName":454},"Organization","/solutions/public-sector/","public sector",{"text":456,"config":457},"Pricing",{"href":458,"dataGaName":459,"dataGaLocation":310,"dataNavLevelOne":459},"/pricing/","pricing",{"text":461,"config":462,"menu":464},"Resources",{"dataNavLevelOne":463},"resources",{"type":361,"link":465,"columns":469,"feature":563},{"text":466,"config":467},"View all resources",{"href":468,"dataGaName":463,"dataGaLocation":310},"/resources/",[470,503,530],{"title":471,"items":472},"Getting started",[473,478,483,488,493,498],{"text":474,"config":475},"Install",{"href":476,"dataGaName":477,"dataGaLocation":310},"/install/","install",{"text":479,"config":480},"Quick start guides",{"href":481,"dataGaName":482,"dataGaLocation":310},"/get-started/","quick setup checklists",{"text":484,"config":485},"Learn",{"href":486,"dataGaLocation":310,"dataGaName":487},"https://university.gitlab.com/","learn",{"text":489,"config":490},"Product documentation",{"href":491,"dataGaName":492,"dataGaLocation":310},"https://docs.gitlab.com/","product documentation",{"text":494,"config":495},"Best practice videos",{"href":496,"dataGaName":497,"dataGaLocation":310},"/getting-started-videos/","best practice videos",{"text":499,"config":500},"Integrations",{"href":501,"dataGaName":502,"dataGaLocation":310},"/integrations/","integrations",{"title":504,"items":505},"Discover",[506,511,516,521,525],{"text":507,"config":508},"Customer success stories",{"href":509,"dataGaName":510,"dataGaLocation":310},"/customers/","customer success stories",{"text":512,"config":513},"Blog",{"href":514,"dataGaName":515,"dataGaLocation":310},"/blog/","blog",{"text":517,"config":518},"Demo Hub",{"href":519,"dataGaName":520,"dataGaLocation":310},"/demo-hub/","demo hub",{"text":522,"config":523},"The Source",{"href":524,"dataGaName":515,"dataGaLocation":310},"/the-source/",{"text":526,"config":527},"Remote",{"href":528,"dataGaName":529,"dataGaLocation":310},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":531,"items":532},"Connect",[533,538,543,548,553,558],{"text":534,"config":535},"GitLab Services",{"href":536,"dataGaName":537,"dataGaLocation":310},"/services/","services",{"text":539,"config":540},"Contribute",{"href":541,"dataGaName":542,"dataGaLocation":310},"https://contributors.gitlab.com","contribute",{"text":544,"config":545},"Community",{"href":546,"dataGaName":547,"dataGaLocation":310},"/community/","community",{"text":549,"config":550},"Forum",{"href":551,"dataGaName":552,"dataGaLocation":310},"https://forum.gitlab.com/","forum",{"text":554,"config":555},"Events",{"href":556,"dataGaName":557,"dataGaLocation":310},"/events/","events",{"text":559,"config":560},"Partners",{"href":561,"dataGaName":562,"dataGaLocation":310},"/partners/","partners",{"config":564,"title":567,"text":568,"link":569},{"background":565,"textColor":566},"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":570,"config":571},"Read the latest",{"href":572,"dataGaName":573,"dataGaLocation":310},"/whats-new/","whats new",{"text":575,"config":576,"menu":578},"Company",{"dataNavLevelOne":577},"company",{"type":361,"columns":579},[580],{"items":581},[582,587,593,595,600,605,610,615,620,625],{"text":583,"config":584},"About",{"href":585,"dataGaName":586,"dataGaLocation":310},"/company/","about",{"text":588,"config":589,"footerGa":592},"Jobs",{"href":590,"dataGaName":591,"dataGaLocation":310},"/jobs/","jobs",{"dataGaName":591},{"text":554,"config":594},{"href":556,"dataGaName":557,"dataGaLocation":310},{"text":596,"config":597},"Leadership",{"href":598,"dataGaName":599,"dataGaLocation":310},"/company/team/e-group/","leadership",{"text":601,"config":602},"Handbook",{"href":603,"dataGaName":604,"dataGaLocation":310},"https://handbook.gitlab.com/","handbook",{"text":606,"config":607},"Investor relations",{"href":608,"dataGaName":609,"dataGaLocation":310},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":611,"config":612},"Trust Center",{"href":613,"dataGaName":614,"dataGaLocation":310},"/security/","trust center",{"text":616,"config":617},"AI Transparency Center",{"href":618,"dataGaName":619,"dataGaLocation":310},"/ai-transparency-center/","ai transparency center",{"text":621,"config":622},"Newsletter",{"href":623,"dataGaName":624,"dataGaLocation":310},"/company/contact/#contact-forms","newsletter",{"text":626,"config":627},"Press",{"href":628,"dataGaName":629,"dataGaLocation":310},"/press/","press",{"text":631,"config":632,"menu":633},"Contact us",{"dataNavLevelOne":577},{"type":361,"columns":634},[635],{"items":636},[637,642,647],{"text":638,"config":639},"Talk to sales",{"href":640,"dataGaName":641,"dataGaLocation":310},"/sales/","talk to sales",{"text":643,"config":644},"Support portal",{"href":645,"dataGaName":646,"dataGaLocation":310},"https://support.gitlab.com/hc/en-us","support portal",{"text":648,"config":649},"Customer portal",{"href":650,"dataGaName":651,"dataGaLocation":310},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":653,"login":654,"suggestions":661},"Close",{"text":655,"link":656},"To search repositories and projects, login to",{"text":657,"config":658},"gitlab.com",{"href":324,"dataGaName":659,"dataGaLocation":660},"search login","search",{"text":662,"default":663},"Suggestions",[664,666,670,672,676,680],{"text":341,"config":665},{"href":346,"dataGaName":341,"dataGaLocation":660},{"text":667,"config":668},"Code Suggestions (AI)",{"href":669,"dataGaName":667,"dataGaLocation":660},"/solutions/code-suggestions/",{"text":59,"config":671},{"href":378,"dataGaName":59,"dataGaLocation":660},{"text":673,"config":674},"GitLab on AWS",{"href":675,"dataGaName":673,"dataGaLocation":660},"/partners/technology-partners/aws/",{"text":677,"config":678},"GitLab on Google Cloud",{"href":679,"dataGaName":677,"dataGaLocation":660},"/partners/technology-partners/google-cloud-platform/",{"text":681,"config":682},"Why GitLab?",{"href":354,"dataGaName":681,"dataGaLocation":660},{"freeTrial":684,"mobileIcon":689,"desktopIcon":694,"secondaryButton":697},{"text":685,"config":686},"Start free trial",{"href":687,"dataGaName":315,"dataGaLocation":688},"https://gitlab.com/-/trials/new/","nav",{"altText":690,"config":691},"Gitlab Icon",{"src":692,"dataGaName":693,"dataGaLocation":688},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":690,"config":695},{"src":696,"dataGaName":693,"dataGaLocation":688},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":698,"config":699},"Get Started",{"href":700,"dataGaName":701,"dataGaLocation":688},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":703,"mobileIcon":707,"desktopIcon":709},{"text":704,"config":705},"Learn more about GitLab Duo",{"href":346,"dataGaName":706,"dataGaLocation":688},"gitlab duo",{"altText":690,"config":708},{"src":692,"dataGaName":693,"dataGaLocation":688},{"altText":690,"config":710},{"src":696,"dataGaName":693,"dataGaLocation":688},{"button":712,"mobileIcon":717,"desktopIcon":719},{"text":713,"config":714},"/switch",{"href":715,"dataGaName":716,"dataGaLocation":688},"#contact","switch",{"altText":690,"config":718},{"src":692,"dataGaName":693,"dataGaLocation":688},{"altText":690,"config":720},{"src":721,"dataGaName":693,"dataGaLocation":688},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":723,"mobileIcon":728,"desktopIcon":730},{"text":724,"config":725},"Back to pricing",{"href":458,"dataGaName":726,"dataGaLocation":688,"icon":727},"back to pricing","GoBack",{"altText":690,"config":729},{"src":692,"dataGaName":693,"dataGaLocation":688},{"altText":690,"config":731},{"src":696,"dataGaName":693,"dataGaLocation":688},{"title":733,"titleMobile":734,"button":735,"config":740},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":352,"config":736},{"href":737,"dataGaName":738,"dataGaLocation":739},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":741,"disabled":288},"release",{"data":743},{"text":744,"source":745,"edit":751,"contribute":756,"config":761,"items":766,"minimal":974},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":746,"config":747},"View page source",{"href":748,"dataGaName":749,"dataGaLocation":750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":752,"config":753},"Edit this page",{"href":754,"dataGaName":755,"dataGaLocation":750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":757,"config":758},"Please contribute",{"href":759,"dataGaName":760,"dataGaLocation":750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":762,"facebook":763,"youtube":764,"linkedin":765},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[767,814,866,910,942],{"title":456,"links":768,"subMenu":783},[769,773,778],{"text":770,"config":771},"View plans",{"href":458,"dataGaName":772,"dataGaLocation":750},"view plans",{"text":774,"config":775},"Why Premium?",{"href":776,"dataGaName":777,"dataGaLocation":750},"/pricing/premium/","why premium",{"text":779,"config":780},"Why Ultimate?",{"href":781,"dataGaName":782,"dataGaLocation":750},"/pricing/ultimate/","why ultimate",[784],{"title":785,"links":786},"Contact Us",[787,790,792,794,799,804,809],{"text":788,"config":789},"Contact sales",{"href":640,"dataGaName":320,"dataGaLocation":750},{"text":643,"config":791},{"href":645,"dataGaName":646,"dataGaLocation":750},{"text":648,"config":793},{"href":650,"dataGaName":651,"dataGaLocation":750},{"text":795,"config":796},"Status",{"href":797,"dataGaName":798,"dataGaLocation":750},"https://status.gitlab.com/","status",{"text":800,"config":801},"Terms of use",{"href":802,"dataGaName":803,"dataGaLocation":750},"/terms/","terms of use",{"text":805,"config":806},"Privacy statement",{"href":807,"dataGaName":808,"dataGaLocation":750},"/privacy/","privacy statement",{"text":810,"config":811},"Cookie preferences",{"dataGaName":812,"dataGaLocation":750,"id":813,"isOneTrustButton":184},"cookie preferences","ot-sdk-btn",{"title":357,"links":815,"subMenu":823},[816,819],{"text":302,"config":817},{"href":339,"dataGaName":818,"dataGaLocation":750},"devsecops platform",{"text":820,"config":821},"AI-Assisted Development",{"href":346,"dataGaName":822,"dataGaLocation":750},"ai-assisted development",[824],{"title":825,"links":826},"Topics",[827,832,837,842,847,851,856,861],{"text":828,"config":829},"CICD",{"href":830,"dataGaName":831,"dataGaLocation":750},"/topics/ci-cd/","cicd",{"text":833,"config":834},"GitOps",{"href":835,"dataGaName":836,"dataGaLocation":750},"/topics/gitops/","gitops",{"text":838,"config":839},"DevOps",{"href":840,"dataGaName":841,"dataGaLocation":750},"/topics/devops/","devops",{"text":843,"config":844},"Version Control",{"href":845,"dataGaName":846,"dataGaLocation":750},"/topics/version-control/","version control",{"text":301,"config":848},{"href":849,"dataGaName":850,"dataGaLocation":750},"/topics/devsecops/","devsecops",{"text":852,"config":853},"Cloud Native",{"href":854,"dataGaName":855,"dataGaLocation":750},"/topics/cloud-native/","cloud native",{"text":857,"config":858},"AI for Coding",{"href":859,"dataGaName":860,"dataGaLocation":750},"/topics/devops/ai-for-coding/","ai for coding",{"text":862,"config":863},"Agentic AI",{"href":864,"dataGaName":865,"dataGaLocation":750},"/topics/agentic-ai/","agentic ai",{"title":867,"links":868},"Solutions",[869,871,873,878,882,885,889,892,894,897,900,905],{"text":400,"config":870},{"href":395,"dataGaName":400,"dataGaLocation":750},{"text":389,"config":872},{"href":373,"dataGaName":374,"dataGaLocation":750},{"text":874,"config":875},"Agile development",{"href":876,"dataGaName":877,"dataGaLocation":750},"/solutions/agile-delivery/","agile delivery",{"text":879,"config":880},"SCM",{"href":385,"dataGaName":881,"dataGaLocation":750},"source code management",{"text":828,"config":883},{"href":378,"dataGaName":884,"dataGaLocation":750},"continuous integration & delivery",{"text":886,"config":887},"Value stream management",{"href":428,"dataGaName":888,"dataGaLocation":750},"value stream management",{"text":833,"config":890},{"href":891,"dataGaName":836,"dataGaLocation":750},"/solutions/gitops/",{"text":438,"config":893},{"href":441,"dataGaName":442,"dataGaLocation":750},{"text":895,"config":896},"Small business",{"href":447,"dataGaName":448,"dataGaLocation":750},{"text":898,"config":899},"Public sector",{"href":453,"dataGaName":454,"dataGaLocation":750},{"text":901,"config":902},"Education",{"href":903,"dataGaName":904,"dataGaLocation":750},"/solutions/education/","education",{"text":906,"config":907},"Financial services",{"href":908,"dataGaName":909,"dataGaLocation":750},"/solutions/finance/","financial services",{"title":461,"links":911},[912,914,916,918,921,923,926,928,930,932,934,936,938,940],{"text":474,"config":913},{"href":476,"dataGaName":477,"dataGaLocation":750},{"text":479,"config":915},{"href":481,"dataGaName":482,"dataGaLocation":750},{"text":484,"config":917},{"href":486,"dataGaName":487,"dataGaLocation":750},{"text":489,"config":919},{"href":491,"dataGaName":920,"dataGaLocation":750},"docs",{"text":512,"config":922},{"href":514,"dataGaName":515,"dataGaLocation":750},{"text":924,"config":925},"What's new",{"href":572,"dataGaName":573,"dataGaLocation":750},{"text":507,"config":927},{"href":509,"dataGaName":510,"dataGaLocation":750},{"text":526,"config":929},{"href":528,"dataGaName":529,"dataGaLocation":750},{"text":534,"config":931},{"href":536,"dataGaName":537,"dataGaLocation":750},{"text":539,"config":933},{"href":541,"dataGaName":542,"dataGaLocation":750},{"text":544,"config":935},{"href":546,"dataGaName":547,"dataGaLocation":750},{"text":549,"config":937},{"href":551,"dataGaName":552,"dataGaLocation":750},{"text":554,"config":939},{"href":556,"dataGaName":557,"dataGaLocation":750},{"text":559,"config":941},{"href":561,"dataGaName":562,"dataGaLocation":750},{"title":575,"links":943},[944,946,948,950,952,954,958,963,965,967,969],{"text":583,"config":945},{"href":585,"dataGaName":577,"dataGaLocation":750},{"text":588,"config":947},{"href":590,"dataGaName":591,"dataGaLocation":750},{"text":596,"config":949},{"href":598,"dataGaName":599,"dataGaLocation":750},{"text":601,"config":951},{"href":603,"dataGaName":604,"dataGaLocation":750},{"text":606,"config":953},{"href":608,"dataGaName":609,"dataGaLocation":750},{"text":955,"config":956},"Sustainability",{"href":957,"dataGaName":955,"dataGaLocation":750},"/sustainability/",{"text":959,"config":960},"Diversity, inclusion and belonging (DIB)",{"href":961,"dataGaName":962,"dataGaLocation":750},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":611,"config":964},{"href":613,"dataGaName":614,"dataGaLocation":750},{"text":621,"config":966},{"href":623,"dataGaName":624,"dataGaLocation":750},{"text":626,"config":968},{"href":628,"dataGaName":629,"dataGaLocation":750},{"text":970,"config":971},"Modern Slavery Transparency Statement",{"href":972,"dataGaName":973,"dataGaLocation":750},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":975},[976,979,982],{"text":977,"config":978},"Terms",{"href":802,"dataGaName":803,"dataGaLocation":750},{"text":980,"config":981},"Cookies",{"dataGaName":812,"dataGaLocation":750,"id":813,"isOneTrustButton":184},{"text":983,"config":984},"Privacy",{"href":807,"dataGaName":808,"dataGaLocation":750},[986],{"id":987,"title":7,"body":287,"config":988,"content":990,"description":287,"extension":994,"meta":995,"navigation":184,"path":996,"seo":997,"stem":998,"__hash__":999},"blogAuthors/en-us/blog/authors/mitra-jozenazemian.yml",{"template":989},"BlogAuthor",{"name":7,"config":991},{"headshot":992,"ctfId":993},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662373/Blog/Author%20Headshots/Screenshot_2024-10-25_at_8.23.56_AM.png","4suqsutT8w5ZmkIvSVrmWQ","yml",{},"/en-us/blog/authors/mitra-jozenazemian",{},"en-us/blog/authors/mitra-jozenazemian","DzsXAQdHz5kyKwnJ-xGAs_Wr_lt8XWi_J9LQijwLiVY",[1001,1009,1017],{"title":1002,"description":1003,"heroImage":1004,"category":283,"date":1005,"authors":1006,"slug":1008,"externalUrl":287},"A sandbox is only as closed as what an AI agent can reach","Stuck in an evaluation with no way out, an AI agent escaped in an hour through the one service on its allowlist. Here's the gap that opened.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1786468880/uxouffutvvwsbxzikhyc.png","2026-08-12",[1007],"Daniel Abeles","ai-agent-sandbox",{"title":1010,"description":1011,"heroImage":1012,"category":283,"date":1013,"authors":1014,"slug":1016,"externalUrl":287},"Shai-Hulud copycat campaign targets Python developers through PyPI typosquatting","GitLab’s Vulnerability Research team has uncovered a new Python supply chain attack targeting PyPI, deploying the Shai-Hulud worm to steal credentials from CI/CD systems.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1772630163/akp8ly2mrsfrhsb0liyb.png","2026-06-09",[1015,1007],"Dinesh Bolkensteyn","shai-hulud-copycat-campaign-targets-python-developers",{"title":1018,"description":1019,"heroImage":1020,"category":283,"date":1021,"authors":1022,"slug":1025,"externalUrl":287},"How to detect and prevent Contagious Interview IDE attacks","Learn how we built custom controls that detect and prevent malware campaigns like those used for Contagious Interview and how to deploy them in your environment.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774375772/kpaaaiqhokevxxeoxvu0.png","2026-05-04",[1023,1024],"Josh Feehs","Austin Bollinger","how-to-detect-and-prevent-contagious-interview-ide-attacks",{"promotions":1027},[1028,1042,1054,1065],{"id":1029,"categories":1030,"header":1032,"text":1033,"button":1034,"image":1039},"ai-modernization",[1031],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1035,"config":1036},"Get your AI maturity score",{"href":1037,"dataGaName":1038,"dataGaLocation":515},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1040},{"src":1041},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1043,"categories":1044,"header":1046,"text":1033,"button":1047,"image":1051},"devops-modernization",[1045,850],"product","Are you just managing tools or shipping innovation?",{"text":1048,"config":1049},"Get your DevOps maturity score",{"href":1050,"dataGaName":1038,"dataGaLocation":515},"/assessments/devops-modernization-assessment/",{"config":1052},{"src":1053},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1055,"categories":1056,"header":1057,"text":1033,"button":1058,"image":1062},"security-modernization",[299],"Are you trading speed for security?",{"text":1059,"config":1060},"Get your security maturity score",{"href":1061,"dataGaName":1038,"dataGaLocation":515},"/assessments/security-modernization-assessment/",{"config":1063},{"src":1064},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1066,"paths":1067,"header":1070,"text":1071,"button":1072,"image":1077},"github-azure-migration",[1068,1069],"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":1073,"config":1074},"See how GitLab compares to GitHub",{"href":1075,"dataGaName":1076,"dataGaLocation":515},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1078},{"src":1053},{"header":1080,"blurb":1081,"button":1082,"secondaryButton":1087},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1083,"config":1084},"Get your free trial",{"href":1085,"dataGaName":315,"dataGaLocation":1086},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":788,"config":1088},{"href":640,"dataGaName":320,"dataGaLocation":1086},1786803764747]