[{"data":1,"prerenderedAt":717},["ShallowReactive",2],{"/en-us/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd/":3,"navigation-en-us":38,"banner-en-us":455,"footer-en-us":467,"João Pereira-Tim Rizzi":678,"next-steps-en-us":702},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":28,"_id":31,"_type":32,"title":33,"_source":34,"_file":35,"_stem":36,"_extension":37},"/en-us/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Container image provenance with Cosign in GitLab CI/CD","Use GitLab pipelines to automate building, signing, and annotating Docker images. This tutorial shares code to show you how. Try it out in your own organization.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098395/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2823%29_2w6waL76KROjhJHM2vXet6_1750098395162.png","https://about.gitlab.com/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Annotate container images with build provenance using Cosign in GitLab CI/CD\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"João Pereira\"},{\"@type\":\"Person\",\"name\":\"Tim Rizzi\"}],\n        \"datePublished\": \"2024-09-04\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":21,"body":22,"category":23,"tags":24},"Annotate container images with build provenance using Cosign in GitLab CI/CD",[19,20],"João Pereira","Tim Rizzi","2024-09-04","Container security has become a critical concern in software development. As organizations increasingly rely on containerized applications, ensuring the integrity and traceability of container images is paramount. Enhancing the security and traceability of your container images directly in your GitLab CI/CD pipeline can streamline your development process while significantly boosting your security posture.\n\nThis tutorial demonstrates setting up a GitLab pipeline to automate the process of building, signing, and annotating Docker images using Cosign and the GitLab container registry. By integrating these practices, you'll secure your images and ensure that each one is easily traceable, aligning with best practices in DevSecOps.\n\n## Background on container image security\n\nBefore we dive into the technical details, it's crucial to understand why container image security is so important. In [microservices](https://about.gitlab.com/topics/microservices/) and cloud-native applications, containers have become the standard for packaging and deploying software. However, this widespread adoption has also made containers an attractive target for cyber attacks.\n\nContainer image security is a vital component of the broader [software supply chain security](https://about.gitlab.com/blog/the-ultimate-guide-to-software-supply-chain-security/) concept. This encompasses all the tools, processes, and practices that ensure your software's integrity, authenticity, and security from development to deployment. By securing your container images, you're protecting your application and your entire software supply chain.\n\n## Introduction to Cosign\n\nEnter [Cosign](https://about.gitlab.com/blog/keyless-signing-with-cosign/), a tool designed to address these security concerns. Cosign is part of the Sigstore project, an open-source initiative aimed at improving the security of the software supply chain. Cosign allows developers to sign and verify container images, ensuring their integrity and authenticity.\n\nKey benefits of Cosign include:\n\n- easy integration with existing CI/CD pipelines\n- support for various signing methods, including keyless signing\n- ability to attach and verify arbitrary metadata to container images\n\nBy incorporating Cosign into your GitLab CI/CD pipeline, you're taking a significant step towards robust [DevSecOps](https://about.gitlab.com/topics/devsecops/) practices.\n\n## Benefits of image signing and annotation\n\nImage signing serves as a seal of authenticity for your container images. It helps prevent tampering and ensures that the image deployed in your production environment is precisely the one that passed through your secure build process.\n\nAnnotations, on the other hand, provide valuable metadata about the build process. This information is used for auditing and traceability. In a security incident, having detailed provenance data can significantly speed up the investigation and remediation process.\n\n## GitLab CI/CD pipeline configuration\n\nLet's look at an example `.gitlab-ci.yml` file that outlines the process of building, signing, and annotating a Docker image using Cosign:\n\n```yaml\nstages:\n  - build\n\nbuild_and_sign:\n  stage: build\n  image: docker:latest\n  services:\n    - docker:dind  # Enable Docker-in-Docker service to allow Docker commands inside the container\n  variables:\n    IMAGE_TAG: $CI_COMMIT_SHORT_SHA  # Use the commit short SHA as the image tag\n    IMAGE_URI: $CI_REGISTRY_IMAGE:$IMAGE_TAG  # Construct the full image URI with the registry, project path, and tag\n    COSIGN_YES: \"true\"  # Automatically confirm actions in Cosign without user interaction\n    FF_SCRIPT_SECTIONS: \"true\"  # Enables GitLab's CI script sections for better multi-line script output\n  id_tokens:\n    SIGSTORE_ID_TOKEN:\n      aud: sigstore  # Provide an OIDC token for keyless signing with Cosign\n  before_script:\n    - apk add --no-cache cosign jq  # Install Cosign (mandatory) and jq (optional)\n    - docker login -u \"gitlab-ci-token\" -p \"$CI_JOB_TOKEN\" \"$CI_REGISTRY\"  # Log in to the Docker registry using GitLab CI token\n  script:\n    # Build the Docker image using the specified tag and push it to the registry\n    - docker build --pull -t \"$IMAGE_URI\" .\n    - docker push \"$IMAGE_URI\"\n\n    # Retrieve the digest of the pushed image to use in the signing step\n    - IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' \"$IMAGE_URI\")\n\n    # Sign the image using Cosign with annotations that provide metadata about the build and tag annotation to allow verifying\n    # the tag->digest mapping (https://github.com/sigstore/cosign?tab=readme-ov-file#tag-signing)\n    - |\n      cosign sign \"$IMAGE_DIGEST\" \\\n        --annotations \"com.gitlab.ci.user.name=$GITLAB_USER_NAME\" \\\n        --annotations \"com.gitlab.ci.pipeline.id=$CI_PIPELINE_ID\" \\\n        --annotations \"com.gitlab.ci.pipeline.url=$CI_PIPELINE_URL\" \\\n        --annotations \"com.gitlab.ci.job.id=$CI_JOB_ID\" \\\n        --annotations \"com.gitlab.ci.job.url=$CI_JOB_URL\" \\\n        --annotations \"com.gitlab.ci.commit.sha=$CI_COMMIT_SHA\" \\\n        --annotations \"com.gitlab.ci.commit.ref.name=$CI_COMMIT_REF_NAME\" \\\n        --annotations \"com.gitlab.ci.project.path=$CI_PROJECT_PATH\" \\\n        --annotations \"org.opencontainers.image.source=$CI_PROJECT_URL\" \\\n        --annotations \"org.opencontainers.image.revision=$CI_COMMIT_SHA\" \\\n        --annotations \"tag=$IMAGE_TAG\"\n\n    # Verify the image signature using Cosign to ensure it matches the expected annotations and certificate identity\n    - |\n      cosign verify \\\n        --annotations \"tag=$IMAGE_TAG\" \\\n        --certificate-identity \"$CI_PROJECT_URL//.gitlab-ci.yml@refs/heads/$CI_COMMIT_REF_NAME\" \\\n        --certificate-oidc-issuer \"$CI_SERVER_URL\" \\\n        \"$IMAGE_URI\" | jq .  # Use jq to format the verification output for easier readability\n```\n\nLet's break down this pipeline configuration and understand each part in detail.\n\n## Detailed explanation of the pipeline\n\n### 1. Setup and prerequisites\n\nThe pipeline starts by setting up the necessary environment:\n\n* It uses the `docker:latest` image and enables Docker-in-Docker service, allowing Docker commands to be run within the CI job.\n* It defines variables for the image tag and URI using GitLab CI/CD predefined variables.\n* It sets up an OIDC token for keyless signing with Cosign.\n* In the `before_script` section, it installs Cosign and jq (for JSON processing) and logs into the GitLab container registry.\n\n### 2. Building and pushing the image\n\nThe first step in the script is to build the Docker image and push it to the GitLab container registry:\n\n```yaml\n- docker build --pull -t \"$IMAGE_URI\" .\n- docker push \"$IMAGE_URI\"\n```\n\nThis creates the image using the current directory's Dockerfile and pushes it to the registry.\n\n### 3. Signing the image with Cosign\n\nAfter building and pushing the image, the pipeline signs it using Cosign:\n\n```yaml\n- IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' \"$IMAGE_URI\")\n- |\n  cosign sign \"$IMAGE_DIGEST\" \\\n    --annotations \"com.gitlab.ci.user.name=$GITLAB_USER_NAME\" \\\n    --annotations \"com.gitlab.ci.pipeline.id=$CI_PIPELINE_ID\" \\\n    # ... (other annotations) ...\n    --annotations \"tag=$IMAGE_TAG\"\n```\n\nThis step first retrieves the image digest and then uses Cosign to sign the image, adding several annotations.\n\n## Verifying the signature and annotations\n\nAfter signing the image, it's crucial to verify the signature and the annotations we've added. This verification step ensures that the provenance data attached to the image is correct and hasn't been tampered with.\n\nIn our pipeline, we've included a verification step using the `cosign verify` command:\n\n```yaml\n- |\n  cosign verify \\\n    --annotations \"tag=$IMAGE_TAG\" \\\n    --certificate-identity \"$CI_PROJECT_URL//.gitlab-ci.yml@refs/heads/$CI_COMMIT_REF_NAME\" \\\n    --certificate-oidc-issuer \"$CI_SERVER_URL\" \\\n    \"$IMAGE_URI\" | jq .\n```\n\nThis command verifies the signature and checks the annotations. Its output will show all the annotations we've added to the image during the signing process.\n\nHere's what you might see in your pipeline logs after running this command:\n\n![verifying the signature and checking annotations](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098404/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098404260.png)\n\nIn this output, you should see all the annotations we added earlier, including:\n\n* GitLab CI user name\n* Pipeline ID and URL\n* Job ID and URL\n* Commit SHA and reference name\n* Project path\n* Image source and revision\n\nBy verifying these annotations, you can ensure that the image's provenance data is intact and matches what you expect based on your build process. This verification step is crucial for maintaining the integrity of your software supply chain. It allows you to confirm that the image you're about to deploy has gone through your secure build process and has yet to be modified since it was signed.\n\n## Summary\n\nBy integrating Cosign into your GitLab CI/CD pipeline, you've taken a significant step toward securing your software supply chain. This setup not only automates securing and annotating your container images with build metadata but also ensures a transparent and traceable build process.\n\nThe benefits of this approach are numerous:\n\n- enhanced security through image signing\n- improved traceability with detailed build provenance data\n- automated verification process\n- alignment with DevSecOps best practices\n\nAs container security continues to be a critical concern in the software development lifecycle, implementing these practices puts you ahead of potential security threats and demonstrates a commitment to software integrity.\n\n## Try it in your organization\n\nNow that you've seen how to enhance your container security using Cosign in GitLab CI/CD, it's time to put this knowledge into practice:\n\n1. **Implement in your projects**: Adapt the provided `.gitlab-ci.yml` file to fit your specific needs.\n2. **Explore further**: Dive deeper into Cosign's capabilities. Consider exploring advanced features like policy enforcement or integration with vulnerability scanning tools.\n3. **Share your experience**: After implementing this in your projects, share your experience with your team or the wider GitLab community. Your insights could help others enhance their security practices.\n4. **Stay updated**: Container security is an evolving field. Check GitLab's blog and documentation for new features and best practices updates.\n5. **Contribute**: If you find ways to improve this process or encounter any issues, consider contributing to the GitLab or Cosign open-source projects.\n\nRemember, security is a journey, not a destination. By taking these steps, you're securing your containers and contributing to a more secure software ecosystem for everyone.\n\nStart implementing these practices in your GitLab projects today, and take your container security to the next level!\n\n> Get started today! Sign up for a [free 30-day trial of GitLab Ultimate](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/blog&glm_content=default-saas-trial)!\n\n## Read more\n\n- [Next-generation GitLab container registry goes GA](https://about.gitlab.com/blog/next-generation-gitlab-container-registry-goes-ga/)\n- [A beginner's guide to container security](https://about.gitlab.com/topics/devsecops/beginners-guide-to-container-security/)\n- [DevSecOps basics, including security](https://about.gitlab.com/topics/devsecops/)\n- [What is CI/CD?](https://about.gitlab.com/topics/ci-cd/)\n","security",[23,25,26,27],"tutorial","product","features",{"slug":29,"featured":6,"template":30},"annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd","BlogPost","content:en-us:blog:annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd.yml","yaml","Annotate Container Images With Build Provenance Using Cosign In Gitlab Ci Cd","content","en-us/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd.yml","en-us/blog/annotate-container-images-with-build-provenance-using-cosign-in-gitlab-ci-cd","yml",{"_path":39,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":41,"_id":451,"_type":32,"title":452,"_source":34,"_file":453,"_stem":454,"_extension":37},"/shared/en-us/main-navigation","en-us",{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":392,"minimal":423,"duo":442},{"config":43},{"href":44,"dataGaName":45,"dataGaLocation":46},"/","gitlab logo","header",{"text":48,"config":49},"Get free trial",{"href":50,"dataGaName":51,"dataGaLocation":46},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":53,"config":54},"Talk to sales",{"href":55,"dataGaName":56,"dataGaLocation":46},"/sales/","sales",{"text":58,"config":59},"Sign in",{"href":60,"dataGaName":61,"dataGaLocation":46},"https://gitlab.com/users/sign_in/","sign in",[63,107,203,208,313,373],{"text":64,"config":65,"cards":67,"footer":90},"Platform",{"dataNavLevelOne":66},"platform",[68,74,82],{"title":64,"description":69,"link":70},"The most comprehensive AI-powered DevSecOps Platform",{"text":71,"config":72},"Explore our Platform",{"href":73,"dataGaName":66,"dataGaLocation":46},"/platform/",{"title":75,"description":76,"link":77},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":78,"config":79},"Meet GitLab Duo",{"href":80,"dataGaName":81,"dataGaLocation":46},"/gitlab-duo/","gitlab duo ai",{"title":83,"description":84,"link":85},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":86,"config":87},"Learn more",{"href":88,"dataGaName":89,"dataGaLocation":46},"/why-gitlab/","why gitlab",{"title":91,"items":92},"Get started with",[93,98,103],{"text":94,"config":95},"Platform Engineering",{"href":96,"dataGaName":97,"dataGaLocation":46},"/solutions/platform-engineering/","platform engineering",{"text":99,"config":100},"Developer Experience",{"href":101,"dataGaName":102,"dataGaLocation":46},"/developer-experience/","Developer experience",{"text":104,"config":105},"MLOps",{"href":106,"dataGaName":104,"dataGaLocation":46},"/topics/devops/the-role-of-ai-in-devops/",{"text":108,"left":109,"config":110,"link":112,"lists":116,"footer":185},"Product",true,{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"View all Solutions",{"href":115,"dataGaName":111,"dataGaLocation":46},"/solutions/",[117,142,164],{"title":118,"description":119,"link":120,"items":125},"Automation","CI/CD and automation to accelerate deployment",{"config":121},{"icon":122,"href":123,"dataGaName":124,"dataGaLocation":46},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[126,130,134,138],{"text":127,"config":128},"CI/CD",{"href":129,"dataGaLocation":46,"dataGaName":127},"/solutions/continuous-integration/",{"text":131,"config":132},"AI-Assisted Development",{"href":80,"dataGaLocation":46,"dataGaName":133},"AI assisted development",{"text":135,"config":136},"Source Code Management",{"href":137,"dataGaLocation":46,"dataGaName":135},"/solutions/source-code-management/",{"text":139,"config":140},"Automated Software Delivery",{"href":123,"dataGaLocation":46,"dataGaName":141},"Automated software delivery",{"title":143,"description":144,"link":145,"items":150},"Security","Deliver code faster without compromising security",{"config":146},{"href":147,"dataGaName":148,"dataGaLocation":46,"icon":149},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[151,154,159],{"text":152,"config":153},"Security & Compliance",{"href":147,"dataGaLocation":46,"dataGaName":152},{"text":155,"config":156},"Software Supply Chain Security",{"href":157,"dataGaLocation":46,"dataGaName":158},"/solutions/supply-chain/","Software supply chain security",{"text":160,"config":161},"Compliance & Governance",{"href":162,"dataGaLocation":46,"dataGaName":163},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":165,"link":166,"items":171},"Measurement",{"config":167},{"icon":168,"href":169,"dataGaName":170,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[172,176,180],{"text":173,"config":174},"Visibility & Measurement",{"href":169,"dataGaLocation":46,"dataGaName":175},"Visibility and Measurement",{"text":177,"config":178},"Value Stream Management",{"href":179,"dataGaLocation":46,"dataGaName":177},"/solutions/value-stream-management/",{"text":181,"config":182},"Analytics & Insights",{"href":183,"dataGaLocation":46,"dataGaName":184},"/solutions/analytics-and-insights/","Analytics and insights",{"title":186,"items":187},"GitLab for",[188,193,198],{"text":189,"config":190},"Enterprise",{"href":191,"dataGaLocation":46,"dataGaName":192},"/enterprise/","enterprise",{"text":194,"config":195},"Small Business",{"href":196,"dataGaLocation":46,"dataGaName":197},"/small-business/","small business",{"text":199,"config":200},"Public Sector",{"href":201,"dataGaLocation":46,"dataGaName":202},"/solutions/public-sector/","public sector",{"text":204,"config":205},"Pricing",{"href":206,"dataGaName":207,"dataGaLocation":46,"dataNavLevelOne":207},"/pricing/","pricing",{"text":209,"config":210,"link":212,"lists":216,"feature":300},"Resources",{"dataNavLevelOne":211},"resources",{"text":213,"config":214},"View all resources",{"href":215,"dataGaName":211,"dataGaLocation":46},"/resources/",[217,250,272],{"title":218,"items":219},"Getting started",[220,225,230,235,240,245],{"text":221,"config":222},"Install",{"href":223,"dataGaName":224,"dataGaLocation":46},"/install/","install",{"text":226,"config":227},"Quick start guides",{"href":228,"dataGaName":229,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":231,"config":232},"Learn",{"href":233,"dataGaLocation":46,"dataGaName":234},"https://university.gitlab.com/","learn",{"text":236,"config":237},"Product documentation",{"href":238,"dataGaName":239,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":241,"config":242},"Best practice videos",{"href":243,"dataGaName":244,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":246,"config":247},"Integrations",{"href":248,"dataGaName":249,"dataGaLocation":46},"/integrations/","integrations",{"title":251,"items":252},"Discover",[253,258,262,267],{"text":254,"config":255},"Customer success stories",{"href":256,"dataGaName":257,"dataGaLocation":46},"/customers/","customer success stories",{"text":259,"config":260},"Blog",{"href":261,"dataGaName":5,"dataGaLocation":46},"/blog/",{"text":263,"config":264},"Remote",{"href":265,"dataGaName":266,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":268,"config":269},"TeamOps",{"href":270,"dataGaName":271,"dataGaLocation":46},"/teamops/","teamops",{"title":273,"items":274},"Connect",[275,280,285,290,295],{"text":276,"config":277},"GitLab Services",{"href":278,"dataGaName":279,"dataGaLocation":46},"/services/","services",{"text":281,"config":282},"Community",{"href":283,"dataGaName":284,"dataGaLocation":46},"/community/","community",{"text":286,"config":287},"Forum",{"href":288,"dataGaName":289,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":291,"config":292},"Events",{"href":293,"dataGaName":294,"dataGaLocation":46},"/events/","events",{"text":296,"config":297},"Partners",{"href":298,"dataGaName":299,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":301,"textColor":302,"text":303,"image":304,"link":308},"#2f2a6b","#fff","Insights for the future of software development",{"altText":305,"config":306},"the source promo card",{"src":307},"/images/navigation/the-source-promo-card.svg",{"text":309,"config":310},"Read the latest",{"href":311,"dataGaName":312,"dataGaLocation":46},"/the-source/","the source",{"text":314,"config":315,"lists":317},"Company",{"dataNavLevelOne":316},"company",[318],{"items":319},[320,325,331,333,338,343,348,353,358,363,368],{"text":321,"config":322},"About",{"href":323,"dataGaName":324,"dataGaLocation":46},"/company/","about",{"text":326,"config":327,"footerGa":330},"Jobs",{"href":328,"dataGaName":329,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":329},{"text":291,"config":332},{"href":293,"dataGaName":294,"dataGaLocation":46},{"text":334,"config":335},"Leadership",{"href":336,"dataGaName":337,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":339,"config":340},"Team",{"href":341,"dataGaName":342,"dataGaLocation":46},"/company/team/","team",{"text":344,"config":345},"Handbook",{"href":346,"dataGaName":347,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":349,"config":350},"Investor relations",{"href":351,"dataGaName":352,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":354,"config":355},"Trust Center",{"href":356,"dataGaName":357,"dataGaLocation":46},"/security/","trust center",{"text":359,"config":360},"AI Transparency Center",{"href":361,"dataGaName":362,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":364,"config":365},"Newsletter",{"href":366,"dataGaName":367,"dataGaLocation":46},"/company/contact/","newsletter",{"text":369,"config":370},"Press",{"href":371,"dataGaName":372,"dataGaLocation":46},"/press/","press",{"text":374,"config":375,"lists":376},"Contact us",{"dataNavLevelOne":316},[377],{"items":378},[379,382,387],{"text":53,"config":380},{"href":55,"dataGaName":381,"dataGaLocation":46},"talk to sales",{"text":383,"config":384},"Get help",{"href":385,"dataGaName":386,"dataGaLocation":46},"/support/","get help",{"text":388,"config":389},"Customer portal",{"href":390,"dataGaName":391,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":393,"login":394,"suggestions":401},"Close",{"text":395,"link":396},"To search repositories and projects, login to",{"text":397,"config":398},"gitlab.com",{"href":60,"dataGaName":399,"dataGaLocation":400},"search login","search",{"text":402,"default":403},"Suggestions",[404,406,410,412,416,420],{"text":75,"config":405},{"href":80,"dataGaName":75,"dataGaLocation":400},{"text":407,"config":408},"Code Suggestions (AI)",{"href":409,"dataGaName":407,"dataGaLocation":400},"/solutions/code-suggestions/",{"text":127,"config":411},{"href":129,"dataGaName":127,"dataGaLocation":400},{"text":413,"config":414},"GitLab on AWS",{"href":415,"dataGaName":413,"dataGaLocation":400},"/partners/technology-partners/aws/",{"text":417,"config":418},"GitLab on Google Cloud",{"href":419,"dataGaName":417,"dataGaLocation":400},"/partners/technology-partners/google-cloud-platform/",{"text":421,"config":422},"Why GitLab?",{"href":88,"dataGaName":421,"dataGaLocation":400},{"freeTrial":424,"mobileIcon":429,"desktopIcon":434,"secondaryButton":437},{"text":425,"config":426},"Start free trial",{"href":427,"dataGaName":51,"dataGaLocation":428},"https://gitlab.com/-/trials/new/","nav",{"altText":430,"config":431},"Gitlab Icon",{"src":432,"dataGaName":433,"dataGaLocation":428},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":430,"config":435},{"src":436,"dataGaName":433,"dataGaLocation":428},"/images/brand/gitlab-logo-type.svg",{"text":438,"config":439},"Get Started",{"href":440,"dataGaName":441,"dataGaLocation":428},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":443,"mobileIcon":447,"desktopIcon":449},{"text":444,"config":445},"Learn more about GitLab Duo",{"href":80,"dataGaName":446,"dataGaLocation":428},"gitlab duo",{"altText":430,"config":448},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":450},{"src":436,"dataGaName":433,"dataGaLocation":428},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":456,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"title":457,"button":458,"config":462,"_id":464,"_type":32,"_source":34,"_file":465,"_stem":466,"_extension":37},"/shared/en-us/banner","GitLab Duo Agent Platform is now in public beta!",{"text":86,"config":459},{"href":460,"dataGaName":461,"dataGaLocation":46},"/gitlab-duo/agent-platform/","duo banner",{"layout":463},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":468,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":469,"_id":674,"_type":32,"title":675,"_source":34,"_file":676,"_stem":677,"_extension":37},"/shared/en-us/main-footer",{"text":470,"source":471,"edit":477,"contribute":482,"config":487,"items":492,"minimal":666},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":472,"config":473},"View page source",{"href":474,"dataGaName":475,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":478,"config":479},"Edit this page",{"href":480,"dataGaName":481,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":483,"config":484},"Please contribute",{"href":485,"dataGaName":486,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":488,"facebook":489,"youtube":490,"linkedin":491},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[493,516,573,602,636],{"title":64,"links":494,"subMenu":499},[495],{"text":496,"config":497},"DevSecOps platform",{"href":73,"dataGaName":498,"dataGaLocation":476},"devsecops platform",[500],{"title":204,"links":501},[502,506,511],{"text":503,"config":504},"View plans",{"href":206,"dataGaName":505,"dataGaLocation":476},"view plans",{"text":507,"config":508},"Why Premium?",{"href":509,"dataGaName":510,"dataGaLocation":476},"/pricing/premium/","why premium",{"text":512,"config":513},"Why Ultimate?",{"href":514,"dataGaName":515,"dataGaLocation":476},"/pricing/ultimate/","why ultimate",{"title":517,"links":518},"Solutions",[519,524,527,529,534,539,543,546,550,555,557,560,563,568],{"text":520,"config":521},"Digital transformation",{"href":522,"dataGaName":523,"dataGaLocation":476},"/topics/digital-transformation/","digital transformation",{"text":152,"config":525},{"href":147,"dataGaName":526,"dataGaLocation":476},"security & compliance",{"text":141,"config":528},{"href":123,"dataGaName":124,"dataGaLocation":476},{"text":530,"config":531},"Agile development",{"href":532,"dataGaName":533,"dataGaLocation":476},"/solutions/agile-delivery/","agile delivery",{"text":535,"config":536},"Cloud transformation",{"href":537,"dataGaName":538,"dataGaLocation":476},"/topics/cloud-native/","cloud transformation",{"text":540,"config":541},"SCM",{"href":137,"dataGaName":542,"dataGaLocation":476},"source code management",{"text":127,"config":544},{"href":129,"dataGaName":545,"dataGaLocation":476},"continuous integration & delivery",{"text":547,"config":548},"Value stream management",{"href":179,"dataGaName":549,"dataGaLocation":476},"value stream management",{"text":551,"config":552},"GitOps",{"href":553,"dataGaName":554,"dataGaLocation":476},"/solutions/gitops/","gitops",{"text":189,"config":556},{"href":191,"dataGaName":192,"dataGaLocation":476},{"text":558,"config":559},"Small business",{"href":196,"dataGaName":197,"dataGaLocation":476},{"text":561,"config":562},"Public sector",{"href":201,"dataGaName":202,"dataGaLocation":476},{"text":564,"config":565},"Education",{"href":566,"dataGaName":567,"dataGaLocation":476},"/solutions/education/","education",{"text":569,"config":570},"Financial services",{"href":571,"dataGaName":572,"dataGaLocation":476},"/solutions/finance/","financial services",{"title":209,"links":574},[575,577,579,581,584,586,588,590,592,594,596,598,600],{"text":221,"config":576},{"href":223,"dataGaName":224,"dataGaLocation":476},{"text":226,"config":578},{"href":228,"dataGaName":229,"dataGaLocation":476},{"text":231,"config":580},{"href":233,"dataGaName":234,"dataGaLocation":476},{"text":236,"config":582},{"href":238,"dataGaName":583,"dataGaLocation":476},"docs",{"text":259,"config":585},{"href":261,"dataGaName":5,"dataGaLocation":476},{"text":254,"config":587},{"href":256,"dataGaName":257,"dataGaLocation":476},{"text":263,"config":589},{"href":265,"dataGaName":266,"dataGaLocation":476},{"text":276,"config":591},{"href":278,"dataGaName":279,"dataGaLocation":476},{"text":268,"config":593},{"href":270,"dataGaName":271,"dataGaLocation":476},{"text":281,"config":595},{"href":283,"dataGaName":284,"dataGaLocation":476},{"text":286,"config":597},{"href":288,"dataGaName":289,"dataGaLocation":476},{"text":291,"config":599},{"href":293,"dataGaName":294,"dataGaLocation":476},{"text":296,"config":601},{"href":298,"dataGaName":299,"dataGaLocation":476},{"title":314,"links":603},[604,606,608,610,612,614,616,620,625,627,629,631],{"text":321,"config":605},{"href":323,"dataGaName":316,"dataGaLocation":476},{"text":326,"config":607},{"href":328,"dataGaName":329,"dataGaLocation":476},{"text":334,"config":609},{"href":336,"dataGaName":337,"dataGaLocation":476},{"text":339,"config":611},{"href":341,"dataGaName":342,"dataGaLocation":476},{"text":344,"config":613},{"href":346,"dataGaName":347,"dataGaLocation":476},{"text":349,"config":615},{"href":351,"dataGaName":352,"dataGaLocation":476},{"text":617,"config":618},"Sustainability",{"href":619,"dataGaName":617,"dataGaLocation":476},"/sustainability/",{"text":621,"config":622},"Diversity, inclusion and belonging (DIB)",{"href":623,"dataGaName":624,"dataGaLocation":476},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":626},{"href":356,"dataGaName":357,"dataGaLocation":476},{"text":364,"config":628},{"href":366,"dataGaName":367,"dataGaLocation":476},{"text":369,"config":630},{"href":371,"dataGaName":372,"dataGaLocation":476},{"text":632,"config":633},"Modern Slavery Transparency Statement",{"href":634,"dataGaName":635,"dataGaLocation":476},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":637,"links":638},"Contact Us",[639,642,644,646,651,656,661],{"text":640,"config":641},"Contact an expert",{"href":55,"dataGaName":56,"dataGaLocation":476},{"text":383,"config":643},{"href":385,"dataGaName":386,"dataGaLocation":476},{"text":388,"config":645},{"href":390,"dataGaName":391,"dataGaLocation":476},{"text":647,"config":648},"Status",{"href":649,"dataGaName":650,"dataGaLocation":476},"https://status.gitlab.com/","status",{"text":652,"config":653},"Terms of use",{"href":654,"dataGaName":655,"dataGaLocation":476},"/terms/","terms of use",{"text":657,"config":658},"Privacy statement",{"href":659,"dataGaName":660,"dataGaLocation":476},"/privacy/","privacy statement",{"text":662,"config":663},"Cookie preferences",{"dataGaName":664,"dataGaLocation":476,"id":665,"isOneTrustButton":109},"cookie preferences","ot-sdk-btn",{"items":667},[668,670,672],{"text":652,"config":669},{"href":654,"dataGaName":655,"dataGaLocation":476},{"text":657,"config":671},{"href":659,"dataGaName":660,"dataGaLocation":476},{"text":662,"config":673},{"dataGaName":664,"dataGaLocation":476,"id":665,"isOneTrustButton":109},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[679,692],{"_path":680,"_dir":681,"_draft":6,"_partial":6,"_locale":7,"content":682,"config":686,"_id":688,"_type":32,"title":689,"_source":34,"_file":690,"_stem":691,"_extension":37},"/en-us/blog/authors/joo-pereira","authors",{"name":19,"config":683},{"headshot":684,"ctfId":685},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665547/Blog/Author%20Headshots/joao_pereira.png","7wLh5rwID5R39PRA6aiAb0",{"template":687},"BlogAuthor","content:en-us:blog:authors:joo-pereira.yml","Joo Pereira","en-us/blog/authors/joo-pereira.yml","en-us/blog/authors/joo-pereira",{"_path":693,"_dir":681,"_draft":6,"_partial":6,"_locale":7,"content":694,"config":698,"_id":699,"_type":32,"title":20,"_source":34,"_file":700,"_stem":701,"_extension":37},"/en-us/blog/authors/tim-rizzi",{"name":20,"config":695},{"headshot":696,"ctfId":697},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661866/Blog/Author%20Headshots/trizzi-headshot.jpg","trizzi",{"template":687},"content:en-us:blog:authors:tim-rizzi.yml","en-us/blog/authors/tim-rizzi.yml","en-us/blog/authors/tim-rizzi",{"_path":703,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"header":704,"eyebrow":705,"blurb":706,"button":707,"secondaryButton":711,"_id":713,"_type":32,"title":714,"_source":34,"_file":715,"_stem":716,"_extension":37},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":48,"config":708},{"href":709,"dataGaName":51,"dataGaLocation":710},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":53,"config":712},{"href":55,"dataGaName":56,"dataGaLocation":710},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1753475312723]