[{"data":1,"prerenderedAt":733},["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":467,"footer-en-us":484,"João Pereira-Tim Rizzi":694,"next-steps-en-us":718},{"_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\norganizations increasingly rely on containerized applications, ensuring the\nintegrity and traceability of container images is paramount. Enhancing the\nsecurity and traceability of your container images directly in your GitLab\nCI/CD pipeline can streamline your development process while significantly\nboosting your security posture.\n\n\nThis tutorial demonstrates setting up a GitLab pipeline to automate the\nprocess of building, signing, and annotating Docker images using Cosign and\nthe GitLab container registry. By integrating these practices, you'll secure\nyour images and ensure that each one is easily traceable, aligning with best\npractices in DevSecOps.\n\n\n## Background on container image security\n\n\nBefore we dive into the technical details, it's crucial to understand why\ncontainer image security is so important. In\n[microservices](https://about.gitlab.com/topics/microservices/) and\ncloud-native applications, containers have become the standard for packaging\nand deploying software. However, this widespread adoption has also made\ncontainers an attractive target for cyber attacks.\n\n\nContainer image security is a vital component of the broader [software\nsupply chain\nsecurity](https://about.gitlab.com/blog/the-ultimate-guide-to-software-supply-chain-security/)\nconcept. This encompasses all the tools, processes, and practices that\nensure your software's integrity, authenticity, and security from\ndevelopment to deployment. By securing your container images, you're\nprotecting your application and your entire software supply chain.\n\n\n## Introduction to Cosign\n\n\nEnter\n[Cosign](https://about.gitlab.com/blog/keyless-signing-with-cosign/),\na tool designed to address these security concerns. Cosign is part of the\nSigstore project, an open-source initiative aimed at improving the security\nof the software supply chain. Cosign allows developers to sign and verify\ncontainer images, ensuring their integrity and authenticity.\n\n\nKey benefits of Cosign include:\n\n\n- easy integration with existing CI/CD pipelines\n\n- support for various signing methods, including keyless signing\n\n- ability to attach and verify arbitrary metadata to container images\n\n\nBy incorporating Cosign into your GitLab CI/CD pipeline, you're taking a\nsignificant step towards robust\n[DevSecOps](https://about.gitlab.com/topics/devsecops/) practices.\n\n\n## Benefits of image signing and annotation\n\n\nImage signing serves as a seal of authenticity for your container images. It\nhelps prevent tampering and ensures that the image deployed in your\nproduction environment is precisely the one that passed through your secure\nbuild process.\n\n\nAnnotations, on the other hand, provide valuable metadata about the build\nprocess. This information is used for auditing and traceability. In a\nsecurity incident, having detailed provenance data can significantly speed\nup the investigation and remediation process.\n\n\n## GitLab CI/CD pipeline configuration\n\n\nLet's look at an example `.gitlab-ci.yml` file that outlines the process of\nbuilding, signing, and annotating a Docker image using Cosign:\n\n\n```yaml\n\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\n\nLet's break down this pipeline configuration and understand each part in\ndetail.\n\n\n## Detailed explanation of the pipeline\n\n\n### 1. Setup and prerequisites\n\n\nThe pipeline starts by setting up the necessary environment:\n\n\n* It uses the `docker:latest` image and enables Docker-in-Docker service,\nallowing Docker commands to be run within the CI job.\n\n* It defines variables for the image tag and URI using GitLab CI/CD\npredefined variables.\n\n* It sets up an OIDC token for keyless signing with Cosign.\n\n* In the `before_script` section, it installs Cosign and jq (for JSON\nprocessing) and logs into the GitLab container registry.\n\n\n### 2. Building and pushing the image\n\n\nThe first step in the script is to build the Docker image and push it to the\nGitLab container registry:\n\n\n```yaml\n\n- docker build --pull -t \"$IMAGE_URI\" .\n\n- docker push \"$IMAGE_URI\"\n\n```\n\n\nThis creates the image using the current directory's Dockerfile and pushes\nit to the registry.\n\n\n### 3. Signing the image with Cosign\n\n\nAfter building and pushing the image, the pipeline signs it using Cosign:\n\n\n```yaml\n\n- IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}'\n\"$IMAGE_URI\")\n\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\n\nThis step first retrieves the image digest and then uses Cosign to sign the\nimage, adding several annotations.\n\n\n## Verifying the signature and annotations\n\n\nAfter signing the image, it's crucial to verify the signature and the\nannotations we've added. This verification step ensures that the provenance\ndata attached to the image is correct and hasn't been tampered with.\n\n\nIn our pipeline, we've included a verification step using the `cosign\nverify` command:\n\n\n```yaml\n\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\n\nThis command verifies the signature and checks the annotations. Its output\nwill show all the annotations we've added to the image during the signing\nprocess.\n\n\nHere's what you might see in your pipeline logs after running this command:\n\n\n![verifying the signature and checking\nannotations](https://res.cloudinary.com/about-gitlab-com/image/upload/v1750098404/Blog/Content%20Images/Blog/Content%20Images/image1_aHR0cHM6_1750098404260.png)\n\n\nIn this output, you should see all the annotations we added earlier,\nincluding:\n\n\n* GitLab CI user name\n\n* Pipeline ID and URL\n\n* Job ID and URL\n\n* Commit SHA and reference name\n\n* Project path\n\n* Image source and revision\n\n\nBy verifying these annotations, you can ensure that the image's provenance\ndata is intact and matches what you expect based on your build process. This\nverification step is crucial for maintaining the integrity of your software\nsupply chain. It allows you to confirm that the image you're about to deploy\nhas gone through your secure build process and has yet to be modified since\nit was signed.\n\n\n## Summary\n\n\nBy integrating Cosign into your GitLab CI/CD pipeline, you've taken a\nsignificant step toward securing your software supply chain. This setup not\nonly automates securing and annotating your container images with build\nmetadata but also ensures a transparent and traceable build process.\n\n\nThe benefits of this approach are numerous:\n\n\n- enhanced security through image signing\n\n- improved traceability with detailed build provenance data\n\n- automated verification process\n\n- alignment with DevSecOps best practices\n\n\nAs container security continues to be a critical concern in the software\ndevelopment lifecycle, implementing these practices puts you ahead of\npotential security threats and demonstrates a commitment to software\nintegrity.\n\n\n## Try it in your organization\n\n\nNow that you've seen how to enhance your container security using Cosign in\nGitLab CI/CD, it's time to put this knowledge into practice:\n\n\n1. **Implement in your projects**: Adapt the provided `.gitlab-ci.yml` file\nto fit your specific needs.\n\n2. **Explore further**: Dive deeper into Cosign's capabilities. Consider\nexploring advanced features like policy enforcement or integration with\nvulnerability scanning tools.\n\n3. **Share your experience**: After implementing this in your projects,\nshare your experience with your team or the wider GitLab community. Your\ninsights could help others enhance their security practices.\n\n4. **Stay updated**: Container security is an evolving field. Check GitLab's\nblog and documentation for new features and best practices updates.\n\n5. **Contribute**: If you find ways to improve this process or encounter any\nissues, consider contributing to the GitLab or Cosign open-source projects.\n\n\nRemember, security is a journey, not a destination. By taking these steps,\nyou're securing your containers and contributing to a more secure software\necosystem for everyone.\n\n\nStart implementing these practices in your GitLab projects today, and take\nyour container security to the next level!\n\n\n> Get started today! Sign up for a [free trial of GitLab\nUltimate](https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/blog&glm_content=default-saas-trial)!\n\n\n## Read more\n\n\n- [Next-generation GitLab container registry goes\nGA](https://about.gitlab.com/blog/next-generation-gitlab-container-registry-goes-ga/)\n\n- [A beginner's guide to container\nsecurity](https://about.gitlab.com/topics/devsecops/beginners-guide-to-container-security/)\n\n- [DevSecOps basics, including\nsecurity](https://about.gitlab.com/topics/devsecops/)\n\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":463,"_type":32,"title":464,"_source":34,"_file":465,"_stem":466,"_extension":37},"/shared/en-us/main-navigation","en-us",{"logo":42,"freeTrial":47,"sales":52,"login":57,"items":62,"search":394,"minimal":425,"duo":444,"pricingDeployment":453},{"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,205,210,315,375],{"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":187},"Product",true,{"dataNavLevelOne":111},"solutions",{"text":113,"config":114},"View all Solutions",{"href":115,"dataGaName":111,"dataGaLocation":46},"/solutions/",[117,142,166],{"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,156,161],{"text":152,"config":153},"Application Security Testing",{"href":154,"dataGaName":155,"dataGaLocation":46},"/solutions/application-security-testing/","Application security testing",{"text":157,"config":158},"Software Supply Chain Security",{"href":159,"dataGaLocation":46,"dataGaName":160},"/solutions/supply-chain/","Software supply chain security",{"text":162,"config":163},"Software Compliance",{"href":164,"dataGaName":165,"dataGaLocation":46},"/solutions/software-compliance/","software compliance",{"title":167,"link":168,"items":173},"Measurement",{"config":169},{"icon":170,"href":171,"dataGaName":172,"dataGaLocation":46},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[174,178,182],{"text":175,"config":176},"Visibility & Measurement",{"href":171,"dataGaLocation":46,"dataGaName":177},"Visibility and Measurement",{"text":179,"config":180},"Value Stream Management",{"href":181,"dataGaLocation":46,"dataGaName":179},"/solutions/value-stream-management/",{"text":183,"config":184},"Analytics & Insights",{"href":185,"dataGaLocation":46,"dataGaName":186},"/solutions/analytics-and-insights/","Analytics and insights",{"title":188,"items":189},"GitLab for",[190,195,200],{"text":191,"config":192},"Enterprise",{"href":193,"dataGaLocation":46,"dataGaName":194},"/enterprise/","enterprise",{"text":196,"config":197},"Small Business",{"href":198,"dataGaLocation":46,"dataGaName":199},"/small-business/","small business",{"text":201,"config":202},"Public Sector",{"href":203,"dataGaLocation":46,"dataGaName":204},"/solutions/public-sector/","public sector",{"text":206,"config":207},"Pricing",{"href":208,"dataGaName":209,"dataGaLocation":46,"dataNavLevelOne":209},"/pricing/","pricing",{"text":211,"config":212,"link":214,"lists":218,"feature":302},"Resources",{"dataNavLevelOne":213},"resources",{"text":215,"config":216},"View all resources",{"href":217,"dataGaName":213,"dataGaLocation":46},"/resources/",[219,252,274],{"title":220,"items":221},"Getting started",[222,227,232,237,242,247],{"text":223,"config":224},"Install",{"href":225,"dataGaName":226,"dataGaLocation":46},"/install/","install",{"text":228,"config":229},"Quick start guides",{"href":230,"dataGaName":231,"dataGaLocation":46},"/get-started/","quick setup checklists",{"text":233,"config":234},"Learn",{"href":235,"dataGaLocation":46,"dataGaName":236},"https://university.gitlab.com/","learn",{"text":238,"config":239},"Product documentation",{"href":240,"dataGaName":241,"dataGaLocation":46},"https://docs.gitlab.com/","product documentation",{"text":243,"config":244},"Best practice videos",{"href":245,"dataGaName":246,"dataGaLocation":46},"/getting-started-videos/","best practice videos",{"text":248,"config":249},"Integrations",{"href":250,"dataGaName":251,"dataGaLocation":46},"/integrations/","integrations",{"title":253,"items":254},"Discover",[255,260,264,269],{"text":256,"config":257},"Customer success stories",{"href":258,"dataGaName":259,"dataGaLocation":46},"/customers/","customer success stories",{"text":261,"config":262},"Blog",{"href":263,"dataGaName":5,"dataGaLocation":46},"/blog/",{"text":265,"config":266},"Remote",{"href":267,"dataGaName":268,"dataGaLocation":46},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":270,"config":271},"TeamOps",{"href":272,"dataGaName":273,"dataGaLocation":46},"/teamops/","teamops",{"title":275,"items":276},"Connect",[277,282,287,292,297],{"text":278,"config":279},"GitLab Services",{"href":280,"dataGaName":281,"dataGaLocation":46},"/services/","services",{"text":283,"config":284},"Community",{"href":285,"dataGaName":286,"dataGaLocation":46},"/community/","community",{"text":288,"config":289},"Forum",{"href":290,"dataGaName":291,"dataGaLocation":46},"https://forum.gitlab.com/","forum",{"text":293,"config":294},"Events",{"href":295,"dataGaName":296,"dataGaLocation":46},"/events/","events",{"text":298,"config":299},"Partners",{"href":300,"dataGaName":301,"dataGaLocation":46},"/partners/","partners",{"backgroundColor":303,"textColor":304,"text":305,"image":306,"link":310},"#2f2a6b","#fff","Insights for the future of software development",{"altText":307,"config":308},"the source promo card",{"src":309},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":311,"config":312},"Read the latest",{"href":313,"dataGaName":314,"dataGaLocation":46},"/the-source/","the source",{"text":316,"config":317,"lists":319},"Company",{"dataNavLevelOne":318},"company",[320],{"items":321},[322,327,333,335,340,345,350,355,360,365,370],{"text":323,"config":324},"About",{"href":325,"dataGaName":326,"dataGaLocation":46},"/company/","about",{"text":328,"config":329,"footerGa":332},"Jobs",{"href":330,"dataGaName":331,"dataGaLocation":46},"/jobs/","jobs",{"dataGaName":331},{"text":293,"config":334},{"href":295,"dataGaName":296,"dataGaLocation":46},{"text":336,"config":337},"Leadership",{"href":338,"dataGaName":339,"dataGaLocation":46},"/company/team/e-group/","leadership",{"text":341,"config":342},"Team",{"href":343,"dataGaName":344,"dataGaLocation":46},"/company/team/","team",{"text":346,"config":347},"Handbook",{"href":348,"dataGaName":349,"dataGaLocation":46},"https://handbook.gitlab.com/","handbook",{"text":351,"config":352},"Investor relations",{"href":353,"dataGaName":354,"dataGaLocation":46},"https://ir.gitlab.com/","investor relations",{"text":356,"config":357},"Trust Center",{"href":358,"dataGaName":359,"dataGaLocation":46},"/security/","trust center",{"text":361,"config":362},"AI Transparency Center",{"href":363,"dataGaName":364,"dataGaLocation":46},"/ai-transparency-center/","ai transparency center",{"text":366,"config":367},"Newsletter",{"href":368,"dataGaName":369,"dataGaLocation":46},"/company/contact/","newsletter",{"text":371,"config":372},"Press",{"href":373,"dataGaName":374,"dataGaLocation":46},"/press/","press",{"text":376,"config":377,"lists":378},"Contact us",{"dataNavLevelOne":318},[379],{"items":380},[381,384,389],{"text":53,"config":382},{"href":55,"dataGaName":383,"dataGaLocation":46},"talk to sales",{"text":385,"config":386},"Get help",{"href":387,"dataGaName":388,"dataGaLocation":46},"/support/","get help",{"text":390,"config":391},"Customer portal",{"href":392,"dataGaName":393,"dataGaLocation":46},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":395,"login":396,"suggestions":403},"Close",{"text":397,"link":398},"To search repositories and projects, login to",{"text":399,"config":400},"gitlab.com",{"href":60,"dataGaName":401,"dataGaLocation":402},"search login","search",{"text":404,"default":405},"Suggestions",[406,408,412,414,418,422],{"text":75,"config":407},{"href":80,"dataGaName":75,"dataGaLocation":402},{"text":409,"config":410},"Code Suggestions (AI)",{"href":411,"dataGaName":409,"dataGaLocation":402},"/solutions/code-suggestions/",{"text":127,"config":413},{"href":129,"dataGaName":127,"dataGaLocation":402},{"text":415,"config":416},"GitLab on AWS",{"href":417,"dataGaName":415,"dataGaLocation":402},"/partners/technology-partners/aws/",{"text":419,"config":420},"GitLab on Google Cloud",{"href":421,"dataGaName":419,"dataGaLocation":402},"/partners/technology-partners/google-cloud-platform/",{"text":423,"config":424},"Why GitLab?",{"href":88,"dataGaName":423,"dataGaLocation":402},{"freeTrial":426,"mobileIcon":431,"desktopIcon":436,"secondaryButton":439},{"text":427,"config":428},"Start free trial",{"href":429,"dataGaName":51,"dataGaLocation":430},"https://gitlab.com/-/trials/new/","nav",{"altText":432,"config":433},"Gitlab Icon",{"src":434,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":432,"config":437},{"src":438,"dataGaName":435,"dataGaLocation":430},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":440,"config":441},"Get Started",{"href":442,"dataGaName":443,"dataGaLocation":430},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":445,"mobileIcon":449,"desktopIcon":451},{"text":446,"config":447},"Learn more about GitLab Duo",{"href":80,"dataGaName":448,"dataGaLocation":430},"gitlab duo",{"altText":432,"config":450},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":452},{"src":438,"dataGaName":435,"dataGaLocation":430},{"freeTrial":454,"mobileIcon":459,"desktopIcon":461},{"text":455,"config":456},"Back to pricing",{"href":208,"dataGaName":457,"dataGaLocation":430,"icon":458},"back to pricing","GoBack",{"altText":432,"config":460},{"src":434,"dataGaName":435,"dataGaLocation":430},{"altText":432,"config":462},{"src":438,"dataGaName":435,"dataGaLocation":430},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":468,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"title":469,"button":470,"image":475,"config":479,"_id":481,"_type":32,"_source":34,"_file":482,"_stem":483,"_extension":37},"/shared/en-us/banner","is now in public beta!",{"text":471,"config":472},"Try the Beta",{"href":473,"dataGaName":474,"dataGaLocation":46},"/gitlab-duo/agent-platform/","duo banner",{"altText":476,"config":477},"GitLab Duo Agent Platform",{"src":478},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":480},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":485,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"data":486,"_id":690,"_type":32,"title":691,"_source":34,"_file":692,"_stem":693,"_extension":37},"/shared/en-us/main-footer",{"text":487,"source":488,"edit":494,"contribute":499,"config":504,"items":509,"minimal":682},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":489,"config":490},"View page source",{"href":491,"dataGaName":492,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":495,"config":496},"Edit this page",{"href":497,"dataGaName":498,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":500,"config":501},"Please contribute",{"href":502,"dataGaName":503,"dataGaLocation":493},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":505,"facebook":506,"youtube":507,"linkedin":508},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[510,533,589,618,652],{"title":64,"links":511,"subMenu":516},[512],{"text":513,"config":514},"DevSecOps platform",{"href":73,"dataGaName":515,"dataGaLocation":493},"devsecops platform",[517],{"title":206,"links":518},[519,523,528],{"text":520,"config":521},"View plans",{"href":208,"dataGaName":522,"dataGaLocation":493},"view plans",{"text":524,"config":525},"Why Premium?",{"href":526,"dataGaName":527,"dataGaLocation":493},"/pricing/premium/","why premium",{"text":529,"config":530},"Why Ultimate?",{"href":531,"dataGaName":532,"dataGaLocation":493},"/pricing/ultimate/","why ultimate",{"title":534,"links":535},"Solutions",[536,541,543,545,550,555,559,562,566,571,573,576,579,584],{"text":537,"config":538},"Digital transformation",{"href":539,"dataGaName":540,"dataGaLocation":493},"/topics/digital-transformation/","digital transformation",{"text":152,"config":542},{"href":154,"dataGaName":152,"dataGaLocation":493},{"text":141,"config":544},{"href":123,"dataGaName":124,"dataGaLocation":493},{"text":546,"config":547},"Agile development",{"href":548,"dataGaName":549,"dataGaLocation":493},"/solutions/agile-delivery/","agile delivery",{"text":551,"config":552},"Cloud transformation",{"href":553,"dataGaName":554,"dataGaLocation":493},"/topics/cloud-native/","cloud transformation",{"text":556,"config":557},"SCM",{"href":137,"dataGaName":558,"dataGaLocation":493},"source code management",{"text":127,"config":560},{"href":129,"dataGaName":561,"dataGaLocation":493},"continuous integration & delivery",{"text":563,"config":564},"Value stream management",{"href":181,"dataGaName":565,"dataGaLocation":493},"value stream management",{"text":567,"config":568},"GitOps",{"href":569,"dataGaName":570,"dataGaLocation":493},"/solutions/gitops/","gitops",{"text":191,"config":572},{"href":193,"dataGaName":194,"dataGaLocation":493},{"text":574,"config":575},"Small business",{"href":198,"dataGaName":199,"dataGaLocation":493},{"text":577,"config":578},"Public sector",{"href":203,"dataGaName":204,"dataGaLocation":493},{"text":580,"config":581},"Education",{"href":582,"dataGaName":583,"dataGaLocation":493},"/solutions/education/","education",{"text":585,"config":586},"Financial services",{"href":587,"dataGaName":588,"dataGaLocation":493},"/solutions/finance/","financial services",{"title":211,"links":590},[591,593,595,597,600,602,604,606,608,610,612,614,616],{"text":223,"config":592},{"href":225,"dataGaName":226,"dataGaLocation":493},{"text":228,"config":594},{"href":230,"dataGaName":231,"dataGaLocation":493},{"text":233,"config":596},{"href":235,"dataGaName":236,"dataGaLocation":493},{"text":238,"config":598},{"href":240,"dataGaName":599,"dataGaLocation":493},"docs",{"text":261,"config":601},{"href":263,"dataGaName":5,"dataGaLocation":493},{"text":256,"config":603},{"href":258,"dataGaName":259,"dataGaLocation":493},{"text":265,"config":605},{"href":267,"dataGaName":268,"dataGaLocation":493},{"text":278,"config":607},{"href":280,"dataGaName":281,"dataGaLocation":493},{"text":270,"config":609},{"href":272,"dataGaName":273,"dataGaLocation":493},{"text":283,"config":611},{"href":285,"dataGaName":286,"dataGaLocation":493},{"text":288,"config":613},{"href":290,"dataGaName":291,"dataGaLocation":493},{"text":293,"config":615},{"href":295,"dataGaName":296,"dataGaLocation":493},{"text":298,"config":617},{"href":300,"dataGaName":301,"dataGaLocation":493},{"title":316,"links":619},[620,622,624,626,628,630,632,636,641,643,645,647],{"text":323,"config":621},{"href":325,"dataGaName":318,"dataGaLocation":493},{"text":328,"config":623},{"href":330,"dataGaName":331,"dataGaLocation":493},{"text":336,"config":625},{"href":338,"dataGaName":339,"dataGaLocation":493},{"text":341,"config":627},{"href":343,"dataGaName":344,"dataGaLocation":493},{"text":346,"config":629},{"href":348,"dataGaName":349,"dataGaLocation":493},{"text":351,"config":631},{"href":353,"dataGaName":354,"dataGaLocation":493},{"text":633,"config":634},"Sustainability",{"href":635,"dataGaName":633,"dataGaLocation":493},"/sustainability/",{"text":637,"config":638},"Diversity, inclusion and belonging (DIB)",{"href":639,"dataGaName":640,"dataGaLocation":493},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":356,"config":642},{"href":358,"dataGaName":359,"dataGaLocation":493},{"text":366,"config":644},{"href":368,"dataGaName":369,"dataGaLocation":493},{"text":371,"config":646},{"href":373,"dataGaName":374,"dataGaLocation":493},{"text":648,"config":649},"Modern Slavery Transparency Statement",{"href":650,"dataGaName":651,"dataGaLocation":493},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":653,"links":654},"Contact Us",[655,658,660,662,667,672,677],{"text":656,"config":657},"Contact an expert",{"href":55,"dataGaName":56,"dataGaLocation":493},{"text":385,"config":659},{"href":387,"dataGaName":388,"dataGaLocation":493},{"text":390,"config":661},{"href":392,"dataGaName":393,"dataGaLocation":493},{"text":663,"config":664},"Status",{"href":665,"dataGaName":666,"dataGaLocation":493},"https://status.gitlab.com/","status",{"text":668,"config":669},"Terms of use",{"href":670,"dataGaName":671,"dataGaLocation":493},"/terms/","terms of use",{"text":673,"config":674},"Privacy statement",{"href":675,"dataGaName":676,"dataGaLocation":493},"/privacy/","privacy statement",{"text":678,"config":679},"Cookie preferences",{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":109},"cookie preferences","ot-sdk-btn",{"items":683},[684,686,688],{"text":668,"config":685},{"href":670,"dataGaName":671,"dataGaLocation":493},{"text":673,"config":687},{"href":675,"dataGaName":676,"dataGaLocation":493},{"text":678,"config":689},{"dataGaName":680,"dataGaLocation":493,"id":681,"isOneTrustButton":109},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[695,708],{"_path":696,"_dir":697,"_draft":6,"_partial":6,"_locale":7,"content":698,"config":702,"_id":704,"_type":32,"title":705,"_source":34,"_file":706,"_stem":707,"_extension":37},"/en-us/blog/authors/joo-pereira","authors",{"name":19,"config":699},{"headshot":700,"ctfId":701},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749665547/Blog/Author%20Headshots/joao_pereira.png","7wLh5rwID5R39PRA6aiAb0",{"template":703},"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":709,"_dir":697,"_draft":6,"_partial":6,"_locale":7,"content":710,"config":714,"_id":715,"_type":32,"title":20,"_source":34,"_file":716,"_stem":717,"_extension":37},"/en-us/blog/authors/tim-rizzi",{"name":20,"config":711},{"headshot":712,"ctfId":713},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749661866/Blog/Author%20Headshots/trizzi-headshot.jpg","trizzi",{"template":703},"content:en-us:blog:authors:tim-rizzi.yml","en-us/blog/authors/tim-rizzi.yml","en-us/blog/authors/tim-rizzi",{"_path":719,"_dir":40,"_draft":6,"_partial":6,"_locale":7,"header":720,"eyebrow":721,"blurb":722,"button":723,"secondaryButton":727,"_id":729,"_type":32,"title":730,"_source":34,"_file":731,"_stem":732,"_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":724},{"href":725,"dataGaName":51,"dataGaLocation":726},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":53,"config":728},{"href":55,"dataGaName":56,"dataGaLocation":726},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1758326246456]