[{"data":1,"prerenderedAt":704},["ShallowReactive",2],{"/en-us/blog/threat-modeling-kubernetes-agent/":3,"navigation-en-us":33,"banner-en-us":450,"footer-en-us":465,"Vitor Meireles De Sousa":676,"next-steps-en-us":689},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":23,"_id":26,"_type":27,"title":28,"_source":29,"_file":30,"_stem":31,"_extension":32},"/en-us/blog/threat-modeling-kubernetes-agent","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Threat modeling the Kubernetes Agent: from MVC to continuous improvement","Learn how we put our threat model into action iteratively and expanded the process into a full-fledged standalone activity.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682156/Blog/Hero%20Images/pexels-jesus-miron-garcia-3043592.jpg","https://about.gitlab.com/blog/threat-modeling-kubernetes-agent","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Threat modeling the Kubernetes Agent: from MVC to continuous improvement\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Vitor Meireles De Sousa\"}],\n        \"datePublished\": \"2021-10-11\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Vitor Meireles De Sousa","2021-10-11","\n\nThreat modeling is more common in people’s everyday lives than they might think.  Each of us performs some level of threat modeling every time we’re in a situation where we’re evaluating threats. An everyday example I really like: crossing the street. Before we cross the street we look both ways, we evaluate the speed of each oncoming vehicle and verify the driver has seen us. Finally, if the lights are green, we cross the street. This is threat modeling!\n\n_If you’re interested in learning more about what threat modeling is and how we’re developing our threat model here at GitLab, you can read about [“How we’re creating a threat model framework that works for GitLab“](/blog/creating-a-threat-model-that-works-for-gitlab/) by my teammate [Mark Loveless](/company/team/#mloveless)._\n\n## Threat modeling IRL\n\nIn this blog post I’ll talk about how we put our threat modeling process into action iteratively with an in-depth look into how we developed the process from a security assessment with a side of threat modeling to a full-fledged standalone activity.  \n\n### Our threat modeling MVC\n\nWe rolled out the initial iteration of the GitLab threat model in November of 2020. One of the first projects we assessed through that new process was GitLab’s [Kubernetes Agent](https://docs.gitlab.com/ee/user/clusters/agent/) beta. At that time, my colleague [Joern Schneeweisz](/company/team/#joernchen) performed an initial threat model, which was actually more of a security assessment in which threat modeling activities were incorporated. In this [data flow diagram](/handbook/security/threat_modeling/howto.html#tools-and) from our initial threat model, you can see how the [architecture for the Kubernetes Agent looked in May 2020](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/f374356751aec8cb65b9dea4de3ba618805c2414/docs/architecture.md):\n\n```mermaid\ngraph TB\n  agentk -- gRPC bidirectional streaming --> kgb\n\n  subgraph \"GitLab\"\n  kgb[kgb]\n  GitLabRoR[GitLab RoR] -- gRPC --> kgb\n  kgb -- gRPC --> Gitaly[Gitaly]\n  kgb -- REST API --> GitLabRoR\n  end\n\n  subgraph \"Kubernetes cluster\"\n  agentk[agentk]\n  end\n```\n\nThis first review, despite our threat model being early stage, still allowed us to identify issues and findings (like the Agent exposing public projects with private repositories [(fixed with this merge request)](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48314) or the Agent name being vulnerable to path traversal attacks [(fixed with this merge request)](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37564)) that benefited our security and the broader engineering teams. Plus, the cross-organizational feedback we received during this iteration was key to improving our threat model integration and templates.\n\n### Increasing capabilities expand the threats\n\nFour months had passed since the initial assessment; it was time to revisit our previous findings and to review the expanded capabilities of the Kubernetes Agent feature. The [architecture had also evolved](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/154f538c997b4064294a54695846092c348bada8/doc/architecture.md#high-level-architecture), and at a high level we can see the product is changing names (`kgb` changed to `kas`, for Kubernetes Agent Server (KAS)). \n\n```mermaid\ngraph TB\n  agentk -- gRPC bidirectional streaming --> nginx\n\n  subgraph \"GitLab\"\n  nginx -- proxy pass port 5005 --> kas\n  kas[kas]\n  GitLabRoR[GitLab RoR] -- gRPC --> kas\n  kas -- gRPC --> Gitaly[Gitaly]\n  kas -- REST API --> GitLabRoR\n  end\n\n  subgraph \"Kubernetes cluster\"\n  agentk[agentk]\n  end\n```\n\nBy this time the threat modeling template we were using had evolved, and our [Application Security team](/handbook/security/security-engineering/application-security/) had used it in several other reviews. \n\nGitLab’s practice of [dogfooding](https://handbook.gitlab.com/handbook/values/#dogfooding) means we use issues to track our reviews. At the time of this second review, our threat modeling template now had a more structured approach where reviewers had sections that would 1) guide them throughout the review 2) require them to provide specific information.\n\nBecause our process was more robust now we moved the threat modeling activity of our security assessments into a dedicated repository, giving us a single source of truth. [The template](https://gitlab.com/gitlab-com/gl-security/security-research/threat-modeling-template/-/blob/3486ca53baf13d4aaba28dd340df153b2b83ea05/threat_model.md) had evolved to also include:\n\n* An “Application decomposition” section where the reviewer must enter details such as use case, external entry points, trust levels, data flow diagram, previous security issues and known references and best practices.\n* A dedicated threat analysis section.\n* The use of issue comments to detail each section of the threat modeling allowing us to easily reference sections individually via direct link.\n* The conversion and merge of the completed issue to an MD file, saved into the dedicated repository for future use. \n\n### What is better than iteration? More iteration\n\nSince our second review in October 2020, the Kubernetes Agent feature had evolved significantly, so we performed another assessment in February 2021. The difference this time was that we now had a [formal threat modeling process in place](/handbook/security/threat_modeling/). \n\n**To better understand the Kubernetes Agent feature, we added more details to our architectural diagram:**\n\n_Legend:_\n* Dotted arrows/flow: out of scope of the Architecture or TM\n* grpc: Google Remote Procedure Call\n* grpcs: grpc over SSL/TLS\n* ws: WebSocket\n* wss: ws over SSL/TLS\n\n![Detailed architectural diagram of the Kubernetes Agent](https://about.gitlab.com/images/blogimages/threat-modeling-KA/ka-architectural-diagram.png){: .shadow.medium.center}\nDetailed architectural diagram of the Kubernetes Agent.\n{: .note.text-center}\n\n\n**The data flow diagram we were using also evolved:**\n\n_Legend:_\n* Dotted arrows/flow: out of scope of the architecture or threat model\n* grpc: Google remote procedure call\n* grpcs: grpc over SSL/TLS\n* ws: WebSocket\n* wss: ws over SSL/TLS\n\n![file name](https://about.gitlab.com/images/blogimages/threat-modeling-KA/ka-data-flow.png){: .shadow.medium.center}\nAn evolved data flow diagram for the Kubernetes Agent.\n{: .note.text-center}\n\nAnd, naturally, as the features evolved, the threats evolved. Through our latest threat modeling we discovered that:\n\n* Listeners are used by the Agent and the KAS for observability and health checking. These listeners are unrestricted but they do listen on localhost by default.\n* On GitLab’s side, developers would be able to deploy an application to another cluster on another corporate network. This is limited by Kubernetes' own authorisations defined for each cluster.\n* While brainstorming for threats, we thought about whether a user would be able to access unauthorised projects through indirect access on Gitaly. Thankfully, this is well mitigated since a few conditions are necessary: \n     * A user must have access to the Agent's pod\n     * A user must be able to modify and reply to requests from the Agent pod \n          * However, each Agent also needs to submit a secret token, otherwise the [request is denied](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/5b7ca0b9fbc8daba28ca552dc26aab45e482cf0c/internal/module/agent_configuration/server/server.go#L55) (using [GitLab's client](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/5b7ca0b9fbc8daba28ca552dc26aab45e482cf0c/internal/gitlab/client.go)) GetAgentInfo implementation. That implementation [generates and passes a JWT token](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/5b7ca0b9fbc8daba28ca552dc26aab45e482cf0c/internal/gitlab/client.go#L108-123), along with the [Agent token](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/5b7ca0b9fbc8daba28ca552dc26aab45e482cf0c/internal/gitlab/do_options.go#L103-109). The Agent must also be configured to consult only authorised repositories, which makes it impossible for a user to access other repositories from the Agent.\n* On local installations, it’s possible to use unencrypted communications between the Kubernetes Agent and the KAS. However, on gitlab.com we have enforced secure communications.\n\n## Continuous improvement and iteration\n\nThreat modeling, just like anything in security, isn’t something you do once and are done with it. As we’ve seen with the reviews we’ve performed on the Kubernetes Agent, threat modeling involves iteration and constant adoption of ever-changing features and attack surfaces of a product.\n\nOur threat model is now mature enough that it's an established process, performed as a separate review and merged into a dedicated repository at completion. In the future, we hope to be able to publicly share those threat models to help customers, the community and to continue strengthening our [hackerone program](https://hackerone.com/gitlab).\n\nFor the next iterations we’re looking for broad adoption of threat modeling across GitLab's engineering teams and beyond. We plan to use our threat model as a way to improve  [asynchronous communication](/company/culture/all-remote/asynchronous/) between the different [security stable counterparts](/handbook/security/security-engineering/application-security/stable-counterparts.html) that operate across the organization. These stable counterparts ensure security practices are integrated early on in the development process and also allow us to ensure better coverage across vacations and time zones.\n\n## About Kubernetes\n\nUntil then, if you’re interested in more threat modeling details specific to Kubernetes itself, I highly recommend the [Kubernetes Security Audit Working Group Kubernetes threat model](https://github.com/kubernetes/community/tree/d538271e3f5eed22429ded165aeb2557c6277967/wg-security-audit). One of my fellow GitLab teammates, [Marco Lancini](/company/team/#mlancini) has published a great post, [“The Current State of Kubernetes Threat Modelling”](https://www.marcolancini.it/2020/blog-kubernetes-threat-modelling/) on his personal blog which contains useful information on different methods used to perform a threat model for Kubernetes. \n\n## How to threat model\n\nAnd, if you’re interested in how we’re rolling out threat modeling across GitLab, to teams beyond Security and Engineering, we’ve been tweaking our [how to threat model](/handbook/security/threat_modeling/howto.html) guide to help as many team members as possible understand what threat modeling is and how and where to get started. Perhaps you’ll find some helpful tips and tricks there.\n\nAnd, keep an eye on this space, we’re planning to revisit threat modeling in blog posts where we’ll dive deeper into the PASTA methodology we’re using and take a closer look at what threat modeling looks like in practice here at GitLab.\n\nHave something to share? Comment below or find me on twitter at [@muffinbox33](https://twitter.com/Muffinbox33).\n\n_Also, I would like to take a moment to thank the Configure team and [Mikhail](/company/team/#ash2k) for their awesome collaboration during the various threat models we have performed._\n\nHappy threat modeling!\n\nCover image by [Jesús Mirón García](https://www.pexels.com/@jesus-miron-garcia-1583477?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels) on [Pexels](https://www.pexels.com/photo/timelapse-photography-of-vehicles-on-road-3043592/?utm_content=attributionCopyText&utm_medium=referral&utm_source=pexels)\n{: .note}\n\n\n## Read more on Kubernetes: \n\n- [How to install and use the GitLab Kubernetes Operator](/blog/gko-on-ocp/)\n\n- [How to deploy the GitLab Agent for Kubernetes with limited permissions](/blog/setting-up-the-k-agent/)\n\n- [A new era of Kubernetes integrations on GitLab.com](/blog/gitlab-kubernetes-agent-on-gitlab-com/)\n\n- [Understand Kubernetes terminology from namespaces to pods](/blog/kubernetes-terminology/)\n\n- [What we learned after a year of GitLab.com on Kubernetes](/blog/year-of-kubernetes/)\n","security",[21],{"slug":24,"featured":6,"template":25},"threat-modeling-kubernetes-agent","BlogPost","content:en-us:blog:threat-modeling-kubernetes-agent.yml","yaml","Threat Modeling Kubernetes Agent","content","en-us/blog/threat-modeling-kubernetes-agent.yml","en-us/blog/threat-modeling-kubernetes-agent","yml",{"_path":34,"_dir":35,"_draft":6,"_partial":6,"_locale":7,"data":36,"_id":446,"_type":27,"title":447,"_source":29,"_file":448,"_stem":449,"_extension":32},"/shared/en-us/main-navigation","en-us",{"logo":37,"freeTrial":42,"sales":47,"login":52,"items":57,"search":387,"minimal":418,"duo":437},{"config":38},{"href":39,"dataGaName":40,"dataGaLocation":41},"/","gitlab logo","header",{"text":43,"config":44},"Get free trial",{"href":45,"dataGaName":46,"dataGaLocation":41},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":48,"config":49},"Talk to sales",{"href":50,"dataGaName":51,"dataGaLocation":41},"/sales/","sales",{"text":53,"config":54},"Sign in",{"href":55,"dataGaName":56,"dataGaLocation":41},"https://gitlab.com/users/sign_in/","sign in",[58,102,198,203,308,368],{"text":59,"config":60,"cards":62,"footer":85},"Platform",{"dataNavLevelOne":61},"platform",[63,69,77],{"title":59,"description":64,"link":65},"The most comprehensive AI-powered DevSecOps Platform",{"text":66,"config":67},"Explore our Platform",{"href":68,"dataGaName":61,"dataGaLocation":41},"/platform/",{"title":70,"description":71,"link":72},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":73,"config":74},"Meet GitLab Duo",{"href":75,"dataGaName":76,"dataGaLocation":41},"/gitlab-duo/","gitlab duo ai",{"title":78,"description":79,"link":80},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":81,"config":82},"Learn more",{"href":83,"dataGaName":84,"dataGaLocation":41},"/why-gitlab/","why gitlab",{"title":86,"items":87},"Get started with",[88,93,98],{"text":89,"config":90},"Platform Engineering",{"href":91,"dataGaName":92,"dataGaLocation":41},"/solutions/platform-engineering/","platform engineering",{"text":94,"config":95},"Developer Experience",{"href":96,"dataGaName":97,"dataGaLocation":41},"/developer-experience/","Developer experience",{"text":99,"config":100},"MLOps",{"href":101,"dataGaName":99,"dataGaLocation":41},"/topics/devops/the-role-of-ai-in-devops/",{"text":103,"left":104,"config":105,"link":107,"lists":111,"footer":180},"Product",true,{"dataNavLevelOne":106},"solutions",{"text":108,"config":109},"View all Solutions",{"href":110,"dataGaName":106,"dataGaLocation":41},"/solutions/",[112,137,159],{"title":113,"description":114,"link":115,"items":120},"Automation","CI/CD and automation to accelerate deployment",{"config":116},{"icon":117,"href":118,"dataGaName":119,"dataGaLocation":41},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[121,125,129,133],{"text":122,"config":123},"CI/CD",{"href":124,"dataGaLocation":41,"dataGaName":122},"/solutions/continuous-integration/",{"text":126,"config":127},"AI-Assisted Development",{"href":75,"dataGaLocation":41,"dataGaName":128},"AI assisted development",{"text":130,"config":131},"Source Code Management",{"href":132,"dataGaLocation":41,"dataGaName":130},"/solutions/source-code-management/",{"text":134,"config":135},"Automated Software Delivery",{"href":118,"dataGaLocation":41,"dataGaName":136},"Automated software delivery",{"title":138,"description":139,"link":140,"items":145},"Security","Deliver code faster without compromising security",{"config":141},{"href":142,"dataGaName":143,"dataGaLocation":41,"icon":144},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[146,149,154],{"text":147,"config":148},"Security & Compliance",{"href":142,"dataGaLocation":41,"dataGaName":147},{"text":150,"config":151},"Software Supply Chain Security",{"href":152,"dataGaLocation":41,"dataGaName":153},"/solutions/supply-chain/","Software supply chain security",{"text":155,"config":156},"Compliance & Governance",{"href":157,"dataGaLocation":41,"dataGaName":158},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":160,"link":161,"items":166},"Measurement",{"config":162},{"icon":163,"href":164,"dataGaName":165,"dataGaLocation":41},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[167,171,175],{"text":168,"config":169},"Visibility & Measurement",{"href":164,"dataGaLocation":41,"dataGaName":170},"Visibility and Measurement",{"text":172,"config":173},"Value Stream Management",{"href":174,"dataGaLocation":41,"dataGaName":172},"/solutions/value-stream-management/",{"text":176,"config":177},"Analytics & Insights",{"href":178,"dataGaLocation":41,"dataGaName":179},"/solutions/analytics-and-insights/","Analytics and insights",{"title":181,"items":182},"GitLab for",[183,188,193],{"text":184,"config":185},"Enterprise",{"href":186,"dataGaLocation":41,"dataGaName":187},"/enterprise/","enterprise",{"text":189,"config":190},"Small Business",{"href":191,"dataGaLocation":41,"dataGaName":192},"/small-business/","small business",{"text":194,"config":195},"Public Sector",{"href":196,"dataGaLocation":41,"dataGaName":197},"/solutions/public-sector/","public sector",{"text":199,"config":200},"Pricing",{"href":201,"dataGaName":202,"dataGaLocation":41,"dataNavLevelOne":202},"/pricing/","pricing",{"text":204,"config":205,"link":207,"lists":211,"feature":295},"Resources",{"dataNavLevelOne":206},"resources",{"text":208,"config":209},"View all resources",{"href":210,"dataGaName":206,"dataGaLocation":41},"/resources/",[212,245,267],{"title":213,"items":214},"Getting started",[215,220,225,230,235,240],{"text":216,"config":217},"Install",{"href":218,"dataGaName":219,"dataGaLocation":41},"/install/","install",{"text":221,"config":222},"Quick start guides",{"href":223,"dataGaName":224,"dataGaLocation":41},"/get-started/","quick setup checklists",{"text":226,"config":227},"Learn",{"href":228,"dataGaLocation":41,"dataGaName":229},"https://university.gitlab.com/","learn",{"text":231,"config":232},"Product documentation",{"href":233,"dataGaName":234,"dataGaLocation":41},"https://docs.gitlab.com/","product documentation",{"text":236,"config":237},"Best practice videos",{"href":238,"dataGaName":239,"dataGaLocation":41},"/getting-started-videos/","best practice videos",{"text":241,"config":242},"Integrations",{"href":243,"dataGaName":244,"dataGaLocation":41},"/integrations/","integrations",{"title":246,"items":247},"Discover",[248,253,257,262],{"text":249,"config":250},"Customer success stories",{"href":251,"dataGaName":252,"dataGaLocation":41},"/customers/","customer success stories",{"text":254,"config":255},"Blog",{"href":256,"dataGaName":5,"dataGaLocation":41},"/blog/",{"text":258,"config":259},"Remote",{"href":260,"dataGaName":261,"dataGaLocation":41},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":263,"config":264},"TeamOps",{"href":265,"dataGaName":266,"dataGaLocation":41},"/teamops/","teamops",{"title":268,"items":269},"Connect",[270,275,280,285,290],{"text":271,"config":272},"GitLab Services",{"href":273,"dataGaName":274,"dataGaLocation":41},"/services/","services",{"text":276,"config":277},"Community",{"href":278,"dataGaName":279,"dataGaLocation":41},"/community/","community",{"text":281,"config":282},"Forum",{"href":283,"dataGaName":284,"dataGaLocation":41},"https://forum.gitlab.com/","forum",{"text":286,"config":287},"Events",{"href":288,"dataGaName":289,"dataGaLocation":41},"/events/","events",{"text":291,"config":292},"Partners",{"href":293,"dataGaName":294,"dataGaLocation":41},"/partners/","partners",{"backgroundColor":296,"textColor":297,"text":298,"image":299,"link":303},"#2f2a6b","#fff","Insights for the future of software development",{"altText":300,"config":301},"the source promo card",{"src":302},"/images/navigation/the-source-promo-card.svg",{"text":304,"config":305},"Read the latest",{"href":306,"dataGaName":307,"dataGaLocation":41},"/the-source/","the source",{"text":309,"config":310,"lists":312},"Company",{"dataNavLevelOne":311},"company",[313],{"items":314},[315,320,326,328,333,338,343,348,353,358,363],{"text":316,"config":317},"About",{"href":318,"dataGaName":319,"dataGaLocation":41},"/company/","about",{"text":321,"config":322,"footerGa":325},"Jobs",{"href":323,"dataGaName":324,"dataGaLocation":41},"/jobs/","jobs",{"dataGaName":324},{"text":286,"config":327},{"href":288,"dataGaName":289,"dataGaLocation":41},{"text":329,"config":330},"Leadership",{"href":331,"dataGaName":332,"dataGaLocation":41},"/company/team/e-group/","leadership",{"text":334,"config":335},"Team",{"href":336,"dataGaName":337,"dataGaLocation":41},"/company/team/","team",{"text":339,"config":340},"Handbook",{"href":341,"dataGaName":342,"dataGaLocation":41},"https://handbook.gitlab.com/","handbook",{"text":344,"config":345},"Investor relations",{"href":346,"dataGaName":347,"dataGaLocation":41},"https://ir.gitlab.com/","investor relations",{"text":349,"config":350},"Trust Center",{"href":351,"dataGaName":352,"dataGaLocation":41},"/security/","trust center",{"text":354,"config":355},"AI Transparency Center",{"href":356,"dataGaName":357,"dataGaLocation":41},"/ai-transparency-center/","ai transparency center",{"text":359,"config":360},"Newsletter",{"href":361,"dataGaName":362,"dataGaLocation":41},"/company/contact/","newsletter",{"text":364,"config":365},"Press",{"href":366,"dataGaName":367,"dataGaLocation":41},"/press/","press",{"text":369,"config":370,"lists":371},"Contact us",{"dataNavLevelOne":311},[372],{"items":373},[374,377,382],{"text":48,"config":375},{"href":50,"dataGaName":376,"dataGaLocation":41},"talk to sales",{"text":378,"config":379},"Get help",{"href":380,"dataGaName":381,"dataGaLocation":41},"/support/","get help",{"text":383,"config":384},"Customer portal",{"href":385,"dataGaName":386,"dataGaLocation":41},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":388,"login":389,"suggestions":396},"Close",{"text":390,"link":391},"To search repositories and projects, login to",{"text":392,"config":393},"gitlab.com",{"href":55,"dataGaName":394,"dataGaLocation":395},"search login","search",{"text":397,"default":398},"Suggestions",[399,401,405,407,411,415],{"text":70,"config":400},{"href":75,"dataGaName":70,"dataGaLocation":395},{"text":402,"config":403},"Code Suggestions (AI)",{"href":404,"dataGaName":402,"dataGaLocation":395},"/solutions/code-suggestions/",{"text":122,"config":406},{"href":124,"dataGaName":122,"dataGaLocation":395},{"text":408,"config":409},"GitLab on AWS",{"href":410,"dataGaName":408,"dataGaLocation":395},"/partners/technology-partners/aws/",{"text":412,"config":413},"GitLab on Google Cloud",{"href":414,"dataGaName":412,"dataGaLocation":395},"/partners/technology-partners/google-cloud-platform/",{"text":416,"config":417},"Why GitLab?",{"href":83,"dataGaName":416,"dataGaLocation":395},{"freeTrial":419,"mobileIcon":424,"desktopIcon":429,"secondaryButton":432},{"text":420,"config":421},"Start free trial",{"href":422,"dataGaName":46,"dataGaLocation":423},"https://gitlab.com/-/trials/new/","nav",{"altText":425,"config":426},"Gitlab Icon",{"src":427,"dataGaName":428,"dataGaLocation":423},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":425,"config":430},{"src":431,"dataGaName":428,"dataGaLocation":423},"/images/brand/gitlab-logo-type.svg",{"text":433,"config":434},"Get Started",{"href":435,"dataGaName":436,"dataGaLocation":423},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":438,"mobileIcon":442,"desktopIcon":444},{"text":439,"config":440},"Learn more about GitLab Duo",{"href":75,"dataGaName":441,"dataGaLocation":423},"gitlab duo",{"altText":425,"config":443},{"src":427,"dataGaName":428,"dataGaLocation":423},{"altText":425,"config":445},{"src":431,"dataGaName":428,"dataGaLocation":423},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":451,"_dir":35,"_draft":6,"_partial":6,"_locale":7,"title":452,"button":453,"image":457,"config":460,"_id":462,"_type":27,"_source":29,"_file":463,"_stem":464,"_extension":32},"/shared/en-us/banner","is now in public beta!",{"text":81,"config":454},{"href":455,"dataGaName":456,"dataGaLocation":41},"/gitlab-duo/agent-platform/","duo banner",{"config":458},{"src":459},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":461},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":466,"_dir":35,"_draft":6,"_partial":6,"_locale":7,"data":467,"_id":672,"_type":27,"title":673,"_source":29,"_file":674,"_stem":675,"_extension":32},"/shared/en-us/main-footer",{"text":468,"source":469,"edit":475,"contribute":480,"config":485,"items":490,"minimal":664},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":470,"config":471},"View page source",{"href":472,"dataGaName":473,"dataGaLocation":474},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":476,"config":477},"Edit this page",{"href":478,"dataGaName":479,"dataGaLocation":474},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":481,"config":482},"Please contribute",{"href":483,"dataGaName":484,"dataGaLocation":474},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":486,"facebook":487,"youtube":488,"linkedin":489},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[491,514,571,600,634],{"title":59,"links":492,"subMenu":497},[493],{"text":494,"config":495},"DevSecOps platform",{"href":68,"dataGaName":496,"dataGaLocation":474},"devsecops platform",[498],{"title":199,"links":499},[500,504,509],{"text":501,"config":502},"View plans",{"href":201,"dataGaName":503,"dataGaLocation":474},"view plans",{"text":505,"config":506},"Why Premium?",{"href":507,"dataGaName":508,"dataGaLocation":474},"/pricing/premium/","why premium",{"text":510,"config":511},"Why Ultimate?",{"href":512,"dataGaName":513,"dataGaLocation":474},"/pricing/ultimate/","why ultimate",{"title":515,"links":516},"Solutions",[517,522,525,527,532,537,541,544,548,553,555,558,561,566],{"text":518,"config":519},"Digital transformation",{"href":520,"dataGaName":521,"dataGaLocation":474},"/topics/digital-transformation/","digital transformation",{"text":147,"config":523},{"href":142,"dataGaName":524,"dataGaLocation":474},"security & compliance",{"text":136,"config":526},{"href":118,"dataGaName":119,"dataGaLocation":474},{"text":528,"config":529},"Agile development",{"href":530,"dataGaName":531,"dataGaLocation":474},"/solutions/agile-delivery/","agile delivery",{"text":533,"config":534},"Cloud transformation",{"href":535,"dataGaName":536,"dataGaLocation":474},"/topics/cloud-native/","cloud transformation",{"text":538,"config":539},"SCM",{"href":132,"dataGaName":540,"dataGaLocation":474},"source code management",{"text":122,"config":542},{"href":124,"dataGaName":543,"dataGaLocation":474},"continuous integration & delivery",{"text":545,"config":546},"Value stream management",{"href":174,"dataGaName":547,"dataGaLocation":474},"value stream management",{"text":549,"config":550},"GitOps",{"href":551,"dataGaName":552,"dataGaLocation":474},"/solutions/gitops/","gitops",{"text":184,"config":554},{"href":186,"dataGaName":187,"dataGaLocation":474},{"text":556,"config":557},"Small business",{"href":191,"dataGaName":192,"dataGaLocation":474},{"text":559,"config":560},"Public sector",{"href":196,"dataGaName":197,"dataGaLocation":474},{"text":562,"config":563},"Education",{"href":564,"dataGaName":565,"dataGaLocation":474},"/solutions/education/","education",{"text":567,"config":568},"Financial services",{"href":569,"dataGaName":570,"dataGaLocation":474},"/solutions/finance/","financial services",{"title":204,"links":572},[573,575,577,579,582,584,586,588,590,592,594,596,598],{"text":216,"config":574},{"href":218,"dataGaName":219,"dataGaLocation":474},{"text":221,"config":576},{"href":223,"dataGaName":224,"dataGaLocation":474},{"text":226,"config":578},{"href":228,"dataGaName":229,"dataGaLocation":474},{"text":231,"config":580},{"href":233,"dataGaName":581,"dataGaLocation":474},"docs",{"text":254,"config":583},{"href":256,"dataGaName":5,"dataGaLocation":474},{"text":249,"config":585},{"href":251,"dataGaName":252,"dataGaLocation":474},{"text":258,"config":587},{"href":260,"dataGaName":261,"dataGaLocation":474},{"text":271,"config":589},{"href":273,"dataGaName":274,"dataGaLocation":474},{"text":263,"config":591},{"href":265,"dataGaName":266,"dataGaLocation":474},{"text":276,"config":593},{"href":278,"dataGaName":279,"dataGaLocation":474},{"text":281,"config":595},{"href":283,"dataGaName":284,"dataGaLocation":474},{"text":286,"config":597},{"href":288,"dataGaName":289,"dataGaLocation":474},{"text":291,"config":599},{"href":293,"dataGaName":294,"dataGaLocation":474},{"title":309,"links":601},[602,604,606,608,610,612,614,618,623,625,627,629],{"text":316,"config":603},{"href":318,"dataGaName":311,"dataGaLocation":474},{"text":321,"config":605},{"href":323,"dataGaName":324,"dataGaLocation":474},{"text":329,"config":607},{"href":331,"dataGaName":332,"dataGaLocation":474},{"text":334,"config":609},{"href":336,"dataGaName":337,"dataGaLocation":474},{"text":339,"config":611},{"href":341,"dataGaName":342,"dataGaLocation":474},{"text":344,"config":613},{"href":346,"dataGaName":347,"dataGaLocation":474},{"text":615,"config":616},"Sustainability",{"href":617,"dataGaName":615,"dataGaLocation":474},"/sustainability/",{"text":619,"config":620},"Diversity, inclusion and belonging (DIB)",{"href":621,"dataGaName":622,"dataGaLocation":474},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":349,"config":624},{"href":351,"dataGaName":352,"dataGaLocation":474},{"text":359,"config":626},{"href":361,"dataGaName":362,"dataGaLocation":474},{"text":364,"config":628},{"href":366,"dataGaName":367,"dataGaLocation":474},{"text":630,"config":631},"Modern Slavery Transparency Statement",{"href":632,"dataGaName":633,"dataGaLocation":474},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":635,"links":636},"Contact Us",[637,640,642,644,649,654,659],{"text":638,"config":639},"Contact an expert",{"href":50,"dataGaName":51,"dataGaLocation":474},{"text":378,"config":641},{"href":380,"dataGaName":381,"dataGaLocation":474},{"text":383,"config":643},{"href":385,"dataGaName":386,"dataGaLocation":474},{"text":645,"config":646},"Status",{"href":647,"dataGaName":648,"dataGaLocation":474},"https://status.gitlab.com/","status",{"text":650,"config":651},"Terms of use",{"href":652,"dataGaName":653,"dataGaLocation":474},"/terms/","terms of use",{"text":655,"config":656},"Privacy statement",{"href":657,"dataGaName":658,"dataGaLocation":474},"/privacy/","privacy statement",{"text":660,"config":661},"Cookie preferences",{"dataGaName":662,"dataGaLocation":474,"id":663,"isOneTrustButton":104},"cookie preferences","ot-sdk-btn",{"items":665},[666,668,670],{"text":650,"config":667},{"href":652,"dataGaName":653,"dataGaLocation":474},{"text":655,"config":669},{"href":657,"dataGaName":658,"dataGaLocation":474},{"text":660,"config":671},{"dataGaName":662,"dataGaLocation":474,"id":663,"isOneTrustButton":104},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[677],{"_path":678,"_dir":679,"_draft":6,"_partial":6,"_locale":7,"content":680,"config":684,"_id":686,"_type":27,"title":18,"_source":29,"_file":687,"_stem":688,"_extension":32},"/en-us/blog/authors/vitor-meireles-de-sousa","authors",{"name":18,"config":681},{"headshot":682,"ctfId":683},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682001/Blog/Author%20Headshots/vdesousa-headshot.png","vdesousa",{"template":685},"BlogAuthor","content:en-us:blog:authors:vitor-meireles-de-sousa.yml","en-us/blog/authors/vitor-meireles-de-sousa.yml","en-us/blog/authors/vitor-meireles-de-sousa",{"_path":690,"_dir":35,"_draft":6,"_partial":6,"_locale":7,"header":691,"eyebrow":692,"blurb":693,"button":694,"secondaryButton":698,"_id":700,"_type":27,"title":701,"_source":29,"_file":702,"_stem":703,"_extension":32},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":43,"config":695},{"href":696,"dataGaName":46,"dataGaLocation":697},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":48,"config":699},{"href":50,"dataGaName":51,"dataGaLocation":697},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1753981641546]