<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://about.gitlab.com/blog</id>
    <title>GitLab</title>
    <updated>2026-08-28T20:30:32.486Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <author>
        <name>The GitLab Team</name>
    </author>
    <link rel="alternate" href="https://about.gitlab.com/blog"/>
    <link rel="self" href="https://about.gitlab.com/atom.xml"/>
    <subtitle>GitLab Blog RSS feed</subtitle>
    <icon>https://about.gitlab.com/favicon.ico</icon>
    <rights>All rights reserved 2026</rights>
    <entry>
        <title type="html"><![CDATA[GitLab compliance frameworks: Adhere to SOC 2 in minutes]]></title>
        <id>https://about.gitlab.com/blog/quick-compliance-with-compliance-framework-templates/</id>
        <link href="https://about.gitlab.com/blog/quick-compliance-with-compliance-framework-templates/"/>
        <updated>2026-08-27T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Compliance is the part of software delivery that everyone agrees is important, yet nobody enjoys. It
often lives in spreadsheets, screenshots, and the quiet dread of an upcoming audit. GitLab&#39;s custom
compliance frameworks work differently. Instead of documenting what <em>should</em> be true about your
projects, you define the controls once and let the platform continuously verify what <em>is</em> true.</p><p>In this article, you&#39;ll learn why compliance adherence matters, how to stand up a SOC 2 framework in
minutes using a template, how to monitor adherence on an ongoing basis, how to enforce compliance
with policies, and which standards already ship as ready-to-use templates. You&#39;ll also get a look at
where AI-specific compliance templates are heading. You can watch the video below to see it in
action:</p><figure className="video_container">
  <iframe src="https://www.youtube.com/embed/Yo1JJDs5OBU?si=_5yhOghlbQWab7kV" frameBorder="0" allowFullScreen="true"> </iframe></figure><br /><p><strong>Tier note:</strong> Compliance frameworks are available in <strong>Premium</strong> and <strong>Ultimate</strong>. Framework
requirements and controls, the checks that power adherence reporting and the compliance status
report, require Ultimate. Everything here applies to GitLab.com, GitLab Self-Managed, and GitLab Dedicated.</p><h2 id="why-compliance-adherence-matters-and-how-custom-frameworks-help">Why compliance adherence matters and how custom frameworks help</h2><p>Regulatory and contractual obligations like SOC 2, ISO 27001, PCI DSS, and
<a href="https://about.gitlab.com/solutions/public-sector/fedramp/" rel="">FedRAMP</a> exist because customers,
partners, and regulators need assurance that your software is built and shipped responsibly. Falling
short isn&#39;t just a paperwork problem. It can block deals, trigger fines, delay product launches, and
erode trust. Compliance also isn&#39;t a one-time event. A project that was compliant at audit time can
drift the moment someone disables a scanner, removes branch protection, or merges without the
required approvals.</p><p>Custom compliance frameworks are designed to close that gap. A compliance framework in GitLab is a
<a href="https://docs.gitlab.com/user/project/labels/" rel="">label</a> you create on a top-level group to identify projects that carry specific compliance obligations or need extra oversight. On its own that label provides organization and visibility. In
Ultimate, a framework can also carry <strong>requirements</strong> made up of <strong>controls</strong>, which are automated
checks against the configuration and behavior of every project the framework is applied to.</p><p>Instead of asking an engineer to confirm that static application security testing (<a href="https://docs.gitlab.com/user/application_security/sast/" rel="">SAST</a>) is running, that the default branch is protected, and that merge requests need two approvals, GitLab evaluates those conditions for you on a schedule
and whenever relevant project settings change. Compliance stops being a snapshot you assemble before
an audit and becomes something you can watch year-round. Frameworks are created on the top-level
group and inherited by all subgroups and projects beneath it. You can apply up to 20 frameworks to a
single project when it needs to satisfy several standards at once.</p><p>This changes the day-to-day effort in a few ways. Compliance moves left into the development
workflow, audit preparation becomes a matter of exporting a report rather than reconstructing
evidence, and consistency is enforced by the platform rather than by good intentions.</p><h2 id="applying-a-template-to-adhere-to-soc-2">Applying a template to adhere to SOC 2</h2><p>Building a framework by hand means defining every requirement and every control one at a time. For a
standard like SOC 2 that maps to many controls, that&#39;s repetitive and error-prone. Templates solve
this by giving you a complete, predefined framework, with the name, description, color,
requirements, and controls all configured, and that you can adopt in a single step.</p><p>The <a href="https://gitlab.com/gitlab-org/software-supply-chain-security/compliance/engineering/compliance-adherence-templates" rel="">Compliance Adherence Templates
project</a>
hosts a library of these frameworks as JSON files, and <code>soc2.json</code> is one of them.</p><p>There are two ways to get a template into your group.</p><p><img alt="New compliance framework creation" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1782823594/fyp8dcrkscjuwejsc303.png" /></p><h3 id="option-a-create-from-a-template-in-the-compliance-center">Option A: Create from a template in the Compliance center</h3><p>You can create a framework directly from a built-in template without leaving the UI:</p><ol><li>Go to your <a href="https://docs.gitlab.com/user/group/#group-hierarchy" rel="">top-level group</a>.</li><li>In the sidetab, select <strong>Secure &gt; Compliance center</strong>.</li><li>Click the <strong>New framework</strong> button.</li><li>Choose <strong>Create from template</strong>.</li><li>Scroll down to the <strong>SOC 2</strong> template, and select <strong>View details</strong> to see the controls the
template implements.</li><li>Press the <strong>Use template</strong> button to implement the SOC 2 template. customize the name,
description, and color if you&#39;d like. Select <strong>Next</strong> when complete.</li><li>Preview the included requirements and controls.</li><li>Apply the framework to the groups/projects that require it.</li><li>Press the <strong>Create framework</strong> button.</li></ol><p>Your framework is created and will be applied to the groups/projects you selected.</p><h3 id="option-b-import-the-soc-2-json-template">Option B: Import the SOC 2 JSON template</h3><p>If you&#39;re on a GitLab version without the in-product template picker, or you want to keep the
template under version control and tweak it first, import the JSON directly:</p><ol><li>Go to the <a href="https://gitlab.com/gitlab-org/software-supply-chain-security/compliance/engineering/compliance-adherence-templates" rel="">Compliance Adherence Templates
project</a>
and download <code>soc2.json</code>.</li><li>Go to your <a href="https://docs.gitlab.com/user/group/#group-hierarchy" rel="">top-level group</a>.</li><li>Select <strong>Secure &gt; Compliance center</strong>.</li><li>On the <strong>Frameworks</strong> tab, select <strong>New framework</strong>, then <strong>Import framework</strong>.</li><li>Choose the <code>soc2.json</code> file from your local system.</li><li>When the import succeeds, the SOC 2 framework appears in your frameworks list.</li></ol><p>A framework only does something once it&#39;s attached to projects. Make sure you apply this
framework to the groups/projects where it will be used.</p><p><strong>Note:</strong> Imports fail with an <code>Unable to determine the correct upload URL</code> error if a framework with the same name already exists. Rename or remove the existing one first.</p><h3 id="edit-and-apply-the-framework-to-your-projects">Edit and apply the framework to your projects</h3><p>You can also edit the newly created framework as well as apply it to
additional groups/projects:</p><ol><li>In <strong>Secure &gt; Compliance center</strong>, open the <strong>Frameworks</strong> tab.</li><li>Hover over the SOC 2 framework and select <strong>Edit Framework</strong>.</li><li>In the <strong>Requirements &amp; Controls</strong> section, under <strong>Action</strong>, select the <strong>... &gt; Edit</strong>.</li><li>Perform any necessary changes to the requirements or controls.</li><li>In the <strong>Scoping</strong> section, select the groups/projects that fall under SOC 2.</li><li>Select <strong>Update Framework</strong>.</li></ol><p>If you want every new project in the group to inherit SOC 2 automatically, set the framework as the
group <strong>default</strong> in the <strong>Basic information</strong> section. The framework will then be applied to all
newly created and imported projects going forward.</p><h3 id="what-the-soc-2-template-actually-checks">What the SOC 2 template actually checks</h3><p>Once applied, the SOC 2 framework maps GitLab controls to the relevant Trust Services Criteria. A
few highlights:</p><table><thead><tr><th>SOC 2 criterion</th><th>What it covers</th><th>GitLab controls applied</th></tr></thead><tbody><tr><td>CC3.2</td><td>Identifying vulnerabilities in system components</td><td>Dependency scanning, container scanning, DAST, API security running</td></tr><tr><td>CC5.1</td><td>Segregation of duties</td><td>At least two approvals; author and committer approvals forbidden; approval rules locked from editing</td></tr><tr><td>CC6.6</td><td>Protecting authentication credentials in transit</td><td>Secret detection running</td></tr><tr><td>CC6.8</td><td>Detecting unauthorized or malicious software changes</td><td>Default branch protected</td></tr><tr><td>CC7.1</td><td>Detecting new vulnerabilities through scanning</td><td>Dependency, container, SAST, DAST, and API security scanning running</td></tr><tr><td>CC8.1</td><td>Authorizing, testing, and approving changes</td><td>SAST, DAST, secret detection running; default branch protected; at least two approvals</td></tr></tbody></table><br /><p>After the framework is applied to a project, GitLab runs a compliance scan and begins reporting on
whether each control passes. No manual evidence gathering required.</p><h2 id="continuously-viewing-compliance-status">Continuously viewing compliance status</h2><p>Applying a framework is only half the value. The other half is knowing, at any moment, where you
stand. That&#39;s the job of the <strong>compliance status report</strong> (Ultimate), found in your top-level group
under <strong>Secure &gt; Compliance center &gt; Status</strong>.</p><p>The report surfaces the most recent instances where projects <strong>do</strong> and <strong>do not</strong> adhere to a
framework&#39;s controls, so you can spot and close gaps fast. Each row tells you:</p><ul><li><strong>Status</strong>: whether a requirement is in or out of compliance</li><li><strong>Requirement</strong>: the specific controls in a requirement that failed (for example, &quot;At least two
approvals&quot;)</li><li><strong>Framework</strong>: which framework the control belongs to (for example, SOC 2)</li><li><strong>Project</strong>: where the non-adherence was found</li><li><strong>Last Scanned</strong>: when the gap was first recorded</li><li><strong>Fix Suggestions</strong>: information on how to resolve the issue</li></ul><p>You can filter by project, framework, or requirement, jump straight into a project&#39;s compliance
detail view, and export the whole report (delivered to your inbox as an attachment) when an auditor
asks for evidence.</p><p><img alt="Compliance center status" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1782823594/yq9ec51psgsaocezmpvk.png" /></p><p>Behind the scenes, scans that refresh the report are triggered automatically when a framework is
added to a project, when an associated framework&#39;s requirements change, and on a recurring <strong>12-hour
schedule</strong>. Results typically appear five to ten minutes after a scan runs. This means compliance
drift becomes visible within hours rather than at the next annual audit. To view the report, you&#39;ll
need to be an administrator, or have the Security Manager or Owner role for the group.</p><h2 id="adhering-to-compliance-via-policies">Adhering to compliance via policies</h2><p>Reporting tells you when something is wrong. <strong>Policies</strong> stop the wrong thing from happening in the
first place. This is where compliance frameworks move from observation to enforcement, and it&#39;s an
Ultimate capability tied to the framework label.</p><p><img alt="Policy scoping to compliance framework" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1782823594/hzyc3qhwg6rmvu98fkpl.png" /></p><p>A compliance framework can act as the <strong>scope</strong> for <strong><a href="https://docs.gitlab.com/user/application_security/policies/" rel="">Security
policies</a>.</strong> Scan execution policies,
Pipeline execution policies, and merge request approval policies can be scoped to a compliance
framework, so every project carrying that label automatically inherits them. For example, you can
require that SAST, secret detection, and dependency scanning run on the default branch, and require
approval from a designated security team before a merge request that introduces new critical
vulnerabilities can be merged. Because the policy is bound to the framework rather than to
individual projects, adding a new project to the framework instantly brings it under the same
guardrails.</p><p>The pieces work together. The <strong>framework</strong> defines the obligation, <strong>controls and the status
report</strong> measure adherence, and <strong>policies and compliance pipelines</strong> enforce the behavior. You&#39;re
not just documenting that SOC 2 requires two approvals and running scanners. You&#39;re making it
difficult to ship anything that violates those requirements. When a control fails, the status report
flags it. When a policy is in place, the non-compliant change is blocked before it merges.</p><h2 id="available-templates">Available templates</h2><p>GitLab ships a growing library of predefined framework templates in the <a href="https://gitlab.com/gitlab-org/software-supply-chain-security/compliance/engineering/compliance-adherence-templates" rel="">Compliance Adherence
Templates
project</a>,
each mapping a recognized standard to GitLab controls. As of publication, these include:</p><table><thead><tr><th>Standard</th><th>Template file</th></tr></thead><tbody><tr><td>CIS Critical Security Controls v8.1</td><td><code>cis_csc_v8-1.json</code></td></tr><tr><td>CSA Cloud Controls Matrix v4</td><td><code>csa_ccm_v4.json</code></td></tr><tr><td>Cyber Essentials</td><td><code>cyber_essentials.json</code></td></tr><tr><td>DORA (Digital Operational Resilience Act)</td><td><code>dora.json</code></td></tr><tr><td>FedRAMP Low / Moderate / High (Rev 5)</td><td><code>fedramp_low_r5.json</code>, <code>fedramp_moderate_r5.json</code>, <code>fedramp_high_r5.json</code></td></tr><tr><td>IRAP Official / Protected / Secret / Top Secret</td><td><code>irap_official.json</code>, <code>irap_protected.json</code>, <code>irap_secret.json</code>, <code>irap_top_secret.json</code></td></tr><tr><td>ISMAP</td><td><code>ismap.json</code></td></tr><tr><td>ISO 27001:2022</td><td><code>iso_27001:2022.json</code></td></tr><tr><td>NIS 2</td><td><code>nis_2.json</code></td></tr><tr><td>NIST 800-53 Rev 5</td><td><code>nist_800-53_r5.json</code></td></tr><tr><td>NIST 800-171 Rev 3 (CMMC)</td><td><code>nist_800-171_r3_cmmc.json</code></td></tr><tr><td>NIST CSF 2.0</td><td><code>nist_csf_2.json</code></td></tr><tr><td>NIST SP 800-218 (SSDF)</td><td><code>nist_800-218_v1-1.json</code></td></tr><tr><td>PCI DSS v4.0.1</td><td><code>pci_dss_v4-0-1.json</code></td></tr><tr><td>SOC 2</td><td><code>soc2.json</code></td></tr><tr><td>TISAX</td><td><code>tisax.json</code></td></tr></tbody></table><br /><p>Each template&#39;s exact requirement-to-control mapping is documented in the <a href="https://docs.gitlab.com/user/compliance/compliance_frameworks/compliance_standards/" rel="">compliance
standards</a>
reference. You can import any of them as-is, or use them as a starting point. Export a framework as
JSON, adjust the requirements and controls to match your organization&#39;s interpretation of a
standard, and re-import. The JSON schema is straightforward. A framework has a <code>name</code>,
<code>description</code>, <code>color</code>, and an array of <code>requirements</code>, each with its own <code>controls</code> and evaluation
<code>expression</code>. That makes templates easy to keep in version control and share across groups.</p><h2 id="a-look-ahead-ai-specific-compliance-templates">A look ahead: AI-specific compliance templates</h2><p>The compliance standards covered today were largely written for traditional software. As
organizations embed AI into their products and their own development workflows, a new class of
obligations is emerging around governing how AI systems are built, approved, and monitored. Examples
include the EU AI Act, ISO/IEC 42001, and the NIST AI Risk Management Framework.</p><p>GitLab is exploring <strong>AI governance compliance templates</strong> (<a href="https://gitlab.com/groups/gitlab-org/-/epics/16808" rel="">Epic
#16808</a>, with planning tracked in <a href="https://gitlab.com/groups/gitlab-org/-/work_items/22336" rel="">Work item
#22336</a>) to extend the same template-driven
model into this space. The intent is to let teams adopt an AI-governance framework as easily as they
adopt SOC 2 today, with predefined requirements and controls that map to AI-specific obligations,
applied to the projects that build or deploy AI capabilities, and surfaced through the same
compliance status report.</p><p>It&#39;s worth keeping one distinction in mind. <strong>Compliance</strong> is the state of meeting a defined set of
requirements, while <strong>governance</strong> is the ongoing capability to keep AI systems compliant as both
the systems and the rules evolve. GitLab&#39;s broader direction pairs AI-assisted detection with
human-in-the-loop approval and auditable, policy-based enforcement, so AI findings inform decisions
but accountable humans and measurable controls still gate what ships. AI-specific templates would be
the onramp, giving you a fast way to encode emerging AI requirements into the same framework,
control, status report, and policy machinery you&#39;re already using for everything else.</p><h2 id="summary">Summary</h2><p>Custom compliance frameworks let you define your obligations once and have GitLab continuously
verify them. Templates take the manual setup out of getting started, so a SOC 2 framework is a few
clicks or a single JSON import away. The compliance status report keeps adherence visible on a
12-hour cadence, and security policies plus compliance pipelines turn that visibility into
enforcement. With a library of standards already available and AI-specific templates on the horizon,
the path from &quot;we should be compliant&quot; to &quot;we can prove we are, continuously&quot; is shorter than it&#39;s
ever been.</p><p>Learn more with our <a href="https://docs.gitlab.com/user/compliance/compliance_frameworks/" rel="">compliance frameworks documentation</a> and try the <a href="https://gitlab.navattic.com/custom-compliance" rel="">custom
compliance frameworks click-through demo</a>.</p><p><em>This blog post contains &quot;forward‑looking statements&quot; within the meaning of Section 27A of the Securities Act of 1933, as amended, and Section 21E of the Securities Exchange Act of 1934. Although we believe that the expectations reflected in these statements are reasonable, they are subject to known and unknown risks, uncertainties, assumptions and other factors that may cause actual results or outcomes to differ materially. Further information on these risks and other factors is included under the caption &quot;Risk Factors&quot; in our filings with the SEC. We do not undertake any obligation to update or revise these statements after the date of this blog post, except as required by law.</em></p>]]></content>
        <author>
            <name>Fernando Diaz</name>
            <uri>https://about.gitlab.com/blog/authors/fernando-diaz/</uri>
        </author>
        <published>2026-08-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to recognize your team with GitLab Achievements]]></title>
        <id>https://about.gitlab.com/blog/how-to-recognize-your-team-with-gitlab-achievements/</id>
        <link href="https://about.gitlab.com/blog/how-to-recognize-your-team-with-gitlab-achievements/"/>
        <updated>2026-08-27T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Every team runs on people who go above and beyond. The engineer who fixes the flaky test nobody else will touch. The reviewer who turns your merge request around in an hour. The teammate who finishes their certification. Or the community member who shows up release after release. Whether your team is a company, an open source project, or a community, GitLab had no built-in way to say &quot;we see you.&quot; <a href="https://docs.gitlab.com/user/profile/achievements/" rel="">GitLab Achievements</a> changes that.</p><h2 id="what-are-gitlab-achievements">What are GitLab Achievements?</h2><p>An achievement is a custom badge you create once and award to people for their behavior. That might be a contribution, a milestone, or simply getting the most out of GitLab. Each one has a name, a description, and an avatar. Think &quot;First merged MR&quot;, &quot;Certified&quot;, or &quot;Contributor of the month&quot;. Awarded achievements appear on the recipient&#39;s profile, alongside their contribution history.</p><p>There are two halves to the achievement. The achievement itself is a reusable template you define at the group level. Awarding that achievement to someone is a separate action, and it can carry an optional personal message. That message supports GitLab Flavored Markdown, so you can link straight to the merge request, issue, or event that earned it. The same &quot;Contributor of the month&quot; badge can then tell a different story every time you award it.</p><p>Recipients stay in control. An award doesn&#39;t appear on anyone&#39;s profile until they accept it using a link from an email notification. Recognition is offered, never forced onto someone&#39;s profile.</p><p>Achievements are generally available as of GitLab 19.2, across Free, Premium, and Ultimate, on GitLab.com, GitLab Self-Managed, and GitLab Dedicated.</p><p><img alt="GitLab Achievements on user profile" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787231951/jmwvzqlm0c3ejt0bhm7d.png" /></p><h2 id="why-recognition-matters">Why recognition matters</h2><p>Recognition is one of the least expensive, most effective tools you have for retention, motivation, and belonging. A visible badge on a profile costs you a minute to award and gives the recipient something lasting. And &quot;team&quot; is broad: It might be your company, your open source project, or your wider community. The value depends entirely on who you are and what you&#39;re trying to reinforce.</p><p><strong>Internal engineering and platform teams</strong></p><p>This is where most teams will start. Reward the people who keep the wheels turning: your fastest reviewers, engineers who complete onboarding or earn a certification, members of a guild or chapter, or the ones who show up during an incident. A badge makes the effort that usually goes unnoticed visible to the whole organization.</p><p><strong>Open source maintainers and community programs</strong></p><p>This is our own story, and the reason we built the feature. Open source contributors are rarely paid so recognition is often the only reward on offer. It needs to be genuine and visible. Achievements give you a way to celebrate external contributors at scale: Award a &quot;First contribution&quot; badge automatically, or a &quot;Notable contributor&quot; badge each release. Contributors get something concrete to point to, and you get a consistent way to celebrate people behind it.</p><h2 id="ways-to-use-achievements">Ways to use achievements</h2><p>Here are five ways to use GitLab Achievements.</p><h3 id="identify-your-team-and-core-contributors">Identify your team and core contributors</h3><p>The use case that started it all: Badge your team and core contributors so your community knows who&#39;s who. When someone new lands in your project, a glance at profiles tells them who maintains it, who reviews it, and who will field questions. Add a &quot;Hackathon winner&quot; badge and you&#39;ve turned a one-off event into lasting recognition. Recognition becomes something people can see, not something buried in a changelog.</p><h3 id="reward-great-reviews-and-fast-turnarounds">Reward great reviews and fast turnarounds</h3><p>We&#39;ve since expanded our own use internally to recognise great reviews and fast turnarounds. This is the quiet lesson of achievements: You reinforce the behavior you reward. Badge thoughtful reviews, quick responses, or mentoring, and you signal to the whole team what good looks like. It costs nothing and it compounds.</p><h3 id="reward-adoption-and-learning">Reward adoption and learning</h3><p>Recognition isn&#39;t only for the people who build GitLab, it works just as well for the people getting the most out of it. Award a badge when someone earns a certification, finishes an enablement path, or adopts a capability your team has been trying to roll out. For customer success and platform teams, this turns dry adoption metrics into something people are proud of. Learning to use a tool well is a contribution, too.</p><h3 id="celebrate-milestones-and-first-contributions">Celebrate milestones and first contributions</h3><p>Achievements come in three flavors:</p><ul><li>Awarded once and kept forever (&quot;First merged MR&quot;)</li><li>Awarded once but revocable (&quot;Core team member&quot;)</li><li>Awarded repeatedly (&quot;Contributor of the month&quot;)</li></ul><p>Use them to mark the moments that matter, a first contribution, a 100th contribution, a hard problem finally solved.</p><p>This is where the personal message earns its keep. For a recurring award, attach a message linking to the exact merge request or issue that earned it, with a line on why. The badge stops being a generic sticker and becomes a record of a specific achievement.</p><h3 id="run-programs-hackathons-and-campaigns">Run programs, hackathons, and campaigns</h3><p>Because achievements can be awarded multiple times and revoked, they suit time-boxed events. Run a hackathon and award a badge to every participant. Run a quarterly contribution drive and award a limited-edition achievement that only that cohort will ever hold. It&#39;s a lightweight way to give a campaign a lasting footprint.</p><h2 id="how-to-create-and-award-an-achievement">How to create and award an achievement</h2><p>The <a href="https://docs.gitlab.com/user/profile/achievements/" rel="">Achievements documentation</a> covers creating,
awarding, accepting, and revoking in full.</p><p>Everything is scriptable through the GraphQL API, so you can award in bulk or wire achievements into your own automation.
Awarding a &quot;First contribution&quot; badge the moment someone&#39;s first merge request merges, for example.</p><figure className="video_container">
  <iframe src="https://www.youtube.com/embed/iXg-KQjeBPQ" frameBorder="0" allowFullScreen="true"></iframe></figure><h2 id="built-by-the-community-for-the-community">Built by the community, for the community</h2><p>Achievements didn&#39;t come from the core product team. The feature started as a gap that our team, <a href="https://handbook.gitlab.com/handbook/marketing/developer-relations/" rel="">Co-create and Community Engineering</a>, and the wider community set out to fill, captured in <a href="https://gitlab.com/groups/gitlab-org/-/work_items/9429" rel="">Epic #9429</a>. It&#39;s the &quot;everyone can contribute&quot; value in action: a feature that lets you recognize contributors was itself co-created by contributors.</p><p>Community contributor and Core Team member <a href="https://gitlab.com/Taucher2003" rel="">Niklas van Schrick</a> was key to making it happen.
There&#39;s a neat symmetry to that. A feature for recognizing contributors, delivered by a contributor, and now we get to recognize him for it. If you&#39;ve ever wanted to shape GitLab itself, this is proof that you can! <a href="https://contributors.gitlab.com/start" rel="">Start contributing here</a>.</p><h2 id="how-ai-helped-us-ship-it">How AI helped us ship it</h2><p>Getting Achievements to general availability fell to Mattias Michaux, who had just joined the company, and our team.
The feature was part-built and had sat idle for a while, so his first job wasn&#39;t writing code, it was working out where the previous effort had got to, what was left to do, and how this corner of an enormous, unfamiliar codebase actually fitted together.</p><p>That&#39;s usually the slowest part of picking up someone else&#39;s half-finished work. This is where <a href="https://about.gitlab.com/gitlab-duo/" rel="">GitLab Duo</a> and <a href="https://docs.gitlab.com/orbit/" rel="">Orbit</a> came in. Mapping the existing code, understanding what remained, and getting productive quickly. Doing all of that in the time we had simply wouldn&#39;t have been feasible without them.</p><p>The takeaway isn&#39;t about us. It&#39;s that these tools collapse the ramp-up cost of a large, unfamiliar codebase whether you&#39;re a new hire on your first week or a first-time contributor sending your first merge request. The barrier to contributing has never been lower.</p><h2 id="get-started">Get started</h2><p>Recognition works best when it&#39;s a habit, not an afterthought. So <a href="https://docs.gitlab.com/user/profile/achievements/" rel="">create your first achievement</a> and award it to someone this week: a reviewer, a mentor, a first-time contributor.</p><p>Want to help build the next feature like this one? <a href="https://contributors.gitlab.com/start" rel="">Start contributing to GitLab</a>. And if you have a use case we haven&#39;t thought of, let us know in the <a href="https://gitlab.com/groups/gitlab-org/-/work_items/9429" rel="">Achievements epic</a>.</p>]]></content>
        <author>
            <name>Lee Tickett</name>
            <uri>https://about.gitlab.com/blog/authors/lee-tickett/</uri>
        </author>
        <published>2026-08-27T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Making room for what's next in the GitLab UI]]></title>
        <id>https://about.gitlab.com/blog/making-room-for-whats-next-in-the-gitlab-ui/</id>
        <link href="https://about.gitlab.com/blog/making-room-for-whats-next-in-the-gitlab-ui/"/>
        <updated>2026-08-26T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Throughout this year, the product interface has been in a season of reduction. On the heels of <a href="https://about.gitlab.com/blog/gitlab-dark-mode-is-getting-a-new-look/" rel="">dark mode</a>, the tide has been moving out with a quieter application chrome, overall color reduction, and neutral controls. It can feel like loss, low tide always does. But low tide is also when you can see the shape of the shoreline clearly enough to build something new on it.</p><p>What’s coming in is a user interface built for a different kind of work where you don&#39;t search for the right button, it surfaces at the moment you need it. This is a conceptual shift that needs room to breathe, and we’re clearing the way for it.</p><p>Tech goes through cycles like this. Touchscreens replacing physical buttons felt like a loss at first, until gestures, voice, and haptics enabled a deeper kind of interaction and expression. Cords gave way to wireless and each generational change introduced real friction for a time. The tide going out isn’t the point, it’s the possibility of what comes in with it.</p><p>Here’s what’s changed in the GitLab UI:</p><ul><li>Neutralized actions and controls (buttons, form controls, toggles, tabs) with increased contrast</li><li>Enhanced instance theming addressing more surface area</li><li>Neutral palette update and tinted neutrals for themes</li><li>New bloom-style glow visual element draws attention to <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">GitLab Duo</a> interaction and moments requiring user input</li></ul><p><img alt="Before and after showing component color changes" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787318843/btxsgx3zbqxe4nasdqxv.png" title="Components before (left) and after" /></p><p><img alt="Before and after showing theme color changes" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787318843/q7gjmfb2did0ugmkwhjl.png" title="UI themes before (top) and after" /></p><p><img alt="Crop of GitLab screen with new bloom asset positioned behind AI panel" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787318842/wacr0dj1hqpgpdd2iqqr.png" title="Bloom appears below GitLab Duo panel" /></p><h2 id="the-journey-to-the-new-design">The journey to the new design</h2><p>Our version of that cycle started years ago when we removed many of the old Bootstrap variants and continued as we moved to design tokens. Instead of sharing a crowded palette, we scoped categories like actions, feedback, and controls more narrowly. Color in the product had a real problem of trying to do too many jobs at once and resulted in some screens feeling “lit up like a Christmas tree.” Generally speaking, enterprise software limits color so that when it shows up it means something. That’s the direction we’ve been iterating on for years.</p><p>Changes like this are rarely perfect on the first pass. Something looks fine in review and initial testing, and problems only become apparent with broad use across the larger product surface area. A user might struggle to tell two states apart or locate a control, which can also hint at larger UX or composition problems worth fixing. That’s not unique to this rollout, it’s how iteration works. We keep a <a href="https://gitlab.com/gitlab-org/gitlab/-/work_items/617886" rel="">UI feedback issue</a> and address comments.</p><p>We’ve made it this far without a mention of AI, but here we go. A quieter, more reductive UI isn’t the goal in and of itself. The next UI wave won’t live solely in elements waiting to be clicked, it’ll live in intelligent, self-surfacing moments. An already loud UI drowns that kind of interaction out.</p><p>We realize that not all of the changes will be received the same way, sometimes for subjective reasons, and at other times for very objective reasons. That distinction matters to us and we want to hear about both. <a href="https://gitlab.com/gitlab-org/gitlab/-/work_items/617886" rel="">Drop a note in the feedback issue</a>.</p>]]></content>
        <author>
            <name>Jeremy Elder</name>
            <uri>https://about.gitlab.com/blog/authors/jeremy-elder/</uri>
        </author>
        <published>2026-08-26T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Git was built for humans — agents need an upgrade]]></title>
        <id>https://about.gitlab.com/blog/gitlab-next-gen-scm/</id>
        <link href="https://about.gitlab.com/blog/gitlab-next-gen-scm/"/>
        <updated>2026-08-26T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p><em>The industry is now racing to rebuild source code management for agents. We showed our answer at <a href="https://about.gitlab.com/events/transcend/virtual/" rel="">GitLab Transcend</a>, but let’s reiterate why rebuilding the Git backend is only half the problem.</em></p><p>Three things break when agents become the primary users of a Git server. Every developer running hundreds of agents hits the same wall, regardless of tools:</p><ul><li><strong>The clone tax.</strong> An agent clones an entire repository to read a single file, then does it again for the next agent, and the next retry, transferring far more data than the task requires and burning context on a local grep or blame it shouldn&#39;t have needed to run. One agent invocation today can mean 5GB to 10GB transferred and 30+ seconds of setup, just to answer a single question.</li><li><strong>Concurrency collapse.</strong> Thousands of sessions hit a backend that was originally designed for human scale, producing bottlenecks and unpredictable availability.</li><li><strong>No isolation.</strong> Agents share accounts and one branch space, so they overwhelm the repository, leave no clean way to discard abandoned work, and keep no record of which agent did what.</li></ul><p>Our platform data shows how fast the pressure is building. Over the past year, our customers created 40% more CI/CD pipelines, and code pushes to GitLab.com were up 50%. While the secure repositories grew by 60%, codebase sizes have also grown by up to 500%.</p><p><img alt="Platform metrics" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787744927/g9nwnlelalb9rpqkq0j1.png" /></p><p>When we announced next-generation source code management (next-gen SCM) at GitLab Transcend in June, we walked through how Git, as an operational model, was not designed for the load agents placed on it. A few weeks later, new entrants, including Git hosts built specifically for agent-scale concurrency, are validating that claim independently. That convergence sharpens why rebuilding the Git backend is necessary, but on its own, it’s still not enough.</p><h2 id="what-were-building-for-agent-scale">What we’re building for agent scale</h2><p>Next-gen SCM runs on the Git protocol for backward compatibility, with a redesigned backend and interfaces built for agents. Instead of cloning a full working tree, agents query the repository server-side for exactly what a task requires, with each agent limited to the minimum visibility its task needs. It’s the same Git compatibility and auditability with a different motor underneath.</p><p>The architecture separates an intelligence layer (routing, caching, background work) from elastic compute that scales on demand and elastic object storage. Purpose-built read and write APIs let agents retrieve file, blame, and history data and commit changes without pulling the whole repository. Developers can run agents on any repo, fan them out by the thousands, and let them experiment safely. In practice, that means an agent gets a single batch-read instead of a full clone, a diff-stat request instead of clone-then-diff, and a last-commit-for-path lookup instead of clone-then-blame.</p><p>This isn&#39;t designed for cloud-only. The compute and storage tiers talk to each other over the standard S3 API, so the same architecture that runs on GitLab.com runs on a customer&#39;s own infrastructure, whether that&#39;s a major cloud provider&#39;s object storage or a self-hosted, S3-compatible system running in a customer&#39;s own data center. For air-gapped, regulated, and sovereignty-constrained environments, that means the same horizontal scaling and consistency guarantees, without repository data ever leaving infrastructure the customer controls.</p><p><img alt="Next-gen SCM architecture" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787744927/zsn9uhkz29hgwxmia1we.png" /></p><p>In early internal testing, agents running against next-gen SCM showed:</p><ul><li><strong>Up to 50x faster wall-clock time</strong></li><li><strong>Up to 2x fewer tokens</strong></li><li><strong>Up to 1,000x less network traffic</strong></li></ul><p>These are ceilings, not guarantees, measured under our own testing conditions. The workload that actually stresses a Git backend at agent scale is concurrent reads and writes from many independent agents against the same repositories, sustained under load — so a number only means something if the test runs close to that target, the load generator isn&#39;t the bottleneck, and the full latency distribution is reported rather than a single best case.</p><p>We hold our own results to that bar, and we&#39;d encourage anyone evaluating this category to ask the same three questions of every number they&#39;re shown, including ours. That bar is built into the architecture itself, not only our test conditions. Storage maintenance compacts small artifacts into larger, frozen ones on a geometric schedule, which puts a hard ceiling on how much data any node has to fetch to catch up to the latest snapshot. With a 1GB freeze threshold and a 2x compaction ratio, that ceiling is 2GB, regardless of how large the repository has grown.</p><p>Next-generation source code management is now in <a href="https://about.gitlab.com/early-access-preview/" rel="">private beta</a>, and here it is in action:</p><figure className="video_container">
  <iframe src="https://www.youtube.com/embed/BolGWVjKzaE?si=WxGDRr_l1ewH5oBe" frameBorder="0" allowFullScreen="true"> </iframe></figure><h2 id="rebuilding-the-backend-is-half-the-problem">Rebuilding the backend is half the problem</h2><p>The new entrants are building Git hosts: standalone destinations, or fast mirrors that sit in front of an existing host to absorb read traffic. That solves concurrency, and concurrency is a real problem. But it leaves two questions unanswered, and both are central to how we think about GitLab’s agentic infrastructure.</p><p><strong>The first is provenance.</strong> When agents push code, touch dependencies, and trigger deployments by the hundreds, the operative question stops being “did we scan?” and becomes “which agent did what, under which policy, and can we prove it?” Our agent APIs attribute every agent action to a specific workflow, model, and token. Every agent operation is routed through the same project authorization and role-scoped human-in-the-loop controls that already govern human contributors. Attribution and policy are platform properties, not repository features, so a standalone Git host isn&#39;t built to answer this natively.</p><p><strong>The second is what happens to the work after it succeeds.</strong> A successful agent experiment lives on a standalone host. On GitLab, next-gen SCM is a Git backend inside a platform that already runs CI, policy management, governance controls, and audit of the resulting code. When an agent&#39;s ephemeral experiment works, it graduates directly into a governed, observable production pipeline, without requiring a separate platform or destination.</p><p>Next-gen SCM handles execution at agent scale. <a href="https://about.gitlab.com/blog/introducing-gitlab-orbit/" rel="">GitLab Orbit</a> gives every agent and human context on the full software lifecycle as a knowledge graph, and <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">GitLab Duo Agent Platform</a> orchestrates governance and security around every agent action — so agents plan and carry out work across the full lifecycle, not just the Git operations. A faster Git backend hosts the code agents generate. Paired with GitLab&#39;s governance, lifecycle context, and orchestration, that code ships through the same CI, policy, and audit path as everything else in the platform.</p><h2 id="every-enterprise-will-hit-this-wall">Every enterprise will hit this wall</h2><p>Every customer will use agents for coding, and every customer running them at scale will run into the same limits described above, regardless of which models or tools they standardize on. That&#39;s what makes this an evolution within the infrastructure layer. The teams that move fastest in the agentic era will be the ones who can host, govern, and absorb agent output back into a lifecycle that was already built to ship trusted software.</p><h2 id="get-started">Get started</h2><p>Next-generation source code management is in private beta. <a href="https://about.gitlab.com/early-access-preview/" rel="">Request early access today!</a></p>]]></content>
        <author>
            <name>Kranthi Erusu</name>
            <uri>https://about.gitlab.com/blog/authors/kranthi-erusu/</uri>
        </author>
        <author>
            <name>Jessica Taylor</name>
            <uri>https://about.gitlab.com/blog/authors/jessica-taylor/</uri>
        </author>
        <published>2026-08-26T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[GitLab Patch Release: 19.3.1, 19.2.5, 19.1.7]]></title>
        <id>https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-1-released/</id>
        <link href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-3-1-released/"/>
        <updated>2026-08-26T00:00:00.000Z</updated>
        <published>2026-08-26T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Scale software delivery pipelines in isolation without owning the runner fleet]]></title>
        <id>https://about.gitlab.com/blog/hosted-runners-for-gitlab-dedicated/</id>
        <link href="https://about.gitlab.com/blog/hosted-runners-for-gitlab-dedicated/"/>
        <updated>2026-08-25T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Many enterprises choose <a href="https://about.gitlab.com/dedicated/" rel="">GitLab Dedicated</a> for a clear reason: a secure and compliant, single-tenant GitLab instance, managed by GitLab. As agentic workflows drive more pipeline volume, full data isolation and runner infrastructure operational burden become a challenge. This leads to the question, “Does owning the runner fleet still make sense?”</p><p>With GitLab Dedicated, there is no more need to provision, patch, build, and scale your own runner fleet. Hosted Runners for GitLab Dedicated handles the heavy lifting and delivers a seamless experience across the entire software development lifecycle so your team can focus on shipping.</p><p>Hosted Runners for GitLab Dedicated provides a runner fleet isolated from other customers. To support job-level security, each job runs in a newly provisioned, isolated VM that is deleted after the job completes. We provide a scalable and highly reliable runner fleet to support your bursty CI demands and resiliency needs. Creating and managing runners is self-serviceable through Switchboard (GitLab Dedicated management console).</p><h2 id="the-runner-ownership-trade-off-cost-vs-user-experience">The runner ownership trade-off: Cost vs. user experience</h2><p>Pipeline load can be unpredictable. To account for this, runner infrastructure can be over-provisioned to give developers the best experience and maintain low wait times. But this drives up the infrastructure cost. Conversely, under-provisioning can save on infrastructure cost, but your developers will waste time waiting for their CI jobs to be picked up. Efforts to fine-tune this balance can monopolize your platform team’s time.</p><h2 id="shift-runner-operations-to-gitlab-while-maintaining-control">Shift runner operations to GitLab while maintaining control</h2><p>Hosted Runners for GitLab Dedicated is a fully managed CI execution SaaS offering. It’s backed by a high-performing and reliable runner infrastructure.  Key benefits include:</p><ul><li><strong>Supports compliance:</strong> Full isolation/single-tenant runners with same data residency as GitLab Dedicated.</li><li><strong>Job level security:</strong> “One runner for one job” — hosted runners run every job in a standalone, short-lived VM to ensure complete process protection.</li><li><strong>Network security:</strong> Hosted runners can connect to internal artifact registries, secret managers, and deploy targets securely through AWS PrivateLink.</li><li><strong>Autoscaling for performance and predictability:</strong> Customers get reserved, predictable CI runner capacity for critical workloads resulting in improved queue wait times. Our runners scale with your team’s bursty CI demands.</li><li><strong>High reliability:</strong> The Hosted Runners for GitLab Dedicated SLA of 99.9% uptime is supported by highly available runner architecture to ensure your workflows remain stable, resilient, and online.</li><li><strong>Usage and cost visibility:</strong> Track hosted runners&#39; GitLab Credit consumption on the <a href="https://docs.gitlab.com/subscriptions/gitlab_credits/#gitlab-credits-dashboard" rel="">GitLab Credits Dashboard</a>.</li><li><strong>Consumption pricing:</strong> Hosted runners can now draw down from GitLab Credits, allowing you to pay for only what you use.</li><li><strong>Support you can count on:</strong> GitLab’s world-class support team responds to incidents around the clock.</li></ul><h2 id="experience-hosted-runners-in-gitlab-dedicated">Experience hosted runners in GitLab Dedicated</h2><p>See Hosted Runners for GitLab Dedicated in action:</p><iframe src="https://player.vimeo.com/video/1219640416?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameBorder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerPolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="19.3 Demo - Hosted Runners"></iframe><script src="https://player.vimeo.com/api/player.js"></script><br /><p><a href="https://docs.gitlab.com/administration/dedicated/hosted_runners" rel="">Hosted Runners for GitLab Dedicated</a> is available in Linux x86-64 and Linux Arm64 architecture in the following machine sizes.</p><table><thead><tr><th align="left">Size</th><th align="left">vCPUs</th><th align="left">Memory</th><th align="left">Storage</th><th align="left">Example tag (x86-64)</th></tr></thead><tbody><tr><td align="left">Small</td><td align="left">2</td><td align="left">8 GB</td><td align="left">30 GB</td><td align="left"><code>linux-small-amd64</code> (default)</td></tr><tr><td align="left">Medium</td><td align="left">4</td><td align="left">16 GB</td><td align="left">50 GB</td><td align="left"><code>linux-medium-amd64</code></td></tr><tr><td align="left">Large</td><td align="left">8</td><td align="left">32 GB</td><td align="left">100 GB</td><td align="left"><code>linux-large-amd64</code></td></tr><tr><td align="left">X-Large</td><td align="left">16</td><td align="left">64 GB</td><td align="left">200 GB</td><td align="left"><code>linux-xlarge-amd64</code></td></tr><tr><td align="left">2X-Large</td><td align="left">32</td><td align="left">128 GB</td><td align="left">200 GB</td><td align="left"><code>linux-2xlarge-amd64</code></td></tr></tbody></table><h2 id="get-started-with-hosted-runners-for-gitlab-dedicated">Get started with Hosted Runners for GitLab Dedicated</h2><p><a href="https://docs.gitlab.com/administration/dedicated/hosted_runners/#manage-hosted-runners" rel="">Hosted Runners for GitLab Dedicated</a> is an add-on to GitLab Dedicated. Reach out to your <a href="https://about.gitlab.com/sales/" rel="">GitLab account team</a> to get started.</p><p>If you want to learn more about how GitLab Dedicated can support your compliance posture, <a href="https://about.gitlab.com/sales/" rel="">talk to our team</a>.</p><blockquote><p>Need inference inside the same GitLab Dedicated boundary? <a href="https://about.gitlab.com/blog/gitlab-dedicated-ai-gateway/" rel="">Learn more in our companion article on the single-tenant AI Gateway</a>.</p></blockquote>]]></content>
        <author>
            <name>Kyurim Rhee</name>
            <uri>https://about.gitlab.com/blog/authors/kyurim-rhee/</uri>
        </author>
        <published>2026-08-25T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[When code is abundant]]></title>
        <id>https://about.gitlab.com/blog/when-code-is-abundant/</id>
        <link href="https://about.gitlab.com/blog/when-code-is-abundant/"/>
        <updated>2026-08-24T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>I returned from the holiday break in January convinced that something fundamental had changed.</p><p>Large language models had reached the point where they could produce useful code reliably enough, and cheaply enough, to change the economics of software development. Engineers everywhere seemed to be experimenting with the same thing: not just asking an AI assistant for suggestions, but giving agents real work and seeing how far they could take it.</p><p>I started thinking about what happens if that continues. What changes when producing code is no longer the primary constraint in building software?</p><p>I wrote those thoughts down in a board memo in January. In May, I published part of that thesis in <a href="https://about.gitlab.com/blog/gitlab-act-2/" rel="">GitLab’s Act 2</a>: the cost and time of producing software was collapsing, machines would increasingly build software under human direction, and the architecture underneath software development would have to change with it.</p><p>In June, at <a href="https://about.gitlab.com/blog/gitlab-transcend-announcements/" rel="">GitLab Transcend</a>, we showed the first pieces of that architecture: source control rebuilt for machine-scale concurrency, GitLab Orbit as a context graph spanning the software lifecycle, and governance around agent identity, policy, approval and audit.</p><p>Then, on August 21, Anthropic published <em><a href="https://claude.com/blog/the-ai-native-sdlc-playbook" rel="">The AI-Native SDLC Playbook</a></em>. It opens with a simple statement:</p><p><strong>“Code is no longer the bottleneck.”</strong></p><p>I agree.</p><p>Anthropic’s playbook is a practical description of how the development lifecycle changes when agents can move implementation dramatically faster: planning becomes machine-readable, handoffs become automated, verification moves into the loop, and human judgment concentrates at the gates.</p><p>What interests me is what happens one level beyond the workflow. If code is no longer the primary constraint, what becomes scarce? What architecture does an enterprise need when people, agents and multiple models are all acting across the software lifecycle at machine speed? And where does durable value move when generating the code itself becomes increasingly abundant?</p><p>Over the past eight months, I’ve watched GitLab engineering and other organizations including Stripe, Spotify and Amplitude begin to answer those questions in production. Their experiences have sharpened my original conviction. The important change is not simply that AI can produce code faster.</p><p><strong>It is that when implementation gets dramatically cheaper, the economics and architecture around software change with it.</strong></p><p><strong>The constraint moves from producing code to trusting it.</strong> Trust increasingly depends on the environment around the model: context, verification, governance and evidence. As organizations run many models and agents at once, that layer has to be durable and independent of any one of them. And as agents encode more of an organization&#39;s workflows, expertise and operating knowledge, they should belong to the organization, not to whichever vendor supplies the model or cloud underneath them.</p><h2 id="the-constraint-that-built-an-industry">The constraint that built an industry</h2><p>For sixty years, software engineering has organized itself around one fact:</p><p><strong>Code is precious.</strong></p><p>It is expensive because turning business intent into reliable software requires scarce people who can hold complex abstractions in their heads. It is fragile because small mistakes can have enormous consequences. And complexity accumulates faster than any individual can absorb. Much of how we build software descends from that constraint.</p><p>We preserve old systems because rebuilding them is risky. We bridge between technologies instead of replacing them. Technical debt survives for years because paying it down competes with something customers need this quarter.</p><p>We optimize heavily for developer productivity because developers produce the scarce resource. Fragmented tools, inconsistent environments and awkward processes are tolerated if changing them might slow engineers down.</p><p>Then there is the ceremony: reviews, approvals, release gates, security checks, change processes and increasingly sophisticated testing. Much of it exists to protect an asset that is expensive to create and expensive to get wrong. And most of the value never gets built at all. For every idea that makes it onto a roadmap, many more never survive the economics of scarce engineering capacity.</p><p><strong>We spend enormous energy protecting the cost of change because change has always been expensive.</strong></p><p>That constraint is beginning to break. And when a constraint this fundamental moves, the rest of the system eventually moves with it.</p><h2 id="every-abstraction-reveals-the-next-constraint">Every abstraction reveals the next constraint</h2><p>This has happened before.</p><p>Humans once programmed computers directly in machine instructions. Assembly abstracted the machine. Higher-level languages moved the abstraction again. Each layer made one problem dramatically cheaper and exposed the one hiding behind it.</p><p>Nobody mourns hand-written assembly. We got a bigger problem to work on.</p><p>Large language models are obviously not compilers in the technical sense. They are probabilistic systems, not deterministic transformations with defined semantics. But economically, the analogy is useful: they dramatically reduce the human effort required to move from intent to implementation.</p><p>The distinction that matters is this:</p><p><strong>Code production is becoming abundant. Good software is not.</strong></p><p>Models can generate implementation far faster than humans can. That does not mean the implementation is correct, secure, performant, compliant, maintainable or even what the business intended. That gap is the point. When code was scarce, the hard problem was producing it. As code becomes abundant, the hard problem becomes trusting it.</p><table><thead><tr><th><strong>When code is precious</strong></th><th><strong>When code is abundant</strong></th></tr></thead><tbody><tr><td>Preserve legacy because rebuilding is expensive</td><td>Rebuild when doing so is cheaper than continuing to bridge</td></tr><tr><td>Optimize heavily for developer output</td><td>Optimize for business outcomes and learning speed</td></tr><tr><td>Carry technical debt for long periods</td><td>Retire debt when the economics make sense</td></tr><tr><td>Pursue only the highest-confidence ideas</td><td>Test many more ideas cheaply</td></tr><tr><td>Use process to limit costly mistakes</td><td>Use constraints and verification to govern high-volume change</td></tr></tbody></table><br /><p><strong>The cost of typing hid the harder problems. AI is exposing them.</strong></p><h2 id="cheap-iteration-changes-the-strategy">Cheap iteration changes the strategy</h2><p>One reasonable objection is that typing code was never the hardest part.</p><p>The harder part is deciding what to build. Requirements are ambiguous. Customers change their minds. Teams misunderstand one another. Important edge cases appear only after software meets reality.</p><p>All true.</p><p>But that argument assumes the cost of being wrong stays the same. Discovering after six weeks that a requirement was misunderstood is expensive. That expense creates pressure to be right upfront. Requirements documents, architectural reviews and careful planning are rational responses to expensive iteration.</p><p><strong>Make iteration cheap and the strategy inverts.</strong></p><p>You stop trying to eliminate uncertainty before implementation and start trying to learn faster.</p><p>There is another consequence that may prove even more important. Engineering organizations accumulate enormous amounts of knowledge that never becomes part of the software itself. An experienced engineer knows which service is fragile. Someone remembers why a deployment failed three years ago. A security engineer remembers the class of mistake that caused the last incident. Today, much of that learning lives in human heads. When implementation becomes cheap, more of it can become executable.</p><p>A production failure becomes a regression test. A security incident becomes a policy. A performance requirement becomes an automated constraint. A compliance obligation becomes continuous validation.</p><p><strong>Learning turns into code.</strong></p><p>Not literally all of it, and executable constraints do not eliminate judgment. Policies can be wrong. Tests can encode yesterday’s assumptions. But organizational knowledge can increasingly become persistent, inspectable and revisable instead of disappearing when the person who learned it leaves. That is a different kind of institutional memory, and it is one reason code abundance can improve quality rather than simply increase volume.</p><p>Amplitude recently published a <a href="https://amplitude.com/3x" rel="">striking example</a> of what a broader overhaul of this kind can produce. Over six months, it tripled the number of pull requests it shipped while reported monthly bugs fell from 715 to 319. That does not prove that more AI-generated code creates better software. It does show that much higher change volume does not have to imply proportionally lower quality.</p><h2 id="cost-per-accepted-change">Cost per accepted change</h2><p>The economic unit I think matters most in this transition is not cost per line of code.</p><p>It is <strong>cost per accepted change</strong>.</p><p>A useful software change includes generation, environment setup, context, verification, review, remediation and governance. AI is collapsing the generation term, which makes everything else proportionally more important. An organization that makes generation ten times faster but leaves CI, review and validation untouched will not become ten times faster.</p><p><strong>It will simply move the queue.</strong></p><p>That is exactly what the <a href="https://www.tocinstitute.org/theory-of-constraints.html" rel="">Theory of Constraints</a> predicts: remove one bottleneck and the system exposes the next one. We are now starting to see that happen.</p><h2 id="what-happens-when-agents-reach-production">What happens when agents reach production</h2><p>Stripe built internal coding agents called <a href="https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents" rel="">minions</a>. More than a thousand pull requests merged at Stripe each week are produced entirely by minions. Humans review them, but the code itself is agent-generated.</p><p>Amplitude documented a <a href="https://amplitude.com/3x" rel="">six-month overhaul</a> of its development pipeline. Pull-request cycle time fell from 5.2 hours to 44 minutes. Frontend CI fell from roughly thirty minutes to three or four.</p><p>Spotify has been operating a background coding agent called <a href="https://engineering.atspotify.com/2025/11/spotifys-background-coding-agent-part-1" rel="">Honk</a> and has documented more than 1,500 AI-generated pull requests merged into production.</p><p>These are unusually capable engineering organizations, so their experiences should not be treated as proof that every enterprise is about to work the same way. What makes them useful is that they have gone far enough to expose the next constraints, and several of the same ones keep appearing.</p><p>Amplitude’s development environment had accumulated manual setup, slow CI and inconsistent tooling. That survived for years because code production limited how quickly changes entered the system. Agents removed that throttle, and validation and review became the stoppage points.</p><p>So Amplitude rebuilt the foundations: faster environment setup, dramatically faster CI and fewer inconsistent patterns that confused both humans and agents. Very little of that work was AI. It was infrastructure work that became necessary because AI changed the throughput of the system.</p><p>Many organizations are currently focused on choosing the best coding model.</p><p>In practice, <strong>a thirty-minute CI pipeline defeats every model you point at it.</strong></p><p>Agents do not eliminate existing engineering constraints. They expose them faster.</p><h2 id="three-modes-not-one-maturity-curve">Three modes, not one maturity curve</h2><p>Most descriptions of AI adoption imply a single journey from traditional development to fully autonomous development. I don’t think that is how the enterprise transition will happen. Three modes will coexist for a long time.</p><p><img alt="Diagram of the three modes of AI-assisted development" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787591354/fcloou7pnrjtc2hzvrre.png" /></p><p><strong>Mode 1: Human-controlled legacy</strong></p><p>Systems with undocumented dependencies and operational knowledge that still resides in people. Many will remain largely human-controlled until they are retired or rewritten.</p><p><strong>Mode 2: Agentically accelerated development</strong></p><p>Humans remain in control while agents assist with implementation, testing, migration, review, documentation and security analysis. This is where most enterprise development sits today and where I expect much of the near-term economic value.</p><p>It is not merely a waiting room for autonomy. One of the most valuable uses of agents may be making modernization projects economical when they were previously impossible to justify.</p><p><strong>Mode 3: Autonomous development</strong></p><p>Agents operate the implementation loop while humans provide intent, constraints and oversight. The important dividing line is not greenfield versus brownfield. It is whether execution remains human-controlled or can safely operate as a closed loop.</p><p>A practical way to tell where a system sits is to ask three questions: Can an agent make a useful change with the context available? Can that change be verified without a person reading every line? If it is wrong, does the system catch it or does a person have to? The more those answers depend on a person, the closer the workload remains to Mode 1, regardless of how capable the model is.</p><p>Trying to force every workload into Mode 3 too early is likely to be one of the more expensive mistakes organizations can make during this transition.</p><h2 id="the-pipeline-runs-the-inner-loop">The pipeline runs the inner loop</h2><p>Once Amplitude reduced frontend CI below five minutes, the remote pipeline became fast enough that engineers could launch many pieces of work in parallel and review the results as they returned.</p><p>Stripe reached a similar architecture from another direction, giving minions isolated, pre-warmed development environments so many jobs can run concurrently without interfering with one another.</p><p>Most coding-agent workflows today still begin on a laptop. That is a reasonable place to start. It is unlikely to be where the architecture ends.</p><p>In an agentic system, the pipeline becomes the natural place to run the inner development loop:</p><p><strong>generate → build → test → validate → review → remediate → repeat</strong></p><p>The agent keeps working against those signals until it can return something that is not merely plausible code, but functional, verified software that satisfies the constraints the organization has defined.</p><p>Faster inner loops also increase the need for coordination. A thousand individually valid changes can still pull a system in conflicting directions. As AI compresses the gaps between SDLC phases, alignment on intent has to become continuous rather than periodic.</p><p>There are architectural reasons this loop belongs close to the repository and the systems around it.</p><p>The pipeline already sits next to the code, build system, test infrastructure, security controls, deployment configuration and much of the history surrounding a change. The closer the agent is to those systems, the less context it has to reconstruct through repeated remote calls and fragmented APIs, and the faster it can receive feedback. That matters because machine-speed development can turn even small amounts of latency and context loss into system-level bottlenecks.</p><p>Running the loop there also preserves the evidence around the work. The identity that initiated the change, the policies that applied, the tests that ran, the reviews that occurred, the remediation the agent performed and the artifact that ultimately shipped can all remain connected.</p><p>That is important for more than efficiency. It is what makes increasing autonomy governable.</p><p>The pipeline moves from being a gate at the end of development to becoming the system that runs the development loop itself.</p><p>Agentic development therefore scales best where execution, context and governance are close to the work. The faster an agent can access the right context, receive deterministic feedback and prove what it did, the more of the loop it can safely complete before handing work back to a person.</p><p>The question is no longer simply: Did the code compile?</p><p>It is: Was the change actually good, and can we prove it?</p><h2 id="autonomy-is-governed-not-granted">Autonomy is governed, not granted</h2><p>As model capability improves, I believe governance increasingly becomes the binding constraint on autonomy.</p><p>The stalled enterprise programs I have seen rarely stall because nobody can get a model to generate code.</p><p>They stall on more basic questions. What is the agent allowed to do? How do we prove what it did? Who is accountable when it is wrong?</p><p><a href="https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2" rel="">Stripe’s architecture</a> illustrates the pattern. Minions combine open-ended agent loops with deterministic software for git, linting and testing. They run in isolated environments, pass local checks before pushing, and selectively run tests from a suite containing more than three million tests.</p><p>The agent can be creative.</p><p><strong>The system decides where creativity stops.</strong></p><p>Amplitude uses a risk model to distinguish work that can merge automatically from work that should still route to a person.</p><p>Spotify’s <a href="https://engineering.atspotify.com/2025/12/feedback-loops-background-coding-agents-part-3" rel="">verification architecture</a> gives agents access to verification without exposing the underlying implementation of the verifiers, and runs required checks before a pull request can be opened.</p><p>None of these organizations solved reliability with a better prompt. They combined capable models with deterministic gates, isolation, verification, policy and evidence, and that is what allows autonomy to expand safely.</p><p>It also explains why this becomes harder outside the best-resourced technology companies. Most enterprises will not want to invent their own agent authorization model, isolation layer, verification architecture and evidence system. They will expect to inherit much of it.</p><p>That is increasingly what we mean at GitLab when we talk about <strong>speed with control</strong>.</p><p>Speed without control eventually stops because the organization cannot accept the risk. Control without speed leaves the value of AI unrealized. The two have to be designed together.</p><h2 id="accountability-can-become-clearer">Accountability can become clearer</h2><p>One concern about autonomous development is that accountability disappears into the machine. That can happen if the system is designed poorly. But autonomous development can also make accountability more explicit if identity, policy, context and evidence are preserved as part of execution.</p><p>Humans remain accountable for defining the constraints: the security policy, the performance threshold, the compliance obligation, and what the organization learned from the last incident. The control plane has to make execution against those constraints provable.</p><p>Amplitude’s description of its <a href="https://amplitude.com/3x" rel="">SOC 2 approach</a> is instructive. Its automated approval process relies on documented criteria, logged decisions and an override path rather than requiring a human to click approve on every qualifying change. The human moves from approving every action toward owning the criteria under which actions are permitted, which can be both more consequential work and more auditable.</p><h2 id="the-durable-layer">The durable layer</h2><p>One possible conclusion from increasingly capable agents is that more of the software lifecycle collapses into the model and everything around it becomes commodity infrastructure.
I think the opposite is more likely.</p><p>As agents take on more of the implementation loop, the durable enterprise layer becomes even more important. Context, identity, policy, provenance, verification and organizational memory cannot live only inside whichever model or agent is executing the work. They have to persist across them.</p><p>And over time, I expect the product development lifecycle to use multiple purpose-built models.</p><p>Different tasks will optimize for different things: reasoning quality, latency, cost, security, domain specialization or where the model can run. Some will use frontier models. Others will use smaller models or open-weight models deployed closer to the customer&#39;s data and infrastructure. The best model for planning may not be the best model for code review, security analysis, testing or remediation.</p><p>That is a familiar pattern as technologies mature. A single general-purpose capability gives way to a more specialized stack optimized for different workloads.</p><p>In that world, the model is not the durable architecture. It is an execution component.</p><p><strong>The more models and agents an enterprise uses, the more valuable the common context, controls and history around them become.</strong></p><p>This also changes the boundary of what we have traditionally called the software development lifecycle.</p><p>The SDLC was built around people moving work through a sequence of stages: plan, build, test, secure, deploy and operate. As AI compresses those stages into continuous agentic loops, I expect the distinction between developing software and developing the product itself to blur.</p><p>You can think of the emerging model as a <strong>Product Development Lifecycle, or PDLC</strong>: business intent enters the system, agents turn it into software, verification and governance determine what can proceed, production results feed back into the next decision, and the loop continues.</p><p>At sufficient scale, that begins to look less like a traditional development process and more like a <strong>software factory</strong>: a system that continuously turns intent and business signals into verified software.</p><p>But a software factory is not simply a collection of autonomous agents. The durable layer underneath it is what preserves context, identity, policy, evidence and organizational memory while models and agents change.</p><h3 id="context-and-provenance">Context and provenance</h3><p>Anthropic’s <a href="https://claude.com/blog/the-ai-native-sdlc-playbook" rel="">AI-native SDLC playbook</a> is useful because it makes the transition concrete. It describes intent, specifications and plans becoming machine-readable artifacts; institutional knowledge being made available to Claude; hooks and skills enforcing behavior; MCP connecting agents to tools; and version history preserving evidence of the work. I think those are useful patterns, and many organizations will start there.</p><p><strong>Our architectural bet at GitLab is that agentic development requires a new platform architecture, not just a better model.</strong></p><p>That architecture has four essential capabilities: <strong>an agent platform, machine-scale execution, durable context and governance.</strong> I’ll return to each of these below.</p><p>Enterprises will use more than one model. They will use agents from multiple vendors alongside agents they build themselves. And increasingly, they will want to build agents that encode their own workflows, expertise and operating policies alongside the excellent agents vendors will keep producing.</p><p>The platform therefore has to support both paths: customers should be able to bring the agents they choose and build, customize and operate agents they own.</p><p>Those agents will act across code, planning, security, CI, deployment and production systems, often at the same time. They should not have to be rebuilt because an organization changes its preferred model or cloud. And the organization’s context, policy, identity and history should not become captive to whichever model, agent vendor or infrastructure provider happens to be in favor at the time.</p><p><strong>The model should be replaceable. The agent should belong to the customer. The organization’s memory and controls should endure.</strong></p><p>That is why I believe the architectural pressure is toward a model- and cloud-neutral platform, not toward a single model, agent vendor or cloud becoming the system of record.</p><p>That does not require one vendor to own every artifact involved in creating software. Identity can federate. Events can move between systems. Context can be indexed. Policies can be centralized. MCP and other open interfaces can give agents access to tools across the enterprise. Many organizations will build this way.</p><p>The harder problem with this pattern is preserving the chain from intent to action to outcome as autonomous systems operate across that environment.</p><p>A requirement authorizes a change. The change executes under a particular identity and policy regime. Verification produces evidence. A deployment ships it. Production produces a result. Those relationships form a causal graph.</p><p>None of this is new. What is changing is the frequency at which those relationships have to remain intact. At human development velocity, reconstructing provenance across several systems after the fact is painful but often survivable.</p><p><strong>At machine velocity, provenance becomes part of the execution path itself.</strong></p><p>When the relevant relationships live natively in a common system or control plane, an agent can reason across them directly. When they live across several systems, something has to reconstruct them. That is possible. But it creates work around identity, synchronization, policy consistency, semantic mapping and evidence. At machine volume, reconciliation itself can become a system constraint.</p><p>Spotify’s experience illustrates the same problem inside a codebase. In one <a href="https://engineering.atspotify.com/2026/4/background-coding-agents-dataset-migrations-honk-part-4" rel="">migration</a>, Honk encountered multiple pipeline frameworks. The more standardized frameworks were easier to automate; inconsistency made reliable context much harder. At human speed, inconsistent context creates friction. At machine speed, it degrades output repeatedly.</p><p>The important unit in autonomous development is increasingly not the individual artifact. It is the relationship among intent, code, policy, evidence, deployment and outcome.</p><p>This is why I believe the inner software-development loop will experience increasing pressure toward a common control plane. Not because a single vendor must own every tool, but because trustworthy autonomy requires those relationships to remain coherent while machines act at a scale humans never did. Platforms that already hold many of them have a structural advantage over systems that have to reconstruct them afterward.</p><h3 id="records-not-files">Records, not files</h3><p>One emerging practice in agentic development is to capture intent, specifications and implementation plans as Markdown files committed to a repository.</p><p>I like the instinct. Making intent explicit, versioned and readable by humans and agents creates immediate value.</p><p>But there is an important distinction between a file and a governable record. At enterprise scale, the system eventually needs to answer questions a file cannot answer on its own:</p><ul><li>Who can modify this?</li><li>What state is it in?</li><li>Who approved it?</li><li>Which policy version applied?</li><li>What deployment resulted from it?</li><li>How do I query across ten thousand of these?</li></ul><p>Teams can recreate those capabilities through conventions around Markdown, but those are exactly the capabilities systems of record have spent years developing.</p><p>The best architecture may present Markdown as an interface to agents while keeping a structured, governed record underneath it.</p><p>The interface can remain simple. The system underneath cannot.</p><h3 id="agents-should-belong-to-the-organization">Agents should belong to the organization</h3><p>Agents need context about how an organization builds software: repository structure, coding conventions, build commands, testing practices, architecture rules and known failure modes.</p><p>Spotify calls this work <a href="https://engineering.atspotify.com/2025/11/context-engineering-background-coding-agents-part-2" rel="">context engineering</a> and found it essential for producing reliable, mergeable pull requests across real codebases. As that knowledge grows, it becomes an organizational asset.</p><p>The same is increasingly true of the agent itself.</p><p>An enterprise agent may encode years of accumulated instructions, workflows, tool access, evaluation criteria and operating policy. Over time, that can become some of the most valuable intellectual property in the engineering organization.</p><p>It should belong to the organization, not to a model vendor, cloud provider or proprietary runtime.</p><p>There is another reason ownership matters: it allows the system to compound.</p><p>Every time an agent acts, the organization produces evidence about what worked and what did not. Which changes were accepted? Which were rejected? Where did a human intervene? What failed in production? Which constraints caught the problem?</p><p>Preserved over time, that evidence becomes an internal evaluation set grounded in the organization’s own codebase and outcomes, not a public benchmark. The organization can use it to evaluate models, improve its agents, refine their instructions and workflows, and determine where greater autonomy is actually warranted.</p><p>The result is a feedback loop: the agent does work, the system measures the outcome, and what the organization learns makes the next generation of agents better at that organization’s work.</p><p>This extends the idea that learning turns into code. Learning can become tests and policies, but it can also become evals, context and improved agents.</p><p>That is not an argument against any particular vendor. We build on Anthropic models today and expect to keep doing so. A customer running Claude Code should be able to keep running it, with the same enterprise context, identity and audit trail as any agent we build ourselves.</p><p>The point is, customers must be able to choose a model, change it, use different models for different tasks and run their agents on the infrastructure their business requires. They should also be able to bring agents from other vendors and give them access to the same enterprise context and controls.</p><p><a href="https://agents.md/" rel=""><code>AGENTS.md</code></a> is one example of an open format for providing project instructions and context to coding agents. GitLab supports it, and we will continue to support open formats like it because an organization’s accumulated knowledge should remain portable if the organization changes models, agents or vendors.</p><p>The principle matters more than the filename.</p><p><strong>Own the agent. Own its instructions. Own the context it learns from. Keep the models and infrastructure underneath it a choice.</strong></p><h2 id="anyone-can-ship">Anyone can ship</h2><p>One of the more interesting results in <a href="https://amplitude.com/3x" rel="">Amplitude’s experience</a> was not about engineers. After improving its development setup, validation and review, designers, product managers and marketers began producing code changes themselves. Non-engineers went from essentially zero pull requests to roughly five percent.</p><p>This is an early version of a change I expect to become much larger. As implementation becomes cheaper, the boundary between deciding what to build and building it starts to collapse. Product managers can turn intent into working software. Designers can move from prototypes to implementation. Engineers can operate at a higher level of abstraction across the product. And people outside traditional R&amp;D organizations can increasingly build solutions directly from the expertise they already have.</p><p>I think <strong>Builder</strong> becomes a useful way to describe this broader role. A Builder may be an engineer, designer, product manager, security expert, marketer or domain expert. What they share is the ability to express intent, direct agents, evaluate the result and turn an idea into something that works.</p><p>This is also part of the shift toward the PDLC described earlier. As the distance between product intent, design, implementation and feedback collapses, software development becomes less of a specialized handoff within engineering and more of a continuous product-building loop.</p><p>That does not mean expertise disappears or that everyone becomes an engineer. The opposite may be true. As agents absorb more implementation work, domain expertise and judgment become more valuable. The person overseeing an agentic system may not be an engineering manager supervising coding agents. It may be a domain expert who can express what should happen and recognize whether the outcome is right.</p><p>The result is a much larger population of people who can create software without making engineering judgment abundant.</p><p>Scarce human attention moves upward: toward intent, architecture, constraints, difficult tradeoffs, exceptions and evaluating whether the system produced the outcome the organization actually wanted.</p><p><strong>The work of building software expands beyond engineering. The need for judgment does not.</strong></p><h2 id="integration-moves-outward">Integration moves outward</h2><p>None of this means integration stops mattering. I expect its center of gravity to move.</p><p>Inside the high-frequency execution loop, tighter integration becomes more valuable because agents depend on fast feedback, consistent identity, shared context and enforceable policy.</p><p>Outside that loop, integration becomes even more important because the intent driving software increasingly originates elsewhere in the business.</p><p>Customer support contains customer pain. CRM contains commitments. Data platforms contain usage and business outcomes. Observability describes production health. Compliance systems define obligations. Those systems provide signals, intent and constraints, and the development control plane turns them into governed action.</p><p>Over time, I expect the distance between a business signal and a software response to collapse dramatically.</p><p>The most important development platform in that world may therefore be defined less by how many developer tools it replaces and more by how effectively it connects governed software execution to the systems that describe what the business needs.</p><h2 id="the-new-platform-architecture">The new platform architecture</h2><p>That future requires a platform architecture built around four capabilities:</p><p><strong>Agent platform:</strong> the ability to create, customize and operate agents the organization owns, using the models and infrastructure it chooses, while also supporting agents customers bring from elsewhere.</p><p><strong>Execution:</strong> next generation Git, artifact management, CI/CD and the capacity to build, test, deploy and operate software at both human and machine scale.</p><p><strong>Context:</strong> a coherent picture of the requirement, code, history, business priority and constraints surrounding the work.</p><p><strong>Governance:</strong> enforceable boundaries around security, compliance, quality, identity and permissions, plus the visibility people need to understand what agents did, why it was allowed, and where human attention is required.</p><p>As autonomy increases, governance becomes less about approving every action and more about helping people understand and steer the exceptions. Policies and tests automate decisions the organization has already made; the harder cases are the ones nobody anticipated.</p><p><strong>The ultimate constraint on autonomy may not be whether the agent can act. It may be whether a person can understand and steer what hundreds of agents are doing at once.</strong></p><p>These four architectural layers reinforce one another. Agents act through the execution layer. Execution creates signals that enrich context. Better context makes agents more capable and governance more precise. Stronger governance allows those agents to operate with greater autonomy.</p><p>Enterprises will need those capabilities to work as a coherent platform, even when many different models, clouds, products and agents participate underneath it.</p><h2 id="what-this-means-in-practice">What this means in practice</h2><p>These aren’t only architectural principles for some distant autonomous future. They’re already changing what we build.</p><p>In <a href="https://about.gitlab.com/blog/gitlab-act-2/" rel="">Act 2</a>, we described several architectural bets based on the assumption that software development would increasingly operate at machine scale. At <a href="https://about.gitlab.com/blog/gitlab-transcend-announcements/" rel="">GitLab Transcend</a> in June, we showed the first pieces of that architecture, with demos of each.</p><p><strong>Customers need a place to build and run agents they own.</strong> GitLab Duo Agent Platform is our platform for creating, customizing and operating those agents around an organization’s own workflows and expertise. Customers can choose the models underneath them and run them across the infrastructure their business requires, while continuing to use external agents alongside them. The goal is not to force every enterprise into one agent ecosystem. It is to give customers a place to build agents they can own and evolve without being locked to a single model or cloud.</p><p><strong>Execution has to operate at machine scale.</strong> Agents clone, branch, retry and trigger pipelines at volumes traditional source-control architecture was never designed for. Our next-generation source control is being rebuilt around that reality, including server-side access patterns that allow an agent to retrieve what a task actually requires rather than repeatedly moving an entire repository. In internal testing, those changes have produced task execution up to 50 times faster while moving dramatically less data.</p><p><strong>Context has to become infrastructure.</strong> GitLab Orbit connects code, work items, pipelines, deployments and production signals into a context graph across the software lifecycle. Agents can query those relationships directly instead of reconstructing them through dozens of disconnected calls. Importantly, that context is not reserved for GitLab’s own agents. Third-party agents can use the same organizational memory.</p><p><strong>Governance has to surround the agent, not live inside its prompt.</strong> Governance for Agents is designed to apply identity, policy, approval and audit controls around agent actions so organizations can increase autonomy without giving up evidence or accountability.</p><p>Those are different engineering projects, but they come from the same premise:</p><p><strong>If implementation is becoming abundant, the platform underneath it has to let enterprises build and bring agents, then give all of them execution, context and control at machine scale.</strong></p><h2 id="what-to-do-in-the-next-ninety-days">What to do in the next ninety days</h2><p><strong>Measure cost per accepted change.</strong> Track the elapsed time from generated change to accepted change, then decompose it across environment, CI, review, remediation and governance. Many teams will find generation is already a small part of the total.</p><p><strong>Time your CI.</strong> If a full pipeline takes much longer than five minutes, improving that may matter more than switching models.</p><p><strong>Write down the criteria, not just the approvals.</strong> Pick one class of low-risk change and define what would make it safe to merge without a human. That becomes the beginning of executable governance.</p><p><strong>Make context portable.</strong> Put repository instructions and operating knowledge in an open, versioned format that both people and agents can use.</p><p><strong>Choose which business signals should enter the development loop directly.</strong> Support, observability and compliance systems increasingly contain intent and constraints. Decide which signals should become governed software work without requiring a person to retype them.</p><h2 id="where-we-go-from-here">Where we go from here</h2><p>Code generation is becoming increasingly commoditized. That does not mean software development is becoming free. It means the economics are changing.</p><p>The useful unit is not cost per line of code.</p><p>It is <strong>cost per accepted change</strong>.</p><p>As generation gets cheaper, everything around generation becomes proportionally more important: environment, context, verification, governance and evidence.</p><p>This also changes where scarce human judgment goes. Engineering judgment does not become abundant because implementation does. Human attention moves upward: toward architecture, intent, constraints, difficult exceptions and evaluating whether the system produced the outcome the organization wanted.</p><p>And it changes where I think strategic value will accrue in the software-development stack. For sixty years, implementation was scarce enough that much of software engineering revolved around protecting developer capacity and limiting the cost of change. AI changes that constraint.</p><p><strong>When implementation becomes abundant, trust becomes scarce.</strong></p><p>Trust requires more than a model producing a plausible answer. It requires evidence that the software was produced under the right constraints and behaved the way the organization intended. Enterprises can assemble those capabilities from many products, and many will. But as machine activity increases, fragmented control planes create an increasingly expensive reconciliation problem.</p><p>The architectural pressure is therefore not necessarily toward one vendor owning everything.</p><p>It is toward a <strong>model- and cloud-neutral platform where enterprises can bring agents they choose, build and customize agents they own, and give all of them a common layer of execution, context and governance.</strong></p><p>That is the opportunity we see for GitLab.</p><p>The model may change. The cloud may change. The agent may come from a vendor or be built by the customer.</p><p><strong>The organization’s intelligence, context and controls have to survive all of them.</strong></p><p>Stripe, Spotify and Amplitude have shown what exceptional engineering organizations can build for themselves. Anthropic’s playbook now shows how quickly the operating model around software development is beginning to change. Most companies will not have a platform team available to recreate all of that machinery from scratch. They will need to inherit much of it.</p><p><strong>Software engineering spent sixty years protecting a scarce resource. It will spend the next decade governing an abundant one.</strong></p><p>It’s a better problem.</p><hr /><h3 id="sources">Sources</h3><ul><li>GitLab, <em>GitLab Act 2</em>, May 11, 2026. <a href="https://about.gitlab.com/blog/gitlab-act-2/" rel="">about.gitlab.com/blog/gitlab-act-2</a></li><li>GitLab, <em>Built for the agentic engineering era</em>, June 10, 2026, with demo videos from GitLab Transcend. <a href="https://about.gitlab.com/blog/gitlab-transcend-announcements/" rel="">about.gitlab.com/blog/gitlab-transcend-announcements</a></li><li>Anthropic, <em>The AI-Native SDLC Playbook</em>, August 21, 2026. <a href="https://claude.com/blog/the-ai-native-sdlc-playbook" rel="">claude.com/blog/the-ai-native-sdlc-playbook</a></li><li>Amplitude EPD, <em>Speedrunning Software: How We 3×’d PRs in 6 Months</em>. <a href="https://amplitude.com/3x" rel="">amplitude.com/3x</a></li><li>Stripe, <em>Minions: Stripe’s one-shot, end-to-end coding agents</em>. <a href="https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents" rel="">Part 1</a> and <a href="https://stripe.dev/blog/minions-stripes-one-shot-end-to-end-coding-agents-part-2" rel="">Part 2</a></li><li>Spotify Engineering, <em>Background Coding Agents</em>. <a href="https://engineering.atspotify.com/2025/11/spotifys-background-coding-agent-part-1" rel="">Part 1</a>, <a href="https://engineering.atspotify.com/2025/11/context-engineering-background-coding-agents-part-2" rel="">Part 2</a>, <a href="https://engineering.atspotify.com/2025/12/feedback-loops-background-coding-agents-part-3" rel="">Part 3</a>, <a href="https://engineering.atspotify.com/2026/4/background-coding-agents-dataset-migrations-honk-part-4" rel="">Part 4</a></li><li><a href="https://agents.md/" rel=""><code>AGENTS.md</code></a>, an open format for guiding coding agents</li><li>Goldratt, <em>Theory of Constraints</em>. <a href="https://www.tocinstitute.org/theory-of-constraints.html" rel="">tocinstitute.org</a></li></ul>]]></content>
        <author>
            <name>Bill Staples</name>
            <uri>https://about.gitlab.com/blog/authors/bill-staples/</uri>
        </author>
        <published>2026-08-24T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[When your backlog outgrows your team, GitLab scales remediation]]></title>
        <id>https://about.gitlab.com/blog/gitlab-scales-remediation/</id>
        <link href="https://about.gitlab.com/blog/gitlab-scales-remediation/"/>
        <updated>2026-08-20T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Security teams have historically struggled to keep up with triage and remediation when development was happening at human speed. Today, that challenge is exacerbated by developers writing and shipping code at machine speed with AI.</p><p>At the same time, AI is helping attackers find and exploit vulnerabilities faster in production. <a href="https://www.verizon.com/business/resources/reports/dbir/" rel="">Verizon&#39;s 2026 Data Breach Investigations Report</a> found vulnerability exploitation overtook credential abuse as the top breach entry point. Vulnerability exploitation accounts for 31% of breaches versus just 13% in previous years, and only 26% of known exploited vulnerabilities were remediated this year, down from 38%. That means more breaches are starting with a vulnerability that was already sitting in production, unpatched.</p><p>In GitLab 19.3, teams can now run <a href="https://docs.gitlab.com/user/application_security/vulnerabilities/false_positive_detection/" rel="">Static Application Security Testing (SAST) False Positive Detection</a> and <a href="https://docs.gitlab.com/user/application_security/vulnerabilities/agentic_vulnerability_resolution/" rel="">Agentic SAST Vulnerability Resolution</a>, in bulk, on their existing vulnerability backlog.</p><h2 id="dismiss-false-positives-and-remediate-vulnerabilities-in-bulk">Dismiss false positives and remediate vulnerabilities in bulk</h2><p>Most teams have a known vulnerabilities backlog already running in production, far more than any team has time to open and triage one at a time. That used to be a workload problem. Now it&#39;s a timing problem too: The same AI accelerating development is accelerating exploitation, which means findings that sit in the backlog longer carry more risk than they used to.</p><p>GitLab addresses this with two layers of automated triage and remediation. The first covers <strong>active</strong> vulnerabilities in production. With GitLab 19.3, teams can bulk-select multiple vulnerabilities to run agentic flows, SAST False Positive Detection and Agentic SAST Vulnerability Resolution, against the vulnerability backlog in production. SAST False Positive Detection analyzes a finding&#39;s surrounding code and returns a confidence score and explanation for whether it&#39;s a real risk or a false positive. Agentic SAST Vulnerability Resolution takes findings confirmed as real risk and opens a ready-to-merge fix that remediates the vulnerabilities, so a developer reviews and merges the fixes instead of writing it from scratch.</p><p>This applies to all SAST vulnerabilities in the vulnerability report, no matter the scanner origin or severity. You can import findings from any third-party scanner that outputs <a href="https://docs.gitlab.com/user/application_security/detect/sarif/" rel="">SARIF</a>; GitLab ingests them into a unified vulnerability report.</p><p>With bulk SAST False Positive Detection and Agentic SAST Vulnerability Resolution teams can cut years of accumulated risk in a single action instead of one vulnerability at a time and to reduce the risk of vulnerabilities being exploited in production.</p><p>See these two features in action:</p><iframe src="https://player.vimeo.com/video/1219621778?title=0&amp;byline=0&amp;portrait=0&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameBorder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerPolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Bulk false positive detection and vulnerability resolution"></iframe><script src="https://player.vimeo.com/api/player.js"></script><p>The second layer covers any <strong>new</strong> vulnerabilities identified. Teams can configure pipelines to run SAST False Positive Detection and Agentic SAST Vulnerability Resolution automatically on Critical and High severity vulnerabilities (<a href="https://click-through-demo-generator-v-2-d63870.gitlab.io/demos/sast-fp-vr-enablement/" rel="">watch an interactive demo</a>). New findings get triaged automatically, and when one is deemed a real risk, GitLab creates a ready-to-merge fix before anyone has to open the finding by hand.</p><h2 id="start-automating-triage-and-clearing-your-backlog-today">Start automating triage and clearing your backlog today</h2><p>With bulk triage and remediation developers spend less time confirming false positives and more time shipping fixes that drive down real risk.</p><p><a href="https://gitlab.com/-/trials/new?glm_content=default-saas-trial&amp;glm_source=about.gitlab.com/gitlab-duo-agent-platform/" rel="">Start a free trial of GitLab Duo Agent Platform</a> to try it today.</p><h2 id="faq">FAQ</h2><p><strong>Do bulk SAST False Positive Detection and Agentic Vulnerability Resolution consume GitLab Duo Agent Platform credits?</strong><br />
Yes. Please see <a href="https://about.gitlab.com/pricing/" rel="">the pricing page</a> for further details.</p><p><strong>Does bulk triage and remediation cost more credits than running detection one at a time?</strong><br />
No. Each finding still costs the same per-execution rate; bulk just queues many at once instead of triggering them manually one by one.</p><p><strong>Which vulnerabilities qualify for bulk triage?</strong><br />
Any SAST vulnerability in your vulnerability report, no matter the scanner origin or severity.</p><p><strong>Will running this on my whole backlog overwhelm my pipeline?</strong><br />
No. Concurrency limits keep the bulk job from competing with your pipeline&#39;s other work, so clearing thousands of findings doesn&#39;t come at the cost of build capacity.</p><p><strong>Can I stop a bulk job once it&#39;s running?</strong><br />
Yes. A progress indicator tracks the job while it runs, and you can cancel it at any point.</p>]]></content>
        <author>
            <name>Alisa Ho</name>
            <uri>https://about.gitlab.com/blog/authors/alisa-ho/</uri>
        </author>
        <published>2026-08-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Run agentic software delivery inside the boundaries you already trust]]></title>
        <id>https://about.gitlab.com/blog/gitlab-dedicated-ai-gateway/</id>
        <link href="https://about.gitlab.com/blog/gitlab-dedicated-ai-gateway/"/>
        <updated>2026-08-20T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Many enterprises choose <a href="https://about.gitlab.com/dedicated/" rel="">GitLab Dedicated</a> for a clear reason: a single-tenant instance, managed by GitLab, in a cloud region they select. That isolation already covers source code, project data, and the software development lifecycle they run on GitLab.</p><p>GitLab Dedicated customers can now deploy the AI Gateway for the <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">GitLab Duo Agent Platform</a> inside their single-tenant SaaS infrastructure, so AI-processed data stays in their environment and chosen region.</p><h2 id="gitlab-dedicated-as-the-critical-infrastructure-for-software-delivery">GitLab Dedicated as the critical infrastructure for software delivery</h2><p>GitLab Dedicated is deployed in your preferred AWS region, and hosted and maintained by GitLab. You can bring your own encryption keys. No private cloud installation required.</p><p>GitLab operates the instance, including high availability and disaster recovery, and maintains 99.9% monthly availability for core services. Updates to GitLab Dedicated follow a stability-first cadence, with instances on the <a href="https://docs.gitlab.com/administration/dedicated/releases/#versioning-model" rel="">previous minor version (N-1)</a> relative to the current GitLab release.</p><p>That is the infrastructure organizations already trust when they scale software delivery under audit: guardrails you can take to a regulator, SaaS operations you do not staff, and an availability target that holds when the platform is in the critical path.</p><h2 id="trust-should-travel-with-every-agent">Trust should travel with every agent</h2><p>Agentic workflows demand more from your software development lifecycle beyond the AI coding: increased pipeline volume, greater risk for vulnerabilities introduced, context that needs to travel with every agent and flow, among others.</p><p>The isolation, residency, and service-level requirements that already apply to GitLab Dedicated should apply to that inference path too, especially with growing adoption of agentic software development.</p><h2 id="adopt-ai-while-staying-compliant">Adopt AI while staying compliant</h2><p>Here is what&#39;s new with the introduction of AI Gateway for GitLab Dedicated:</p><ul><li><strong>Keep AI processing in the tenancy.</strong> The AI Gateway runs in the Dedicated single-tenant environment, aligned with data residency.</li><li><strong>Bring your own models.</strong> Connect models you control so inference follows your policy, not a one-size default outside your region.</li><li><strong>Unlock Duo Agent Platform where you already run GitLab.</strong> Agentic work becomes available under the Dedicated deployment model your auditors already understand.</li></ul><p>GitLab Dedicated customers using GitLab Duo Agent Platform can connect the AI Gateway to Amazon Bedrock as their model backend, so inference stays in their AWS region. Or you can use your own preferred model providers.</p><p>If you have specific model requirements, data classification rules, or existing commitments, you can identify models hosted in Amazon Bedrock for your team to use with GitLab Duo Agent Platform. All <a href="https://docs.gitlab.com/user/duo_agent_platform/" rel="">capabilities of Duo Agent Platform</a>, including its top use cases such as automating custom code reviews, fixing failed pipelines, and security analysis can now run against your chosen models.</p><h2 id="start-your-agentic-software-delivery-on-gitlab-dedicated">Start your agentic software delivery on GitLab Dedicated</h2><p>If you are on GitLab Dedicated, review <a href="https://docs.gitlab.com/administration/gitlab_duo_self_hosted/configure_duo_features/#add-a-self-hosted-model" rel="">how to add a self-hosted model</a>, validate model connectivity in a non-production project, and then expand agentic workflows under your existing change controls.</p><p>If you are not using GitLab Duo Agent Platform today, you can <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">start with a free trial</a>. If you are an existing subscriber to GitLab Dedicated, you can get started simply by <a href="https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/" rel="">turning on Duo Agent Platform</a> and start using the GitLab Credits <a href="https://docs.gitlab.com/subscriptions/gitlab_credits/#included-credits" rel="">that are included</a> with your subscription.</p>]]></content>
        <author>
            <name>Ozer Dondurmacioglu</name>
            <uri>https://about.gitlab.com/blog/authors/ozer-dondurmacioglu/</uri>
        </author>
        <published>2026-08-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Build custom flows in minutes with the Flow Creator agent]]></title>
        <id>https://about.gitlab.com/blog/flow-creator-agent/</id>
        <link href="https://about.gitlab.com/blog/flow-creator-agent/"/>
        <updated>2026-08-20T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p><a href="https://about.gitlab.com/blog/multi-step-software-delivery-with-agentic-flows/" rel="">Custom Flows</a> already let teams turn manual, multi-step work into automation that runs on GitLab events. But writing one meant learning the <a href="https://docs.gitlab.com/user/duo_agent_platform/flows/claude-edit-v1-flow-registry/" rel="">Flow Registry</a> schema first. That requirement is a real barrier. The people who understand a workflow best aren’t always the same ones who know a YAML schema.</p><p>In GitLab 19.3, the <a href="https://docs.gitlab.com/user/duo_agent_platform/agents/foundational_agents/flow_creator/" rel="">Flow Creator</a> agent removes that requirement. Describe the flow you want in your own words, and it responds with a complete, runnable definition.</p><h3 id="when-good-automations-stopped-at-the-schema">When good automations stopped at the schema</h3><p>Consider two people who know exactly what should be automated, but not how to build it.</p><ul><li><strong>The security analyst</strong> triages vulnerability reports every day and knows which patterns are false positives and who owns each affected dependency. None of that knowledge is captured in a schema they have never used.</li><li><strong>The planning lead</strong> knows what should happen next when a work item changes status. The automation is obvious to them. The Flow Registry syntax is not.</li></ul><p>Writing a flow meant learning that schema before any of this knowledge could become automation. That requirement limited who could author flows to people with schema familiarity, not people with process knowledge. The result is a gap between who understands the work and who can automate it. That gap effectively slows down automations across the entire software lifecycle especially where bottlenecks already lurk.</p><h3 id="bring-flow-building-to-everyone-who-understands-the-work">Bring flow building to everyone who understands the work</h3><p>Flow Creator is a <a href="https://docs.gitlab.com/user/duo_agent_platform/agents/foundational_agents/" rel="">foundational agent</a> within GitLab Duo Agent Platform, available via Agentic Chat. Invoke the agent, describe what you want the flow to do in plain language, and it produces a complete flow definition.</p><p>For example, <em>&quot;When a work item is created with the label <code>security-triage</code>, check it against our known false-positive patterns, find the affected dependency and its owner, and post a severity assessment as a comment.&quot;</em> This simple explanation gives the agent a trigger, steps, and an output target.</p><p>You don&#39;t have to get the description perfect on the first try either. If something is ambiguous or missing, like which project the flow should target or whether a step needs human approval, the agent confirms before it builds instead of guessing and returning a flow that runs against the wrong project or skips a needed approval.</p><h3 id="guardrails-hold-as-the-author-pool-grows">Guardrails hold as the author pool grows</h3><p>More people building flows does not mean looser guardrails. Every flow runs through a scoped service account under composite identity, so it can never reach further than the permissions of the person who ran it. That account is scoped to the top-level group and cannot access resources outside of its bounds. Authoring a flow and enabling it stay separate: Anyone can describe a flow to Flow Creator, but enabling one still requires the Maintainer role or higher. Group Owners and instance administrators can turn Custom Flows off entirely.</p><p><strong>See Flow Creator in action:</strong></p><iframe src="https://player.vimeo.com/video/1219636630?badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameBorder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerPolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="19.3 Demo - Flow Creator Agent"></iframe><script src="https://player.vimeo.com/api/player.js"></script><h2 id="how-it-works">How it works</h2><p>Flow Creator does three things behind the scenes:</p><ul><li><strong>Reads current documentation.</strong> The agent checks the Flow Registry documentation before every response, rather than answering from what it learned during training.</li><li><strong>Applies rules.</strong> These rules encode failure patterns seen in real flows, so common mistakes get caught before a session even starts.</li><li><strong>Runs a pre-output checklist.</strong> This check happens before any YAML is generated, catching issues early rather than after registration.</li></ul><p>Each rule corresponds to ways flows break today:</p><ul><li><strong>Missing project_id.</strong> The flow runs but has no clear target, so it acts against the wrong project or against nothing.</li><li><strong>Broken human in the loop gates.</strong> A flow meant to pause for approval proceeds without it.</li><li><strong>Wrong <code>sends_response_to</code> targets.</strong> The flow completes and writes its output somewhere nobody is looking.</li><li><strong>Missing stopping instructions.</strong> The agent keeps working beyond task completion.</li></ul><p>The output is a full, runnable definition, not a fragment to assemble. Paste it into the configuration editor when you create a flow from a project or from the <a href="https://docs.gitlab.com/user/duo_agent_platform/ai_catalog/" rel="">AI Catalog</a>. Then, choose whether the flow is private, restricted, or public, and add the triggers that should start it.</p><h2 id="run-your-first-custom-flow">Run your first custom flow</h2><p>Flow Creator ships in GitLab 19.3 as part of GitLab Duo Agent Platform. If you have been waiting on someone else to write your automation, you don’t have to anymore.</p><p>Read the <a href="https://docs.gitlab.com/user/duo_agent_platform/flows/custom/" rel="">Custom Flows</a> documentation to see how to register and enable a flow, then describe the one you want to Flow Creator. Start a <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">free trial of GitLab Duo Agent Platform</a>. On the Free tier, you can <a href="https://docs.gitlab.com/subscriptions/gitlab_credits/#for-the-free-tier-on-gitlabcom" rel="">sign up in a few simple steps</a>. If you&#39;re already on GitLab Premium or Ultimate, you can <a href="https://docs.gitlab.com/user/duo_agent_platform/turn_on_off/" rel="">turn on Duo Agent Platform</a> and use the <a href="https://docs.gitlab.com/subscriptions/gitlab_credits/#included-credits/" rel="">GitLab Credits included with your subscription</a>.</p>]]></content>
        <author>
            <name>Rebecca Carter</name>
            <uri>https://about.gitlab.com/blog/authors/rebecca-carter/</uri>
        </author>
        <published>2026-08-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[GitLab 19.3 released]]></title>
        <id>https://docs.gitlab.com/releases/19/gitlab-19-3-released/</id>
        <link href="https://docs.gitlab.com/releases/19/gitlab-19-3-released/"/>
        <updated>2026-08-20T00:00:00.000Z</updated>
        <published>2026-08-20T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[From chaos to context: Building an AI dev workflow]]></title>
        <id>https://about.gitlab.com/blog/building-an-ai-dev-workflow/</id>
        <link href="https://about.gitlab.com/blog/building-an-ai-dev-workflow/"/>
        <updated>2026-08-19T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>There&#39;s a particular kind of frustration that happens when prompting an AI assistant with the same correction multiple times in a single session. The marvels of modern large language models (LLMs) make it so you&#39;re working with the most enthusiastic apprentice you&#39;ll ever have. However, that apprentice also happens to be an amnesiac. “Yes, I really do want my commit messages formatted that way, we&#39;ve had this conversation three times already.”</p><p>Or perhaps you&#39;ve experienced the trouble of trying to orchestrate several parallel AI sessions, only to watch them independently start solving the same problems and deleting each other&#39;s work.</p><p>These frustrations led me down a path of iteration. I worked on early renditions of two GitLab AI features: <a href="https://docs.gitlab.com/ee/user/application_security/analyze/duo/" rel="">Explain this vulnerability</a> and <a href="https://docs.gitlab.com/ee/user/application_security/vulnerabilities/#vulnerability-resolution" rel="">Resolve this vulnerability</a> features. They felt naive at the time, and I wanted more from them.</p><p>Agentic AI delivered that. Instead of one-shot suggestions I had to prompt for and paste back, an agent could read the codebase, make the change, and run the tests on its own. It was doing the work rather than just advising on it. From there, I moved through GitLab Duo Custom Agents, VS Code integrations, and eventually <a href="https://opencode.ai" rel="">OpenCode</a>, an open source agent that describes itself as helping you &quot;write code in your terminal, IDE, or desktop.&quot;</p><p>Along the way, I&#39;ve distilled what&#39;s been working for me. AI coding assistants are genuinely transformative, but they need your engineering instincts to guide them. They amplify both good decisions and bad ones, so direction matters. The tools will keep changing, but here&#39;s what&#39;s helped my day-to-day engineering so far.</p><h2 id="an-optimized-ai-workflow">An optimized AI workflow</h2><p>Before diving into the principles, it&#39;s worth showing what an optimized AI workflow actually looks like in practice.</p><p><strong>Priority comes to me.</strong> When I start a session, the AI loads my active sessions, unresolved blockers, standing directives, and recent decisions. It then fetches my GitLab todos, active MRs, and tracked epics, presenting them in my defined priority order: stale items first (things falling through the cracks), review requests from others (don&#39;t block teammates), questions needing my response, my own blocked MRs, and finally everything else. I no longer spend time figuring out what I should be doing; the context comes to me.</p><p><strong>The focus paradigm has shifted.</strong> Software development typically required hours of intense, uninterrupted focus to get anything meaningful done. That&#39;s changed. In a 15- or 30-minute window, I can ask what&#39;s at the top of the queue, have the AI load context for that item (prior decisions, blockers, relevant procedures), and start delegating coding and testing. The AI brings me up to speed nearly instantly, rather than me needing to rebuild mental context from scratch.</p><p><strong>Parallel work on multiple merge requests.</strong> I use git worktrees with isolated test databases to have AI sessions work on multiple merge requests simultaneously. Each worktree gets its own session, its own database, and a claiming system prevents sessions from stepping on one another. The AI runs tests, ensures the code works, and I review for correctness.</p><p><strong>Recurring tasks are made into procedures.</strong> For a priority epic I track, the AI handles weekly status updates by fetching current state from GitLab, comparing to the previous week&#39;s state to compute deltas, and drafting the update with progress metrics. The procedure is documented in my directives so any session can execute it consistently.</p><p><strong>Token efficiency matters.</strong> I&#39;ve contributed improvements to GitLab&#39;s <a href="https://docs.gitlab.com/api/rest/" rel="">REST and GraphQL API</a> and the <a href="https://gitlab.com/vglafirov/opencode-gitlab-plugin" rel="">OpenCode GitLab plugin</a> to reduce context overhead, and built a local workflow Model Context Protocol (<a href="https://about.gitlab.com/topics/ai/model-context-protocol/" rel="">MCP</a>) server that encodes common patterns. Instead of the AI reconstructing how to do something from scratch each time, it calls an optimized tool that handles the data gathering, leaving reasoning to the <a href="https://about.gitlab.com/blog/what-is-a-large-language-model-llm/" rel="">LLM</a>. This makes responses faster and keeps token usage manageable.</p><p><strong>Active delegation is the underlying pattern.</strong> I preserve top-level context and alignment while the AI executes specific tasks. Before working on any merge request, the AI claims it to prevent conflicts, loads its history from memory, and checks for relevant directives. I maintain oversight of direction; the AI maintains execution velocity.</p><h2 id="write-surgical-directives-not-vague-instructions">Write surgical directives, not vague instructions</h2><p>Every session starts fresh. Without intervention, you&#39;ll re-explain the same preferences, the same conventions, the same quirks of your codebase.</p><p>The solution is explicit, persistent directives. Agentic AI tools have begun standardizing on AGENTS.md configuration files that load as boot context. But the key insight isn&#39;t that you need directives; it&#39;s that they need to be specific.</p><p>A vague instruction like &quot;be careful with comments&quot; doesn&#39;t work. The AI will acknowledge it and then do whatever it was going to do anyway. What works is something specific:</p><blockquote><p>&quot;ALWAYS verify user IDs exist before posting comments under their name. STOP and ask if unsure.&quot;</p></blockquote><p>The all-caps keywords aren&#39;t just for emphasis. They seem to make the AI respond more reliably to the instruction.</p><p><strong>Pattern to apply:</strong> When the AI tool makes a mistake, don&#39;t just correct it. Ask it what directive would prevent this mistake next time. Have that dialogue, then ask it to note it for next time. Over time, you build a set of instructions tailored to your actual workflow, not hypothetical best practices.</p><p>My <a href="https://gitlab.com/ghavenga/agents-config" rel="">agents-config repository</a> used to contain over a dozen specialized configuration files that emerged this way: code review guidelines, merge request workflows, database review procedures, and comment writing standards. Each one exists because I was doing it often enough that it made sense to proceduralize and get the AI to execute it consistently. The memory system I describe later in this article lightened this approach; those directives now live in searchable memory rather than static files. The repository now contains practical examples and a <a href="https://gitlab.com/ghavenga/agents-config/-/blob/master/USAGE-GUIDE.md" rel="">usage guide</a> showing how I work day-to-day.</p><h2 id="parallel-sessions-need-coordination-primitives">Parallel sessions need coordination primitives</h2><p>Running multiple AI sessions simultaneously can be efficient, if you can manage it well. Three terminals, three assistants, three parallel streams of work. But without coordination, you&#39;ll probably encounter familiar problems:</p><ul><li>Sessions editing the same files without knowing the other exists</li><li>Multiple sessions working on the same item (assuming you have a way to claim work, which you probably don&#39;t yet)</li><li>Contradictory decisions made in isolation</li><li>Sessions deleting each other&#39;s work, or blithely committing it with their own changes to unrelated MRs</li><li>Duplicated effort because neither session knows what the other did</li></ul><p>If you&#39;ve done any concurrent programming, you&#39;ll recognize these as classic coordination problems. The solutions are similar, too: You need primitives for claiming work, tracking state, and sharing context.</p><p>My first solution was file-based working notes. They worked, but they weren&#39;t searchable, weren&#39;t linked to the work they described, and didn&#39;t persist well across days. I needed something that could surface relevant context automatically.</p><p>This led me to build <a href="https://gitlab.com/ghavenga/opencode-memory" rel="">opencode-memory</a>, a persistent semantic memory system. The architecture reflects solutions to problems I kept solving by directive: hybrid search (keywords for exact terms, semantics for fuzzy recall), session coordination through claim/release, and boot context that surfaces critical directives automatically.</p><p>The system has grown considerably since its first iteration. It&#39;s now a full knowledge graph with over 760,000 indexed code entities, 15,000+ memories including conversation summaries, and 27,000 links between them. When GitLab announced <a href="https://docs.gitlab.com/orbit/" rel="">Orbit</a>, a knowledge graph that indexes your entire software development lifecycle (SDLC), it lined up almost exactly with the direction I&#39;d been taking locally. Orbit answers cross-SDLC questions like &quot;what breaks if I change this service?&quot; by connecting code, merge requests, and pipelines. My memory module already indexed my codebase locally for fast recall, so rather than reinvent the wider view I wired Orbit in to enhance it. The local memory holds session-level context like decisions, blockers, and procedures, and Orbit adds GitLab&#39;s broader SDLC graph on top. One of the best outcomes is that when I mention a function in conversation, the AI recalls exactly where it lives without me having to look it up.</p><p>Prior decisions also surface automatically when starting work on a merge request. Blockers persist until explicitly resolved. Procedures defined once are available forever. Reminders automatically bring themselves to my attention where they matter. And the combined graph, my local memory plus Orbit&#39;s SDLC data, answers those questions far more efficiently and effectively than a plain text search ever did.</p><h2 id="check-before-you-build">Check before you build</h2><p>No idea is unique. Searching for memory systems for AI coding assistants reveals dozens of approaches. Somebody probably already built what you were thinking about in a coffee-fueled AI rampage three weeks before you imagined it. There&#39;s even a PyPI package called <code>opencode-memory</code> that does something very similar to what I built, just with a different vector database backend.</p><p>The barrier to building what you need has dropped so dramatically that many people independently arrive at similar solutions. You can go from idea to working prototype in a week.</p><p>I&#39;d recommend checking whether something already exists before spinning up a new project. If it almost solves your problem, consider whether contributing might be better than creating another variant. This advice is as old as software development itself; AI just exacerbates it a hundredfold.</p><p>My memory system barely offered much over existing solutions at first. It&#39;s only after months of iteration and deep GitLab integration that I feel it&#39;s somewhat more justified. I did at least contribute improvements back to the <a href="https://gitlab.com/vglafirov/opencode-gitlab-plugin" rel="">OpenCode GitLab plugin</a> rather than forking it, because that&#39;s where my changes could help the most people.</p><p>The question worth asking yourself: Did I bother to look if something already exists and solves this problem, or has AI made it so easy to code that I&#39;ve ignored all forms of due diligence?</p><h2 id="from-active-recall-to-passive-context">From active recall to passive context</h2><p>The vectorized memory search was an immediate win. I transitioned to using it the same day I built it. Recalling useful details became trivial. The next challenge was getting the AI to know there was something worth remembering implicitly, without me prompting it every time.</p><p>I&#39;d made progress: token-efficient memory of specific procedures, a growing corpus of innate recall memories. But it felt like I was just rebuilding AGENTS.md with fancy additions. I needed something smarter.</p><p>The solution was proactive context injection. Instead of the AI calling recall tools explicitly, the system now automatically searches for relevant memories before each interaction. When I mention a merge request number, relevant prior decisions appear in context without me asking. When I&#39;m about to write a comment, the comment-writing guidelines surface automatically. Most of the time, at any rate. It&#39;s still a work in progress, but each day I hone it a little further.</p><p>This shift from active to passive recall made a real difference. Over 30 days, the system achieved around 91% effectiveness at surfacing relevant context automatically. Sessions with proactive injection needed zero explicit recall calls on average, compared to 17 without it. It&#39;s not perfect; there are still moments where I need to tell the AI to remember something or to improve. But it&#39;s an iterative process, and it&#39;s getting better.</p><p>The remaining misses were instructive. Many happened while I was iterating on how boot context loading worked. The fix was a boot gate: a minimal trigger in the startup context that tells the AI to pause and load directives before doing anything else. Even with proactive injection, sometimes the AI needs to be told to stop and think first.</p><h2 id="what-ai-still-cant-do">What AI still can&#39;t do</h2><p>AI can execute procedures reasonably consistently, if those procedures are in context. It can improve its own instructions, if prompted to think about it. It can coordinate across sessions, if given the primitives to do so.</p><p>But AI doesn&#39;t notice things implicitly. It doesn&#39;t feel that a procedure is awkward. It doesn&#39;t recognize that you&#39;ve hit this same problem three times this week. It doesn&#39;t have the pattern recognition that comes from years of debugging production systems at 2 a.m. while wondering if perhaps carpentry might have been a better career choice. At least, not yet.</p><p>The sweet spot seems to be using AI to eliminate menial work, providing the right context at the right times, and watching for what it misses. You provide strategic oversight and pattern recognition. The AI provides tireless execution and enthusiasm for tasks we once found tedious and time-consuming. That&#39;s extremely empowering.</p><p>I&#39;ve watched AI enthusiastically build features while introducing concurrency bugs into its own tooling, blocking itself with synchronous operations. It had no idea. In hindsight, this was an alignment problem. I could have planned with it earlier to ensure a good async pattern. I&#39;d hoped it would build a better pattern from the start, but I was being optimistic. One redirect from me pointing out the architectural flaw, and it was fixed in minutes.</p><p>That&#39;s the pattern: human spots the problem, AI executes the fix rapidly. I could have done it myself, just not as quickly. AI can&#39;t detect meta-inefficiencies yet, though I&#39;m sure someone&#39;s busy writing a dedicated agent for that.</p><h2 id="invest-in-your-tools">Invest in your tools</h2><p>Working this way means accepting constant change. My day-to-day work has shifted completely, and repeatedly, in the space of months. Compare that to how workflows changed slowly over years earlier in my career.</p><p>Don&#39;t try to settle into a &quot;new normal.&quot; It will change. The tools that help today may be obsolete next week at the rate we&#39;re going.</p><p>Rather, iterate on your tooling itself. The workflow that helps you work faster becomes the subject of optimization. I&#39;ve contributed new API endpoints to GitLab, including <a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/230537" rel="">group uploads</a> and <a href="https://gitlab.com/gitlab-org/gitlab/-/merge_requests/220801" rel="">GraphQL mutations for MR workflows</a>, specifically because I needed them for AI-assisted development.</p><p>It&#39;s a meta-loop: better tools lead to more productivity, which creates more capacity to improve tools. There&#39;s an old adage: &quot;Give me six hours to chop down a tree and I will spend the first four sharpening the axe.&quot; I spend a fair bit of time these days sharpening my axe. I&#39;ve never had a better grindstone.</p><h2 id="the-takeaway">The takeaway</h2><p>Code is a commodity now. We&#39;re no longer paid primarily to type it. We&#39;re paid to know what code should exist. To recognize when an approach is fundamentally flawed. To spot inefficiencies before they become problems. To provide the direction that turns raw capability into useful outcomes.</p><p>I&#39;d been working on guidance for how GitLab&#39;s CREDIT values applied to AI use, and then <a href="https://about.gitlab.com/blog/gitlab-act-2/" rel="">GitLab Act 2</a> retired CREDIT entirely, replacing it with new operating principles built for the agentic era. A good example of how fast this space shifts: My own guidance was overtaken before it landed. But the core insight remains: Getting this balance right matters at an organizational level, not just a personal one. AI should augment human work, not substitute for it.</p><p>The tools will keep evolving. The specifics will change. But this fundamental insight won&#39;t: AI amplifies human judgment. It shouldn&#39;t replace it, though it tries if you let it, usually at the cost of code quality and stability. Vibe coding can take you far, but even with the most thorough AI reviews, there&#39;s an assurance of quality and careful consideration in design that I&#39;ve not yet seen AI provide on its own.</p><p>Several colleagues at GitLab have started using variations of this workflow, and watching them experience the same &quot;aha&quot; moments has been validating. One recently messaged me: &quot;Definitely noticed an improvement in my sessions since using the plugin,&quot; meaning the opencode-memory module. I won&#39;t pretend that didn&#39;t make my entire day. The questions shift from &quot;how do I get AI to do X&quot; to &quot;how do I give AI the context it needs to do X well.&quot; That&#39;s the real unlock: not the tools themselves, but the realization that context is the bottleneck.</p><p>Fascinatingly, the better you get at this, the more you start to realize that you may be the bottleneck. But sometimes that&#39;s also an indication that your own processes could be improved even more. I don&#39;t feel like I&#39;ve reached a maximum yet, not by far. Different tasks benefit from different approaches, even when AI-empowered, and there&#39;s still plenty of experimenting to do.</p><p>One final note on pace: The memory system has seen 143 commits in under a month. It&#39;s built on MCP, which means it works with any agent that speaks the protocol: not just OpenCode, but Claude CLI, Cursor, and others. By the time you read this, I&#39;ve probably added features I haven&#39;t thought of yet. That&#39;s the nature of working in this space right now. The tools evolve faster than the documentation.</p><p><em>The tools mentioned in this article are open source: <a href="https://gitlab.com/ghavenga/agents-config" rel="">agents-config</a> for AI directive configurations, and <a href="https://gitlab.com/ghavenga/opencode-memory" rel="">opencode-memory</a> for persistent session memory.</em></p>]]></content>
        <author>
            <name>Gregory Havenga</name>
            <uri>https://about.gitlab.com/blog/authors/gregory-havenga/</uri>
        </author>
        <published>2026-08-19T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[From OpenTofu to Argo CD: GitLab as your AWS control plane]]></title>
        <id>https://about.gitlab.com/blog/gitlab-as-your-aws-control-plane/</id>
        <link href="https://about.gitlab.com/blog/gitlab-as-your-aws-control-plane/"/>
        <updated>2026-08-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Configuring cloud-based environments is complex, as it requires considering networking, subscriptions, services, and all the components that make up the underlying infrastructure. Manual setup is error-prone, inconsistent, and difficult to reproduce.</p><p>This tutorial shows how to set up a fully automated cloud environment using GitLab as the main operations brain. All the cloud infrastructure is defined as code (hosted on GitLab) and deployed on AWS with <a href="https://opentofu.org/" rel="">OpenTofu</a> through GitLab CI/CD pipelines. On top of this, these pipelines also handle the build and deployment of a real web application, using GitOps practices with <a href="https://argoproj.github.io/cd/" rel="">Argo CD</a>.</p><h2 id="why-infrastructure-as-code-and-gitops">Why infrastructure as code and GitOps?</h2><p>First, it is important to understand why infrastructure as code (IaC) and GitOps matter, and how GitLab brings these practices together in a single platform.</p><p>IaC ensures environments are:</p><ul><li><strong>Reproducible</strong>: The same configuration can be deployed anywhere.</li><li><strong>Versioned</strong>: Every change is tracked in a Version Control System (VCS), with Git as the primary choice.</li><li><strong>Automated</strong>: No human interaction needed.</li></ul><p>GitOps extends these principles into the application lifecycle. Instead of manually applying changes to Kubernetes clusters (or other infrastructure), the desired state of applications lives in Git. A GitOps operator like Argo CD continuously ensures the cluster reflects what is in the repository. This brings:</p><ul><li><strong>Consistency</strong> between environments</li><li><strong>Faster recovery</strong> with rollbacks that are as simple as reverting a commit</li><li><strong>Better collaboration</strong> because teams can review and approve changes via merge requests</li><li><strong>Increased security</strong> through deployments that are performed without requiring direct access to the cluster by the developers</li></ul><p>GitLab combines all the capabilities required for this approach:</p><ul><li><strong><a href="https://docs.gitlab.com/user/get_started/get_started_managing_code/" rel="">Source code management</a></strong>: Track infrastructure and application code in one place.</li><li><strong><a href="https://docs.gitlab.com/ci/" rel="">CI/CD pipelines</a></strong>: Automate provisioning with OpenTofu and deployments with Kubernetes manifests.</li><li><strong><a href="https://docs.gitlab.com/user/infrastructure/iac/terraform_state/" rel="">Terraform states</a></strong>: Store and manage infrastructure state files securely.</li><li><strong><a href="https://docs.gitlab.com/user/packages/container_registry/" rel="">Container Registry</a></strong>: Build, store, and manage container images next to the code and pipelines.</li></ul><p>With GitLab, everything from provisioning cloud infrastructure to application delivery happens through one platform.</p><p>To follow this tutorial, you will need:</p><ul><li>Basic knowledge of GitLab CI/CD pipelines and Git</li><li>Familiarity with iac (Terraform or OpenTofu) and GitOps</li><li>An AWS account</li><li>A Kubernetes cluster (EKS is provisioned in the tutorial)</li><li>Dockerfile for the sample web application</li></ul><p>This tutorial includes instructions to:</p><ul><li><a href="#provision-a-complete-aws-environment-networking-eks-using-opentofu">Provision a complete AWS environment (networking, EKS) using OpenTofu</a></li><li><a href="#configure-kubernetes-tools-argo-cd-certmanager-automatically">Configure Kubernetes tools (Argo CD, CertManager) automatically</a></li><li><a href="#deploy-a-sample-web-application-using-gitops-principles-with-argo-cd">Deploy a sample web application using GitOps principles with Argo CD</a></li><li><a href="#build-and-package-a-sample-web-application-with-gitlab-cicd">Build and package a sample web application with GitLab CI/CD</a></li></ul><p>Read on to learn how to reproduce this example in your own GitLab environment. You can find the source code of this <a href="https://gitlab.com/gitlab-partners-public/satec/aws-summit-2025-demo" rel="">example</a> in the <a href="https://gitlab.com/gitlab-partners-public/satec" rel="">SATEC Public Demo Group</a>.</p><h2 id="provision-a-complete-aws-environment-networking-eks-using-opentofu">Provision a complete AWS environment (networking, EKS) using OpenTofu</h2><p>The first step is to provision the cloud infrastructure with OpenTofu (the open-source Terraform fork). We can declaratively define networking components and create an Amazon EKS cluster.</p><p>To make this process reproducible and secure, we rely on GitLab CI/CD variables instead of hardcoding values. These variables allow us to configure the AWS environment dynamically across pipelines.</p><p>The following environment variables are required and need to be declared under <strong>Settings &gt; CI/CD &gt; Variables</strong> in the parent group (to be inherited by all projects):</p><ul><li><strong>TF_VAR_region</strong>: AWS region where the infrastructure will be created (e.g., eu-west-1)</li><li><strong>TF_VAR_instance_type</strong>: EC2 instance type for worker nodes (e.g., t3.medium)</li><li><strong>TF_VAR_instance_count</strong>: Number of worker nodes in the cluster</li><li><strong>TF_VAR_cluster_name</strong>: Name of the EKS cluster to provision</li><li><strong>AWS_ACCESS_KEY_ID</strong>: AWS access key for authentication</li><li><strong>AWS_SECRET_ACCESS_KEY</strong>: AWS secret key for authentication</li></ul><p>All variables are defined as <em>protected</em> in GitLab, and sensitive ones such as the AWS secret access key are also <em>masked</em>, ensuring they are only exposed in secure CI/CD contexts. Security can be further enhanced by following <a href="https://docs.gitlab.com/ci/variables/#cicd-variable-security" rel="">this CI/CD variables tutorial</a>. Separating code from configuration makes the pipeline both flexible and independent of environments.</p><p>Once configured, the OpenTofu pipeline can be executed automatically to:</p><ul><li>Provision networking resources (VPC, subnets, gateways, routing tables)</li><li>Provision EKS control plane and worker node groups</li><li>Trigger the pipeline to deploy Argo CD and CertManager into the new cluster</li></ul><p><img alt="How the infrastructure provisioning process works" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786721848/raobe2rbwouolxuakbdl.png" /></p><p>The diagram above illustrates how the infrastructure provisioning process works.</p><ol><li>A GitLab pipeline is triggered from the infrastructure repository, which contains the Terraform/OpenTofu configuration files.</li><li>GitLab CI/CD executes the OpenTofu commands, using the integrated Terraform state backend to securely manage the state file in GitLab.</li><li>OpenTofu connects to AWS through configured providers to create all required resources: the VPC, subnets, gateways, load balancers, and the Amazon EKS cluster distributed across multiple availability zones.</li></ol><p>At the end of this stage, the AWS environment and Kubernetes cluster are fully provisioned and ready to operate.</p><p><img alt="AWS environment and Kubernetes cluster fully provisioned" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786721902/z6fbu78rw9xprgkrju9p.png" /></p><p>The final step of this process (post-deploy) is to trigger a secondary GitLab pipeline (located in a dedicated repository), which is responsible for deploying Argo CD and CertManager automatically into the new EKS cluster using the Helm Provider.</p><h2 id="configure-kubernetes-tools-argo-cd-certmanager-automatically">Configure Kubernetes tools (Argo CD, CertManager) automatically</h2><p>Once the AWS infrastructure and the EKS cluster have been successfully provisioned, the next step is to configure the Kubernetes tools required to operate the environment, which are Argo CD, CertManager, and Ingress NGINX Controller.</p><p>This process is fully automated through a secondary GitLab pipeline hosted in a separate repository.</p><p><img alt="Secondary GitLab pipeline hosted in a separate repo" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786721969/tgupmzi9q557f0nivgb7.png" /></p><p>The execution of this second pipeline is triggered automatically from the infrastructure pipeline, using a trigger job once the OpenTofu provisioning stage has completed successfully.</p><p>In practice, this means that the deployment of these core components happens seamlessly as part of the same end-to-end workflow, there are no manual steps required. The deployment itself is handled by OpenTofu using the Helm provider, which allows managing Helm charts declaratively as code through GitLab.</p><p>A simplified workflow looks like this:</p><ol><li><strong>The first pipeline</strong> provides the EKS cluster and triggers the second one via a GitLab trigger job.</li><li><strong>The second pipeline</strong> uses OpenTofu with the Helm provider to:<ul><li>Download Kubeconfig from the EKS cluster.</li><li>Install Argo CD (for GitOps management).</li><li>Install CertManager (for automated TLS certificate management).</li><li>Install Ingress NGINX Controller (for ingress traffic routing). <em>(Note: Ingress NGINX Controller is being deprecated in the Kubernetes ecosystem; for new deployments, it is recommended to consider alternatives such as Traefik or an API gateway-based approach.)</em></li></ul></li><li>Each Helm release is defined in the OpenTofu configuration, allowing upgrades or rollbacks through standard infrastructure code changes.</li><li>Finally, <strong>a third pipeline</strong> is triggered to deploy the sample web application. This pipeline applies to the Argo CD application manifests that define the web app and its associated resources.</li></ol><h2 id="deploy-a-sample-web-application-using-gitops-principles-with-argo-cd">Deploy a sample web application using GitOps principles with Argo CD</h2><p>Once all the core Kubernetes components (Argo CD, CertManager, and Ingress NGINX Controller) are installed, the final stage of the automation pipeline begins. This step is executed automatically right after the Helm chart installation process is completed.</p><p>A third GitLab pipeline is triggered, responsible for deploying a sample web application into the newly created EKS cluster through Argo CD.</p><p>The diagram below shows the overall process:</p><p><img alt="GitLab uses the kubeconfig generated by OpenTofu to connect to the cluster and apply the Argo CD application manifests that define the desired state of the web application" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786722029/aw36utqgxlj6ipmw6rgj.png" /></p><p>In this stage, GitLab uses the kubeconfig generated by OpenTofu to connect to the cluster and apply the Argo CD application manifests that define the desired state of the web application.</p><p>The pipeline:</p><ul><li><strong>Downloads and updates the kubeconfig</strong> file to connect to the EKS Cluster.</li><li><strong>Updates credentials and repository information</strong> dynamically using CI/CD variables.</li><li><strong>Creates the Kubernetes namespace</strong> for the application (aws-summit-app).</li><li><strong>Applies the Argo CD manifests</strong> (repository.yaml, application.yaml, cluster-issuer.yaml).</li><li><strong>Creates a Container Registry secret</strong> to allow the application to pull images securely from GitLab using an access token.</li></ul><p>All these actions are performed automatically through <a href="https://about.gitlab.com/blog/ultimate-guide-to-ci-cd-fundamentals-to-advanced-implementation/" rel="">GitLab CI/CD</a>, with no manual intervention.</p><p>Once the manifests are applied, the Argo CD controller detects them and synchronizes the application state with the repository, deploying the sample web page into the EKS cluster.</p><p>The result is a fully operational Kubernetes environment, where:</p><ul><li>Infrastructure is provisioned with OpenTofu.</li><li>Cluster tools are installed declaratively with Helm.</li><li>Applications are deployed and managed via GitOps using Argo CD.</li></ul><p>This approach ensures end-to-end automation, traceability, and reproducibility, all managed by GitLab.</p><h2 id="build-and-package-a-sample-web-application-with-gitlab-cicd">Build and package a sample web application with GitLab CI/CD</h2><p>Before the application is deployed through Argo CD, it must first be built, containerized, and published to the GitLab Container Registry.</p><p>This process is managed through a dedicated CI/CD pipeline and follows a GitOps repository structure, where the source code and Kubernetes manifests are stored in separate repositories.</p><p><img alt="A dedicated CI/CD pipeline that follows a GitOps repository structure" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786722075/nqscss5qee8sdydrej0d.png" /></p><p>In this setup, the GitLab group is organized into two main sections:</p><ul><li><strong>Apps/</strong> contains the source code repositories for the applications.<ul><li>Example: aws-summit-app/web holds the source code of the sample web page.</li></ul></li><li><strong>Deployments/</strong>  contains the repositories with Kubernetes manifests for each application.<ul><li>Example: aws-summit-app/web within Deployments defines the Kubernetes manifests to deploy the web page (deployment.yaml, ingress.yaml, service.yaml, etc.).</li></ul></li></ul><p>This separation enables a clean GitOps workflow because application code and deployment configurations are independent but remain synchronized through automation.</p><p>The CI/CD pipeline defined in the application repository automates the following tasks:</p><ul><li><strong>Build and package:</strong> The pipeline compiles the source code and builds the Docker image using the provided Dockerfile.</li><li><strong>Publish to the GitLab Container Registry:</strong> The image is automatically tagged and pushed to the integrated GitLab Container Registry.</li><li><strong>Update deployment manifests:</strong> Once the image has been published, the pipeline executes a job that updates the image reference inside the corresponding deployment repository (under Deployments/aws-summit-app/web).</li></ul><p>These are performed automatically by committing the new image tag or creating a merge request.</p><p><img alt="Committing the new image tag or creating a merge request" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786722113/zdh3bk63swvxibhaw5m9.png" /></p><p>Once the commit or merge request is created, Argo CD automatically detects the change in the deployment repository and synchronizes the updated manifests with the Kubernetes cluster, ensuring that the new application version is deployed without any manual intervention.</p><h2 id="summary">Summary</h2><p>This tutorial demonstrated how to build a fully automated cloud environment with GitLab as the central hub, achieving the goals we set out at the beginning: infrastructure that is reproducible, versioned, and automated. By combining OpenTofu for infrastructure provisioning, GitLab CI/CD for pipeline orchestration, and Argo CD for GitOps-based application delivery, teams can manage the entire lifecycle — from cloud resources to running applications — through a single platform.</p><p>As a GitLab partner with deep expertise in cloud infrastructure and DevSecOps practices, <a href="https://www.clober.tech/" rel="">Clober</a> (<a href="https://www.satec.es/en" rel="">SATEC</a> group) can help organizations implement similar automated environments tailored to their specific needs.</p><p><em>Note: This blog post is based on a live demo originally presented at <a href="https://aws.amazon.com/es/events/summits/madrid/" rel="">AWS Summit Madrid</a> 2025 by the <a href="https://www.clober.tech/" rel="">Clober</a> DevSecOps team (<a href="https://www.satec.es/en" rel="">SATEC</a> group).</em></p><h2 id="resources">Resources</h2><ul><li><a href="https://docs.gitlab.com/ci/components/" rel="">GitLab CI/CD components</a></li><li><a href="https://docs.gitlab.com/user/packages/container_registry/" rel="">GitLab Container Registry</a></li><li><a href="https://docs.gitlab.com/user/infrastructure/iac/terraform_state/" rel="">GitLab-managed Terraform state management</a></li></ul>]]></content>
        <author>
            <name>Javier Urones Monteserín, Clober</name>
            <uri>https://about.gitlab.com/blog/authors/javier-urones-montesern-clober/</uri>
        </author>
        <author>
            <name>Péter Bozsó</name>
            <uri>https://about.gitlab.com/blog/authors/pter-bozs/</uri>
        </author>
        <published>2026-08-18T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Avoid the massive end-to-end tax of default full history clones]]></title>
        <id>https://about.gitlab.com/blog/git-clone-override-policy/</id>
        <link href="https://about.gitlab.com/blog/git-clone-override-policy/"/>
        <updated>2026-08-18T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>It&#39;s easy to think of <code>git clone</code> as a client-side operation, but the settings of this operation impact the server side and all networks in between. When you run a default full history clone, the server has to walk the entire history, build a pack file for it (that&#39;s what &quot;counting objects&quot; is actually doing), and ship it over the wire. The client then unpacks all of it and checks out a full working tree. Every layer, client CPU, network, the Git server&#39;s pack-building compute, and disk, pays for the size of that request. Make the request smaller and the whole stack gets cheaper at once, not just your laptop.</p><p>Agentic AI turns up the pressure on this in a way normal developer workflows don&#39;t. An agent doing repository work can clone far more often, and far less predictably, than a human ever would. If the default is a full history clone, you&#39;re now paying that tax at agent scale.</p><p>GitLab is working hard on the backend to serve large repositories faster. But you can also change what you ask for. Options like shallow clones (<code>--depth=1</code>), single-branch clones, and partial clones (<code>--filter=blob:none</code>) let you fetch only what a job actually needs. A more precise request immediately reduces peak load, unreliability, wait time, and cost. And every future backend improvement compounds on top of these leaner requests.</p><p>In <a href="https://about.gitlab.com/blog/supercharge-your-git-workflows/" rel="">Supercharge your Git workflows</a>, I walked through how <a href="https://gitlab.com/gitlab-accelerates-embedded/git-clone-perf/git-much-faster" rel="">Git Much Faster</a> benchmarks the settings that cut clone times by up to 93% and disk usage by up to 98%: disabling compression, widening the HTTP buffer, shallow and partial clones, and sparse checkout that skips binaries. Great numbers. There&#39;s just one catch: Every place that clones the repo has to be meticulously updated with many lines of optimizing code. A developer&#39;s laptop, a CI job, an agent spinning up a sandbox: Each one is a separate opportunity to forget.</p><p>That&#39;s not automation. That&#39;s hoping.</p><p>In this article, you will learn how to implement the Git Clone Override Policy to automatically enforce repository cloning optimizations and minimize costs.</p><h2 id="where-the-clone-tax-hits-hardest">Where the clone tax hits hardest</h2><p>Agentic AI is the newest and fastest growing pressure, but it&#39;s not the only place a default full history clone is costing the software industry dearly:</p><ul><li><strong>Monorepos:</strong> Consolidating many projects into one repository means every clone pulls far more than any single team actually needs.</li><li><strong>Complex, long-running Git history:</strong> Years of commits compound total repository size even when the current tree is modest.</li><li><strong>Media, binaries, and embedded projects:</strong> Firmware images, vendor SDKs, and design assets stored directly in version control balloon a repository the way source code alone never would.</li><li><strong>CI/CD pipelines:</strong> A fresh clone on every job, run thousands of times a day, turns a small per-clone inefficiency into a large recurring one.</li><li><strong>Data science and machine learning data sets:</strong> Large data files tracked in git carry the same size tax as any other oversized blob.</li><li><strong>Remote developer environments:</strong> Cloud-hosted or ephemeral development environments want fast, lightweight startup, but still default to a full repository replication.</li><li><strong>Agentic AI:</strong> Many more clone requests, but far less predictable than any human-driven workflow.</li></ul><h2 id="making-the-optimization-impossible-to-skip">Making the optimization impossible to skip</h2><p>The fix isn&#39;t a better README telling people which flags to set. It&#39;s moving the decision out of individual hands entirely: Commit the policy to the repository itself, as code, and let a small program enforce it.</p><p>That&#39;s what <a href="https://gitlab.com/gitlab-accelerates-embedded/git-clone-perf/git-clone-override-policy" rel="">Git Clone Override Policy</a> does. Drop a <code>.afullhistorycloneoverridepolicy.toml</code> file in a repo, and a lightweight Go binary intercepts <em>only</em> a bare <code>git clone URL</code>, the plain, default, full-history request. The moment you add any option yourself (<code>--depth 1</code>, <code>--filter</code>, anything), the binary assumes you&#39;re already optimizing and passes your command straight through untouched. No policy file in the repo at all? Same thing: clean pass-through to a normal clone. The only case it ever touches is the one everyone agrees is a mistake: the unqualified default.</p><p>When it does intercept, here&#39;s the sequence: Fetch the policy file, then run a fixed 13-step process that shallow-and-partial-clones the repo, set up sparse checkout to skip binary files (images, archives, media, fonts, and more), and apply the same tuned git config from Git Much Faster, all before a single line of source shows up on disk.</p><h2 id="what-maximum-optimization-looks-like">What maximum optimization looks like</h2><p>Let’s take a look at the commands required to do a maximum optimization of a Git Clone.</p><p><strong>1. Build the repo shell yourself, instead of <code>git clone</code>.</strong></p><p>This allows us to set a broad variety of git configuration settings that set the file scope of the first clone request.</p><pre className="language-shell shiki shiki-themes github-light" code="mkdir my-repo &amp;&amp; cd my-repo
git init
git remote add origin https://example.com/group/my-repo.git
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">mkdir</span><span class="sYBdl"> my-repo</span><span class="sgsFI"> &amp;&amp; </span><span class="sYu0t">cd</span><span class="sYBdl"> my-repo
</span></span><span class="line" line="2"><span class="s7eDp">git</span><span class="sYBdl"> init
</span></span><span class="line" line="3"><span class="s7eDp">git</span><span class="sYBdl"> remote</span><span class="sYBdl"> add</span><span class="sYBdl"> origin</span><span class="sYBdl"> https://example.com/group/my-repo.git
</span></span></code></pre><p><strong>2. Tune git config for large-transfer performance, scoped to just this repo.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git config --local core.compression 0
git config --local http.postBuffer 1024M
git config --local http.lowSpeedLimit 1000
git config --local http.lowSpeedTime 300
git config --local pack.windowMemory 256m
git config --local pack.packSizeLimit 256m
git config --local pack.threads 4
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> core.compression</span><span class="sYu0t"> 0
</span></span><span class="line" line="2"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> http.postBuffer</span><span class="sYBdl"> 1024M
</span></span><span class="line" line="3"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> http.lowSpeedLimit</span><span class="sYu0t"> 1000
</span></span><span class="line" line="4"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> http.lowSpeedTime</span><span class="sYu0t"> 300
</span></span><span class="line" line="5"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> pack.windowMemory</span><span class="sYBdl"> 256m
</span></span><span class="line" line="6"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> pack.packSizeLimit</span><span class="sYBdl"> 256m
</span></span><span class="line" line="7"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> pack.threads</span><span class="sYu0t"> 4
</span></span></code></pre><p><strong>3. Turn on partial clone, since you&#39;re about to fetch with <code>--filter</code>.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git config --local extensions.partialClone origin
git config --local remote.origin.promisor true
git config --local remote.origin.partialclonefilter blob:none
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> extensions.partialClone</span><span class="sYBdl"> origin
</span></span><span class="line" line="2"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> remote.origin.promisor</span><span class="sYu0t"> true
</span></span><span class="line" line="3"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> remote.origin.partialclonefilter</span><span class="sYBdl"> blob:none
</span></span></code></pre><p><strong>4. Narrow the fetch refspec to the one ref you actually want, instead of every branch on the remote.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git config --local remote.origin.fetch &quot;+refs/heads/main:refs/remotes/origin/main&quot;
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> config</span><span class="sYu0t"> --local</span><span class="sYBdl"> remote.origin.fetch</span><span class="sYBdl"> &quot;+refs/heads/main:refs/remotes/origin/main&quot;
</span></span></code></pre><p>Without this update, <code>remote.origin.fetch</code> is automatically set to <code>+refs/heads/*:refs/remotes/origin/*</code>, meaning every fetch (and the initial clone) pulls down the ref pointers for all branches on origin. Updating this setting allows us to restrict fetch operations to just the <code>main</code> branch so that Git will no longer track or update refs for any other remote branch.</p><p>There are fewer refs to negotiate and update which means less overhead per fetch, especially on repos with hundreds of branches.</p><p><strong>5. Fetch shallow, with blob content deferred.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git fetch --depth=1 --filter=blob:none origin main
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> fetch</span><span class="sYu0t"> --depth=1</span><span class="sYu0t"> --filter=blob:none</span><span class="sYBdl"> origin</span><span class="sYBdl"> main
</span></span></code></pre><p>This depth and filter combination gets you the smallest possible initial transfer: one commit&#39;s worth of tree structure, no blob data at all until you check out files. This benefit comes specifically when you’re working on repositories with large files or a lot of history.</p><p><strong>6. Turn on sparse checkout and exclude every binary file type you don&#39;t need for source work.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git sparse-checkout init --cone
cat &gt;&gt; .git/info/sparse-checkout &lt;&lt;&#39;EOF&#39;
/*
!*.png
!*.PNG
!*.jpg
!*.JPG
!*.pdf
!*.PDF
!*.zip
!*.ZIP
!*.mp4
!*.MP4
!*.exe
!*.EXE
EOF
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> sparse-checkout</span><span class="sYBdl"> init</span><span class="sYu0t"> --cone
</span></span><span class="line" line="2"><span class="s7eDp">cat</span><span class="sD7c4"> &gt;&gt;</span><span class="sYBdl"> .git/info/sparse-checkout</span><span class="sD7c4"> &lt;&lt;</span><span class="sYBdl">&#39;EOF&#39;
</span></span><span class="line" line="3"><span class="sYBdl">/*
</span></span><span class="line" line="4"><span class="sYBdl">!*.png
</span></span><span class="line" line="5"><span class="sYBdl">!*.PNG
</span></span><span class="line" line="6"><span class="sYBdl">!*.jpg
</span></span><span class="line" line="7"><span class="sYBdl">!*.JPG
</span></span><span class="line" line="8"><span class="sYBdl">!*.pdf
</span></span><span class="line" line="9"><span class="sYBdl">!*.PDF
</span></span><span class="line" line="10"><span class="sYBdl">!*.zip
</span></span><span class="line" line="11"><span class="sYBdl">!*.ZIP
</span></span><span class="line" line="12"><span class="sYBdl">!*.mp4
</span></span><span class="line" line="13"><span class="sYBdl">!*.MP4
</span></span><span class="line" line="14"><span class="sYBdl">!*.exe
</span></span><span class="line" line="15"><span class="sYBdl">!*.EXE
</span></span><span class="line" line="16"><span class="sYBdl">EOF
</span></span></code></pre><p>The real policy excludes over 30 extensions across images, documents, archives, media, compiled binaries, and design files, in both cases. That&#39;s just a representative slice.</p><p><strong>7. Check out the ref.</strong></p><pre className="language-shell shiki shiki-themes github-light" code="git checkout main
" language="shell" meta="" style=""><code><span class="line" line="1"><span class="s7eDp">git</span><span class="sYBdl"> checkout</span><span class="sYBdl"> main
</span></span></code></pre><p>Do all seven stages, in that exact order, against <code>www.gitlab.com</code>, and you land at the same 110 MB instead of 9.5 GB. Get the order wrong (fetch before narrowing the refspec, sparse-checkout after checkout instead of before) and at best you&#39;ve wasted the optimization, at worst you&#39;ve fetched the thing you were trying to avoid fetching. That precision, repeated correctly on every clone, by every person and every pipeline, is exactly the discipline problem from the top of this post. Git Clone Override Policy doesn&#39;t invent a new technique here. It just guarantees these seven stages run, in order, every time, without anyone needing to remember them.</p><h2 id="automation-to-the-rescue">Automation to the rescue</h2><p>Git client usage is both highly scaled and distributed, so propagating a precise, purpose-specific set of clone optimization commands to be run by humans or custom coded into every CI job and agent sandbox requires automation to be truly reliable.</p><p>What if we could enforce that workflow with automatic policies, instead of betting on everyone remembering all seven stages? It turns out there&#39;s already a working MVC of exactly that: a TOML policy file that lives in the repository alongside the code, plus a client capable of intercepting every <code>git clone</code> call before it ever reaches the network. Store the policy once, and every clone (human, CI job, or agent) gets the optimized sequence automatically instead of by request. Using a policy settings file also allows for the tuning that will be necessary for various purposes. The default above is for counting lines of code, so we just need a reliable copy of all existing text files. Building the same software might require more files because it compiles some graphics into the UI in the application or some builds may require more of the Git history information in order to locate commit messages for release notes.</p><h2 id="a-small-portable-go-binary-and-a-repo-stored-policy-configuration-file">A small, portable Go binary and a repo stored policy configuration file</h2><p>The interceptor itself is a single self-contained Go binary, not a shell script held together with <code>sed</code> and hope. That choice buys a few things worth calling out.</p><p><img alt="A small, portable Go binary a repo stored policy configuration file" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1787080260/bhz0beczhkffzdweghma.png" /></p><p>It runs on Linux, macOS, and Windows, for both amd64 and arm64: one codebase instead of a bash version and a separate PowerShell version drifting out of sync. It&#39;s been tested across every shell you&#39;re likely to hit, from CMD and PowerShell to Git Bash and WSL. The only runtime dependency is a real <code>git</code> binary already on <code>PATH</code>.</p><p>Internally it&#39;s organized into six small, independently testable pieces (policy parsing, the fixed-sequence interpreter, git command execution, logging, cross-platform detection, and the entry point handling all four invocation modes) rather than one large function doing all of it at once.</p><p>This example configuration file gives a feel for the things that can currently be tweaked.</p><pre className="language-toml shiki shiki-themes github-light" code="schema_version = 2

[policyinfo]
description = &quot;The most optimal latest-code-only clone for AI agents (that do not need git history) or counting lines of code.&quot;
OptimalForAIAgents = true

[git_config]
&quot;core.compression&quot;   = 0
&quot;http.postBuffer&quot;    = &quot;1024M&quot;
&quot;http.lowSpeedLimit&quot; = 1000
&quot;http.lowSpeedTime&quot;  = 300
&quot;pack.windowMemory&quot;  = &quot;256m&quot;
&quot;pack.packSizeLimit&quot; = &quot;256m&quot;
&quot;pack.threads&quot;       = 4

[fetch]
flags = [&quot;--depth=1&quot;, &quot;--filter=blob:none&quot;]

[sparse_checkout]
enabled  = true
# conemode &#39;auto&#39; is processed by the solution code to be either &#39;cone&#39; or &#39;no-cone&#39; when passed to git
conemode = &quot;auto&quot;
includes = [&quot;/*&quot;]
excludes = []
exclude_extensions = [
  &quot;png&quot;, &quot;jpg&quot;, &quot;jpeg&quot;, &quot;gif&quot;, &quot;svg&quot;, &quot;ico&quot;, &quot;webp&quot;,
  &quot;pdf&quot;, &quot;doc&quot;, &quot;docx&quot;, &quot;xls&quot;, &quot;xlsx&quot;, &quot;ppt&quot;, &quot;pptx&quot;,
  &quot;zip&quot;, &quot;tar&quot;, &quot;gz&quot;, &quot;jar&quot;,
  &quot;mp4&quot;, &quot;mp3&quot;, &quot;mov&quot;,
  &quot;exe&quot;, &quot;dll&quot;, &quot;so&quot;, &quot;woff&quot;, &quot;woff2&quot;,
  &quot;ttf&quot;, &quot;otf&quot;, &quot;psd&quot;, &quot;sketch&quot;, &quot;fig&quot;, &quot;dmg&quot;, &quot;eps&quot;,
]
case_variants = &quot;both&quot;
" language="toml" meta="" style=""><code><span class="line" line="1"><span class="sgsFI">schema_version = </span><span class="sYu0t">2
</span></span><span class="line" line="2"><span emptyLinePlaceholder>
</span></span><span class="line" line="3"><span class="sgsFI">[</span><span class="s7eDp">policyinfo</span><span class="sgsFI">]
</span></span><span class="line" line="4"><span class="sgsFI">description = </span><span class="sYBdl">&quot;The most optimal latest-code-only clone for AI agents (that do not need git history) or counting lines of code.&quot;
</span></span><span class="line" line="5"><span class="sgsFI">OptimalForAIAgents = </span><span class="sYu0t">true
</span></span><span class="line" line="6"><span emptyLinePlaceholder>
</span></span><span class="line" line="7"><span class="sgsFI">[</span><span class="s7eDp">git_config</span><span class="sgsFI">]
</span></span><span class="line" line="8"><span class="sgsFI">&quot;core.compression&quot;   = </span><span class="sYu0t">0
</span></span><span class="line" line="9"><span class="sgsFI">&quot;http.postBuffer&quot;    = </span><span class="sYBdl">&quot;1024M&quot;
</span></span><span class="line" line="10"><span class="sgsFI">&quot;http.lowSpeedLimit&quot; = </span><span class="sYu0t">1000
</span></span><span class="line" line="11"><span class="sgsFI">&quot;http.lowSpeedTime&quot;  = </span><span class="sYu0t">300
</span></span><span class="line" line="12"><span class="sgsFI">&quot;pack.windowMemory&quot;  = </span><span class="sYBdl">&quot;256m&quot;
</span></span><span class="line" line="13"><span class="sgsFI">&quot;pack.packSizeLimit&quot; = </span><span class="sYBdl">&quot;256m&quot;
</span></span><span class="line" line="14"><span class="sgsFI">&quot;pack.threads&quot;       = </span><span class="sYu0t">4
</span></span><span class="line" line="15"><span emptyLinePlaceholder>
</span></span><span class="line" line="16"><span class="sgsFI">[</span><span class="s7eDp">fetch</span><span class="sgsFI">]
</span></span><span class="line" line="17"><span class="sgsFI">flags = [</span><span class="sYBdl">&quot;--depth=1&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;--filter=blob:none&quot;</span><span class="sgsFI">]
</span></span><span class="line" line="18"><span emptyLinePlaceholder>
</span></span><span class="line" line="19"><span class="sgsFI">[</span><span class="s7eDp">sparse_checkout</span><span class="sgsFI">]
</span></span><span class="line" line="20"><span class="sgsFI">enabled  = </span><span class="sYu0t">true
</span></span><span class="line" line="21"><span class="sAwPA"># conemode &#39;auto&#39; is processed by the solution code to be either &#39;cone&#39; or &#39;no-cone&#39; when passed to git
</span></span><span class="line" line="22"><span class="sgsFI">conemode = </span><span class="sYBdl">&quot;auto&quot;
</span></span><span class="line" line="23"><span class="sgsFI">includes = [</span><span class="sYBdl">&quot;/*&quot;</span><span class="sgsFI">]
</span></span><span class="line" line="24"><span class="sgsFI">excludes = []
</span></span><span class="line" line="25"><span class="sgsFI">exclude_extensions = [
</span></span><span class="line" line="26"><span class="sYBdl">  &quot;png&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;jpg&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;jpeg&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;gif&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;svg&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;ico&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;webp&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="27"><span class="sYBdl">  &quot;pdf&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;doc&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;docx&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;xls&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;xlsx&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;ppt&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;pptx&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="28"><span class="sYBdl">  &quot;zip&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;tar&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;gz&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;jar&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="29"><span class="sYBdl">  &quot;mp4&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;mp3&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;mov&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="30"><span class="sYBdl">  &quot;exe&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;dll&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;so&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;woff&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;woff2&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="31"><span class="sYBdl">  &quot;ttf&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;otf&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;psd&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;sketch&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;fig&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;dmg&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;eps&quot;</span><span class="sgsFI">,
</span></span><span class="line" line="32"><span class="sgsFI">]
</span></span><span class="line" line="33"><span class="sgsFI">case_variants = </span><span class="sYBdl">&quot;both&quot;
</span></span></code></pre><h2 id="declarative-configuration-over-code">Declarative configuration over code</h2><p>Infrastructure as code successfully reduces complexity and increases standardization and security by boiling down what is usually a sprawl of highly variable team code into a declarative configuration file and an engine that processes it. This very effective pattern is repeated here for all of its benefits including:</p><ul><li>standardization of unfamiliar processes (exceptionally detailed git commands)</li><li>complexity avoidance</li><li>easy adoptability by existing specialized clone code (e.g. vs code “clones” that don’t use the git binary)</li><li>reduced bugs and edge cases (compared to everyone devising their own)</li><li>consistency of implementation across contexts (e.g. CI clones, developer IDEs, AI sandboxes)</li><li>improved auditability</li><li>configuration file generation and manipulation by other automation</li><li>improved security (avoiding many code injection vectors)</li></ul><p>The interpreter can only act on configuration: git config key/value pairs, fetch and checkout flags, sparse-checkout include/exclude lists, and a small set of post-clone hooks gated by simple predicates. Any arbitrary additions to the configuration are unknown to the engine and ignored. You can audit exactly what a policy will do just by reading it.</p><h2 id="three-ways-to-leverage-git-clone-override-policy-least-invasive-to-most">Three ways to leverage Git Clone Override Policy, least invasive to most</h2><table><thead><tr><th align="left">Mode</th><th align="left">Command</th><th align="left">Needs admin</th><th align="left">Best for</th></tr></thead><tbody><tr><td align="left">Zero-footprint CLI</td><td align="left"><code>./git-clone-override-policy clone URL</code></td><td align="left">No</td><td align="left">CI jobs, agents, one-off machines</td></tr><tr><td align="left">Git alias</td><td align="left"><code>git cloneusingpolicy URL</code></td><td align="left">No</td><td align="left">Developers opting in individually</td></tr><tr><td align="left">OS alias</td><td align="left"><code>git clone URL</code> (intercepts git binary calls)</td><td align="left">Yes</td><td align="left">Fleet-wide enforcement without developer awareness</td></tr></tbody></table><br /><p>The zero-footprint mode is just the compiled binary: Download it, run it, done. No install, no PATH changes, nothing to clean up, which is exactly what you want when the whole machine is disposable. The git alias mode installs a <code>git cloneusingpolicy</code> command for a single user, no admin rights required. The OS alias mode goes furthest: It installs itself ahead of the real <code>git</code> on the system PATH, so every <code>git clone</code> on that machine is policy-aware whether the person running it knows this exists or not.</p><h2 id="three-example-results-of-git-clone-override-policy-optimization">Three example results of Git Clone Override Policy optimization</h2><p>The results are the same ones from Git Much Faster, now landing automatically instead of by request:</p><table><thead><tr><th align="left">Repository</th><th align="left">Full history clone</th><th align="left">Policy-optimized clone</th></tr></thead><tbody><tr><td align="left"><a href="http://www.gitlab.com" rel="">www.gitlab.com</a></td><td align="left">9.5 GB</td><td align="left">110 MB</td></tr><tr><td align="left">Linux kernel</td><td align="left">7.5 GB</td><td align="left">2 GB</td></tr><tr><td align="left">Chromium</td><td align="left">60 GB</td><td align="left">5 GB</td></tr></tbody></table><br /><p>And the safety behavior holds up under a live demo: Install the OS alias, run a plain <code>git clone</code> against a policy-bearing repo, and you get the 110 MB version. Add <code>--depth 1</code> to that same command and it&#39;s ignored by the interceptor entirely: pass-through, full stop. Uninstall, and <code>git clone</code> goes right back to a standard clone, no residue.</p><h2 id="compounding-git-lfs-benefits">Compounding Git LFS benefits</h2><p>Git LFS and this policy solve different halves of the same problem: LFS changes how binaries are stored, keeping their history off the packfile, while the clone policy changes what each clone asks for. Because they operate on different layers, they stack rather than compete — on an LFS repo, the policy&#39;s shallow depth, single-branch refspec, and transfer tuning still trim everything LFS leaves untouched. And since <code>sparse-checkout</code> excludes those file types by name, it also skips the smudge download of the current binaries, giving you the on-demand behavior of the standard git configuration variable <code>GIT_LFS_SKIP_SMUDGE</code> without any client configuration. The result is compounded: LFS shrinks the history, the policy shrinks the request, and a clone that was already lean under LFS gets leaner still.</p><h2 id="where-this-goes-next">Where this goes next</h2><p>This tutorial closes the loop on where we started: The problem isn&#39;t unique to agents, but agents are the use case that makes &quot;just tell people the right settings&quot; fall apart fastest. Policy as code doesn&#39;t need anyone, human or agent, to know it&#39;s there.</p><p>To go deeper, watch the <a href="https://www.youtube.com/watch?v=Dyl8ICWj3AY" rel="">Git Clone Override Policy Solution Architecture Overview</a> for the problem-solution fit and design, and the <a href="https://www.youtube.com/watch?v=2u_z1nXae7U" rel="">Git Clone Override Policy Demo</a> to see the three runtime modes in action.</p><p><a href="https://gitlab.com/gitlab-accelerates-embedded/git-clone-perf/git-clone-override-policy" rel="">Try the Git Clone Override Policy</a> against your own large repository. And, if you want the benchmarking behind the defaults, <a href="https://gitlab.com/gitlab-accelerates-embedded/git-clone-perf/git-much-faster" rel="">Git Much Faster</a> is where those numbers came from.</p><style>html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}</style>]]></content>
        <author>
            <name>Darwin Sanoy</name>
            <uri>https://about.gitlab.com/blog/authors/darwin-sanoy/</uri>
        </author>
        <published>2026-08-18T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[GitLab Critical Patch Release: 19.2.4, 19.1.6, 19.0.8, 18.11.11]]></title>
        <id>https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-4-released/</id>
        <link href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-4-released/"/>
        <updated>2026-08-17T00:00:00.000Z</updated>
        <published>2026-08-17T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[Critical remote code execution in Serena, a popular MCP coding agent]]></title>
        <id>https://about.gitlab.com/blog/critical-rce-in-serena/</id>
        <link href="https://about.gitlab.com/blog/critical-rce-in-serena/"/>
        <updated>2026-08-17T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Serena, one of the most widely used AI coding agents, ran attacker-supplied code the moment a developer opened a project. GitLab&#39;s Threat Research Group found a critical server-side template injection (<a href="https://github.com/oraios/serena/security/advisories/GHSA-pp25-4cg4-qcr9" rel="">GHSA-pp25-4cg4-qcr9</a>, CVE pending) that executes arbitrary code in the Serena process. Anyone on serena-agent 1.6.1 or earlier should update to 1.7.0 now.</p><p>A threat actor can exploit this by hiding a malicious <code>.serena/project.yml</code> file into a repository it controls and getting a developer to open it via the Serena Model Context Protocol (MCP) server. The flaw bypasses <code>trusted_project_path_patterns</code>, the control Serena built specifically to stop untrusted repositories from running code. We reported it privately on August 1, 2026, and the maintainers shipped a fix eight days later.</p><p>It is an early example of a risk class that will spread as MCP servers become embedded in the software development lifecycle.</p><h2 id="why-mcp-servers-are-a-different-kind-of-attack-surface">Why MCP servers are a different kind of attack surface</h2><p>Most developer tools touch a codebase in a narrow way: A linter reads files, a formatter writes them, and a test runner executes a specific harness. Conversely, MCP servers hand a large language model (LLM) a general-purpose interface to the developer&#39;s environment, covering file system access, shell execution, language server queries, and sometimes the network. The same reach that makes them useful makes compromising the server process severe.</p><p>CI/CD pipelines run in isolated environments with scoped credentials. MCP servers run on the developer&#39;s own machine, in the developer&#39;s own user context, with access to everything the developer can reach: SSH keys, cloud provider credentials, <code>.env</code> files, browser sessions, and internal network resources. Compromise the server process and you compromise the developer&#39;s entire local environment.</p><p>Developers point these servers at repositories they did not write all the time: evaluating a new open-source library, triaging a bug report, or reviewing a contributor&#39;s branch. If the server processes anything from that repository before the developer inspects it, the attacker gets a window. Serena is explicit about this threat and ships a trust model to prevent untrusted repositories from executing code. The trust model had a gap.</p><h2 id="how-the-vulnerability-works">How the vulnerability works</h2><h3 id="what-serena-is">What Serena is</h3><p>Serena describes itself as &quot;the IDE for your agent.&quot; It connects Claude, Cursor, Copilot, and other AI assistants to a local codebase over MCP, providing semantic code navigation, refactoring, and editing tools that go beyond what a raw file system gives an LLM. Developers run it as a local MCP server and point their assistant at it:</p><pre className="language-text" code="serena start-mcp-server --project /path/to/repo
" language="text"><code>serena start-mcp-server --project /path/to/repo
</code></pre><p>Because Serena operates on arbitrary local repositories with the user&#39;s full OS privileges, it ships a trust gate. <code>trusted_project_path_patterns</code> controls which project paths count as trusted, and only trusted projects can use privileged features like <code>activation_command</code>, which runs a shell command on project open. The intended guarantee: opening an untrusted repository is safe.</p><h3 id="the-sink-an-unsandboxed-template-engine">The sink: An unsandboxed template engine</h3><p>Serena lets each project define custom modes, named configurations with a <code>prompt</code> field that gets injected into the LLM&#39;s system prompt when the project is active. Serena renders these prompts as Jinja2 templates, and the rendering is the problem. In <code>src/interprompt/jinja_template.py</code>:</p><pre className="language-py shiki shiki-themes github-light" code="# line 22
self._env = jinja2.Environment()
" language="py" meta="" style=""><code><span class="line" line="1"><span class="sAwPA"># line 22
</span></span><span class="line" line="2"><span class="sYu0t">self</span><span class="sgsFI">._env </span><span class="sD7c4">=</span><span class="sgsFI"> jinja2.Environment()
</span></span></code></pre><p><code>jinja2.Environment()</code> is a plain, unsandboxed environment. It exposes built-in globals whose attributes chain up through Python&#39;s object graph to <code>os</code> and <code>subprocess</code>. The techniques for reaching arbitrary code execution from that starting point are well documented and require no specialized knowledge. Jinja2 ships a <code>SandboxedEnvironment</code> for exactly this reason, but it was not used here.</p><h3 id="the-delivery-project-configuration-as-untrusted-input">The delivery: Project configuration as untrusted input</h3><p>A project&#39;s <code>.serena/project.yml</code> supports an <code>added_modes</code> field, listing additional modes to activate when the project opens. Serena&#39;s mode loader treats any name containing a path separator or ending in <code>.yml</code> as a filesystem path to load directly:</p><pre className="language-py shiki shiki-themes github-light" code="# context_mode.py, lines 29-30
def looks_like_yaml_path(s: str) -&gt; bool:
    return os.sep in s or (os.altsep and os.altsep in s) or s.lower().endswith((&quot;.yml&quot;, &quot;.yaml&quot;))

# context_mode.py, lines 130-135
@classmethod
def load(cls, name_or_path: str | Path) -&gt; Self:
    if isinstance(name_or_path, Path) or looks_like_yaml_path(str(name_or_path)):
        return cls.from_yaml(name_or_path)
    ...
" language="py" meta="" style=""><code><span class="line" line="1"><span class="sAwPA"># context_mode.py, lines 29-30
</span></span><span class="line" line="2"><span class="sD7c4">def</span><span class="s7eDp"> looks_like_yaml_path</span><span class="sgsFI">(s: </span><span class="sYu0t">str</span><span class="sgsFI">) -&gt; </span><span class="sYu0t">bool</span><span class="sgsFI">:
</span></span><span class="line" line="3"><span class="sD7c4">    return</span><span class="sgsFI"> os.sep </span><span class="sD7c4">in</span><span class="sgsFI"> s </span><span class="sD7c4">or</span><span class="sgsFI"> (os.altsep </span><span class="sD7c4">and</span><span class="sgsFI"> os.altsep </span><span class="sD7c4">in</span><span class="sgsFI"> s) </span><span class="sD7c4">or</span><span class="sgsFI"> s.lower().endswith((</span><span class="sYBdl">&quot;.yml&quot;</span><span class="sgsFI">, </span><span class="sYBdl">&quot;.yaml&quot;</span><span class="sgsFI">))
</span></span><span class="line" line="4"><span emptyLinePlaceholder>
</span></span><span class="line" line="5"><span class="sAwPA"># context_mode.py, lines 130-135
</span></span><span class="line" line="6"><span class="s7eDp">@</span><span class="sYu0t">classmethod
</span></span><span class="line" line="7"><span class="sD7c4">def</span><span class="s7eDp"> load</span><span class="sgsFI">(cls, name_or_path: </span><span class="sYu0t">str</span><span class="sD7c4"> |</span><span class="sgsFI"> Path) -&gt; Self:
</span></span><span class="line" line="8"><span class="sD7c4">    if</span><span class="sYu0t"> isinstance</span><span class="sgsFI">(name_or_path, Path) </span><span class="sD7c4">or</span><span class="sgsFI"> looks_like_yaml_path(</span><span class="sYu0t">str</span><span class="sgsFI">(name_or_path)):
</span></span><span class="line" line="9"><span class="sD7c4">        return</span><span class="sYu0t"> cls</span><span class="sgsFI">.from_yaml(name_or_path)
</span></span><span class="line" line="10"><span class="sYu0t">    ...
</span></span></code></pre><p>A path-like entry in <code>added_modes</code> causes Serena to load that file from the repository, read its <code>prompt</code> field verbatim, and pass it to the unsandboxed renderer. <code>yaml.safe_load</code> is used correctly and blocks YAML deserialization gadgets, but it has no bearing on a plain string inside the <code>prompt</code> field. The YAML parser sees harmless text. The injection happens later, when that string is compiled as a Jinja2 template.</p><h3 id="the-trust-control-bypass">The trust control bypass</h3><p><code>is_trusted()</code>, Serena&#39;s mechanism for preventing untrusted projects from executing code, gates two features: <code>activation_command</code>, the shell command run on project open, and <code>ls_specific_settings</code>, project-scoped tool overrides. The mode-loading and prompt-rendering path is never checked against <code>is_trusted()</code>. The <code>added_modes</code> list from a project&#39;s <code>.serena/project.yml</code> is processed without validation, and the mode loader applies no allowlist and no trust check before it loads the file and hands the <code>prompt</code> field to the template engine.</p><p>We confirmed the bypass empirically. We ran the same end-to-end test with <code>trusted_project_path_patterns</code> set to empty, so no project counts as trusted, stricter than any default configuration. Two things happened:</p><table><thead><tr><th align="left">Feature</th><th align="left">Trust-gated</th><th align="left">Result on untrusted project</th></tr></thead><tbody><tr><td align="left"><code>activation_command</code></td><td align="left">Yes</td><td align="left">Blocked</td></tr><tr><td align="left">Template injection via <code>added_modes</code></td><td align="left">No</td><td align="left">Executes</td></tr></tbody></table><br /><p>The feature whose entire purpose is to run a shell command is blocked. The template injection reaches the same outcome through a different path and runs freely. That makes it a protection mechanism failure (CWE-693). The trust model exists to prevent an untrusted repository from executing code, and this path defeats it while looking like ordinary project loading.</p><h3 id="the-full-call-chain">The full call chain</h3><pre className="language-text" code=".serena/project.yml  (attacker-controlled, ships with the repo)
  added_modes: [&quot;./path/to/attacker-mode.yml&quot;]
        |
        v
SerenaAgentMode.load()            context_mode.py:130-135
  from_yaml(name_or_path)
  prompt = &lt;attacker-controlled string&gt;
        |
        v
SerenaAgent._update_active_modes()    agent.py:1063
        |
        v
create_system_prompt()                agent.py:996
  _format_prompt(mode.prompt)
  JinjaTemplate(prompt).render()      arbitrary code execution
" language="text"><code>.serena/project.yml  (attacker-controlled, ships with the repo)
  added_modes: [&quot;./path/to/attacker-mode.yml&quot;]
        |
        v
SerenaAgentMode.load()            context_mode.py:130-135
  from_yaml(name_or_path)
  prompt = &lt;attacker-controlled string&gt;
        |
        v
SerenaAgent._update_active_modes()    agent.py:1063
        |
        v
create_system_prompt()                agent.py:996
  _format_prompt(mode.prompt)
  JinjaTemplate(prompt).render()      arbitrary code execution
</code></pre><p>Code runs as a side effect of the ordinary project-open flow, before Serena serves its first request to the LLM.</p><h3 id="exposure">Exposure</h3><p>Serena&#39;s reach in the developer ecosystem is substantial. The repository has 27.8k GitHub stars and 1.8k forks, and the <code>serena-agent</code> package records roughly 136,000 downloads per month on PyPI. It integrates with Claude Code, Cursor, VS Code, JetBrains IDEs, Claude Desktop, and OpenWebUI, covering the range of AI-assisted development environments in common use.</p><p>A realistic attack needs no infrastructure and no social engineering beyond the repository. An attacker publishes a library, a sample project, a CTF challenge, or a seemingly useful tool. A developer clones it, opens it with Serena, and the code runs. Given everything a developer&#39;s machine can reach, the payoff for the attacker is immediate. In a CI/CD setup where Serena processes submitted repositories automatically, no human interaction is required at all.</p><h2 id="why-new-tools-inherit-old-bugs">Why new tools inherit old bugs</h2><p>None of the patterns behind this bug are unique to Serena.</p><p>User-supplied data flowed into a template engine without sandboxing. Template injection is one of the oldest vulnerability classes in web security, and most template engines ship a sandbox or restricted mode to address it. In a young ecosystem, developers building configuration-driven templating features often reach for the plain variant by default. The pattern will show up in other MCP tools.</p><p>Project configuration files were treated as trusted input. A repository&#39;s configuration files are authored by the repository owner. In any threat model where the repository may be untrusted, those files are attacker-controlled input. The distinction is easy to overlook when you build a tool and the configuration files feel like part of the tool itself.</p><p>Trust gates covered some code paths but not others. Serena&#39;s trust model was designed correctly: The gate exists, it is implemented, and the features it covers are clearly identified. The gap was a code path added without being brought under the same gate. Keeping trust coverage complete as a codebase evolves takes deliberate review of every new path that processes project-supplied input, not only the paths that are obviously privileged.</p><h2 id="what-this-means-for-you">What this means for you</h2><h3 id="if-you-use-serena">If you use Serena</h3><p>Update to serena-agent 1.7.0 now. The fix switches the template engine to <code>jinja2.sandbox.SandboxedEnvironment</code>, which closes the injection path. On Versions 1.6.1 and earlier, avoid opening repositories from untrusted sources.</p><h3 id="if-you-build-mcp-servers-or-ai-coding-tools">If you build MCP servers or AI coding tools</h3><p>These practices should apply to any tool that reads a project directory for an LLM.</p><ul><li>Treat project configuration files as input from a possibly hostile repository owner. Validate them like an HTTP request body: check the structure and reject anything off-schema.</li><li>Map every place a string becomes code or a command: template rendering, subprocess calls, plugin loading, dynamic imports. For each, know whether project input can reach it and what stops it.</li><li>Make your trust gate cover every path, not one feature. Review it whenever you add a feature that reads project input.</li><li>Test against a hostile repository before you ship. Build the most aggressive config you can, confirm nothing runs on open, and automate it.</li></ul><h3 id="if-you-lead-a-security-team">If you lead a security team</h3><p>MCP servers are a new class of local attack surface running with your developers&#39; full user context, so treat them like any other privileged tooling on those machines. Start by finding out which MCP servers are running in your environment and where. At scale, this may call for tooling and policy. From there, apply the same scrutiny to MCP server updates that you apply elsewhere: a vulnerability in an MCP server is a vulnerability on every machine that runs it. When you evaluate new MCP tools, ask the vendor about their trust model and how they test it against untrusted project inputs.</p><h2 id="disclosure-timeline">Disclosure timeline</h2><table><thead><tr><th align="left">Date</th><th align="left">Event</th></tr></thead><tbody><tr><td align="left">2026-08-01</td><td align="left">Vulnerability identified during research into AI coding agent attack surfaces</td></tr><tr><td align="left">2026-08-01</td><td align="left">Full advisory and proof of concept submitted to maintainers via GitHub private security advisory</td></tr><tr><td align="left">2026-08-05</td><td align="left">Report accepted by maintainers</td></tr><tr><td align="left">2026-08-09</td><td align="left">Fix shipped in serena-agent 1.7.0; public advisory published (<a href="https://github.com/oraios/serena/security/advisories/GHSA-pp25-4cg4-qcr9" rel="">GHSA-pp25-4cg4-qcr9</a>)</td></tr><tr><td align="left">2026-08-10</td><td align="left">CVE requested with the GitHub CNA by the maintainers</td></tr></tbody></table><br /><p>We thank the Serena maintainers for their prompt and collaborative handling of the report.</p><h2 id="how-gitlab-can-help">How GitLab can help</h2><p>GitLab Duo Security Agent can help you audit your codebase for the same patterns. Questions like &quot;does this project render user-controlled strings through a template engine?&quot; or &quot;are there configuration files in this repository that get passed to an execution context?&quot; are a practical starting point.</p><h2 id="looking-ahead">Looking ahead</h2><p>The MCP ecosystem sits roughly where the npm ecosystem sat a decade ago: growing fast, adoption outpacing security scrutiny, and trust assumptions left implicit. The Serena finding is ordinary, and that is the point. It is the kind of issue that appears whenever a new technology matures faster than the security patterns around it, and MCP is maturing fast. We expect more of the same as MCP servers become standard developer infrastructure.</p><p>GitLab&#39;s Threat Research Group will keep assessing AI developer tooling and sharing findings as they are responsibly disclosed. We encourage researchers to apply the same scrutiny to MCP servers that the security community has long applied to browser extensions, IDE plugins, and CI/CD integrations: tools that run with significant privilege on developer machines and handle data from sources they do not fully control.</p><style>html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}</style>]]></content>
        <author>
            <name>Daniel Abeles</name>
            <uri>https://about.gitlab.com/blog/authors/daniel-abeles/</uri>
        </author>
        <author>
            <name>Abisheik Magesh</name>
            <uri>https://about.gitlab.com/blog/authors/abisheik-magesh/</uri>
        </author>
        <published>2026-08-17T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How I built a demo generator with GitLab Duo Agent Platform]]></title>
        <id>https://about.gitlab.com/blog/agentic-click-through-demo/</id>
        <link href="https://about.gitlab.com/blog/agentic-click-through-demo/"/>
        <updated>2026-08-13T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>A demo used to take me days to build — screenshots, narration, stitching it together in an external tool, chasing feedback — and every time the feature changed I&#39;d have to start over. A few months ago, I handed most of that to an agent in GitLab Duo Agent Platform.</p><p><a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel="">GitLab Duo Agent Platform</a> is built for intelligent orchestration, running agentic workflows across the software development lifecycle, but it&#39;s flexible enough to take on repetitive work outside of development, too. When I pointed it at demo generation instead, it worked well enough that I think you should try the same thing with something on your own plate. I created this hands-on tutorial to help you get started. And one more thing: You don&#39;t need to be a developer to do this. We&#39;ve seen an increase in interest from non-engineering roles in using GitLab to run agentic workflows like this one. If that&#39;s you, follow along to get started.</p><p><strong>In this article:</strong></p><ul><li><a href="#why-click-through-demos-are-so-effective">Why click-through demos are so effective</a></li><li><a href="#the-evolution-from-vms-to-external-demo-tools-to-agents">The evolution: From VMs to external demo tools to agents</a></li><li><a href="#the-stages-to-create-a-demo">The stages to create a demo</a></li><li><a href="#how-the-demo-generator-works">How the demo generator works</a></li><li><a href="#demos-are-now-in-code">Demos are now in code</a></li><li><a href="#how-gitlab-duo-agent-platform-made-this-possible">How GitLab Duo Agent Platform made this possible</a></li><li><a href="#build-your-first-agent">Build your first agent</a></li></ul><blockquote><p>🎯 Try <a href="https://about.gitlab.com/gitlab-duo-agent-platform/" rel=""><strong>GitLab Duo Agent Platform</strong></a> today!</p></blockquote><h2 id="why-click-through-demos-are-so-effective">Why click-through demos are so effective</h2><p>People connect faster when they see a feature in action rather than read about it. But live demos are hard: You need product access and enough familiarity to navigate confidently.</p><p>A click-through demo solves that. You take real actions yourself, guided by a short narrative at each step. Unlike video, it puts you in control of the pace. And unlike live access, which requires a real environment, it&#39;s just a link: free to share, reusable, and consistent every time.</p><p>Explore examples in the <a href="https://dap-demo-hub-dac14a.gitlab.io/" rel="">GitLab Demo Hub</a>.</p><p><img alt="A click-through demo, guiding the user step by step through a real product flow" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1783421764/x0oyszct1nuhzg7sxv0z.png" title="A click-through demo, guiding the user step by step through a real product flow" /></p><h2 id="the-evolution-from-vms-to-external-demo-tools-to-agents">The evolution: From VMs to external demo tools to agents</h2><p>Demos haven&#39;t always looked like this. Looking back over my career, here&#39;s how they have evolved:</p><ul><li><strong>VMs (2000s)</strong>: Shipped virtual machines pre-loaded with the product and demo content, later centralized on ESX servers.</li><li><strong>External tools (SaaS era)</strong>: Moved to vendor platforms with built-in analytics, but still manual to build and tied to their infrastructure.</li><li><strong>Agentic (now)</strong>: Agents can generate demos from a prompt, deployed on the same project that creates them, no vendor dependency.</li></ul><p>Each layer made demos more accessible; the agentic layer is what makes them sustainable.</p><h2 id="the-stages-to-create-a-demo">The stages to create a demo</h2><p>Creating a click-through demo involves these stages:</p><ol><li><strong>Learn the feature</strong>: Read docs, dig through issues and Slack, sync with product managers and engineers to really understand what you&#39;re showing, and mainly understand the problem it solves and the customer impact and value.</li><li><strong>Build the story</strong>: Build a real-world scenario that shows the customer impact — what problem this solves for them in their day-to-day work, and why it matters.</li><li><strong>Set up the environment</strong>: Create a project and generate realistic demo data that supports the story; for example, seeded vulnerabilities for a security dashboard, or data for meaningful charts.</li><li><strong>Capture the content</strong>: Take screenshots or record clips of the actual flow.</li><li><strong>Write the narrative</strong>: Craft content that guides someone through each step, based on the story and customer scenario you defined in Step 2.</li><li><strong>Build the demo</strong>: Work in an external tool to stitch everything together into a clickable walkthrough, add links to related assets, and define the call to action for each step.</li><li><strong>Review with stakeholders</strong>: Share a draft, collect feedback, iterate.</li><li><strong>Incorporate edits</strong>: Update the narrative, reorder steps, regenerate as needed.</li><li><strong>Publish</strong>: Push to GitLab Docs, Demo Hub, and any other target location.</li><li><strong>Announce</strong>: Share internally on Slack, embed in blog posts, post on social.</li></ol><p>Together, these steps can take days, and the moment something changes in the product, you have to start over from Step 3.</p><p>An agent can help with almost all of these steps: reading docs, scanning issues, pulling context from Slack, populating demo data in the project, and pulling out what matters most. It can&#39;t fully replace the human who decides what to create and reviews the results before they ship, but it can do a remarkable amount of the groundwork.</p><p>In <a href="https://gitlab.com/gitlab-da/projects/click-through-demo-generator-v-2" rel="">the agentic tool I built</a>, the Click-Through Demo Generator, I focused on automating Steps 1, 2, 5, 6, and 9: the ones with clear inputs, predictable outputs, and previously fully manual execution. The other steps can also be handled by specialized agents.</p><h2 id="how-the-demo-generator-works">How the demo generator works</h2><p>The agent works like this: Drop screenshots into a folder in the project, optionally with a <code>context.md</code> for background on the feature, and trigger the workflow from an issue comment. The agent reorders and renames the screenshots, writes the narration, builds the demo with a built-in branded template, and opens a merge request. Review it, and once you merge it, the demo auto-publishes to GitLab Pages. If something needs to change, ask the agent to update it.</p><p><img alt="The issue comment that triggers the Click-Through Demo Generator, and the agent&#39;s response with the merge request link" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1783431076/etfiomoplfb4soaeevig.png" title="The issue comment that triggers the Click-Through Demo Generator, and the agent&#39;s response with the merge request link" /></p><p>Under the hood, a Custom Flow gets triggered. The agent calls a custom tool I built to assemble the demo into an HTML template, overlaying each screenshot with its narration message box, and comments the merge request link back on the issue. A skill guides its writing so the narration follows GitLab&#39;s marketing messaging, focused on customer outcomes rather than our own features.</p><p>Here&#39;s the actual instruction text from that skill&#39;s <code>SKILL.md</code> that the agent reads and follows every time it writes narration:</p><blockquote><p><em>&quot;Great narration sells an outcome, not a UI tour. Someone who clicks through should understand what problem the product solves, why this approach is better, and what they could now do, without reading any docs.</em></p><p><em>Structure every demo as three acts: Open on the customer&#39;s pain, show the product solving it step by step, and close by naming the value they walk away with.&quot;</em></p></blockquote><p>For demos in more languages, we just need to add a localization skill to the project, and every demo gets automatically localized from then on.</p><p><img alt="The demo gallery" src="https://res.cloudinary.com/about-gitlab-com/image/upload/v1783431133/ljn4kvbwvdxpaafhzgvi.png" title="The demo gallery: where demos are reviewed and staged before going to production" /></p><h3 id="publishing-with-a-skill">Publishing with a skill</h3><p>Publishing to the <a href="https://dap-demo-hub-dac14a.gitlab.io/" rel="">Demo Hub</a>, our production demo portal, is just as hands-off as publishing the demo itself. When a demo is ready to ship, you tag it as <strong>production</strong> in the development gallery. That&#39;s the cue for the agent to run a skill in this project that reaches into the Demo Hub project and does the rest: It writes a short description, stamps it with today&#39;s date, tags it as new, and opens a merge request adding the demo as a card. Merging that MR, and putting the demo live, is still a human&#39;s call.</p><h2 id="demos-are-now-in-code">Demos are now in code</h2><p>A click-through demo is really just a set of files: HTML, screenshots, and config, which makes it a great fit to live in a repo. The demo is no longer trapped in a separate tool that only a few people know how to use. It lives in a GitLab project, which means it can be:</p><ul><li>Reviewed in merge requests</li><li>Improved by teammates</li><li>Versioned over time</li><li>Updated by agents, not just humans</li></ul><p>The demo becomes a team asset, not a one-person task. That&#39;s a big deal. More teammates can now create demos, review them, improve them, and publish them, without needing any special tool knowledge. If you can open an issue and approve an MR, you can use this workflow.</p><h3 id="want-to-try-it-yourself">Want to try it yourself?</h3><p>Fork the <a href="https://gitlab.com/gitlab-da/projects/click-through-demo-generator-v-2" rel="">Click-Through Demo Generator</a> project and read the README for the full setup. Custom Flows aren&#39;t copied over when you fork a project, so you&#39;ll also need to enable the <a href="https://gitlab.com/gitlab-da/projects/click-through-demo-generator-v-2/-/automate/flows/1010005/" rel="">Generate click-through demo flow</a> (you&#39;ll need to be logged in to GitLab to view it) in your forked project. From there, the README walks you through everything else.</p><h2 id="how-gitlab-duo-agent-platform-made-this-possible">How GitLab Duo Agent Platform made this possible</h2><p>This project would have been significantly harder without GitLab Duo Agent Platform.</p><p>GitLab Duo Agent Platform gave me the missing infrastructure: a Custom Flow that triggers from an issue comment, a container image I define with exactly the runtime and dependencies it needs, and built-in tools to work with GitLab directly, like opening merge requests and commenting on issues. The merge request is where I review the demo before merging it and letting the agent publish it to the Demo Hub.</p><p>In platform terms, this is agentic automation — the <a href="https://docs.gitlab.com/user/duo_agent_platform/flows/custom/" rel="">Custom Flow</a> orchestrating the agent&#39;s behavior while GitLab’s built-in tools let it work with issues, project files, merge requests, and GitLab Pages without requiring separate integrations.</p><p>Custom Flows let you define your own multi-step workflow and extend the agent with custom tools, like the tool I built to assemble screenshots and narration into the demo&#39;s HTML template. You implement that capability yourself, and it runs as part of the flow, on GitLab&#39;s compute.</p><p>Everything happens inside GitLab: the request, the review, the output, the deployment. That&#39;s what makes the workflow faster, clearer, and easier to hand off.</p><h2 id="build-your-first-agent">Build your first agent</h2><p>Zoom out from my own workflow for a second and focus on what happens when repetitive work gets handed to an agent with access to your GitLab data. For a team lead, that&#39;s fewer cycles spent producing collateral and more spent reviewing and deciding. The same shift shows up anywhere a team has a repeatable, well-scoped task sitting on top of GitLab context.</p><p>Start small and simple. The demo generator is just one example of the pattern, but you don&#39;t need to write code or use a Custom Flow to get started. Start with a single agent, give it one clear job, and see what it can do before reaching for anything more complex.</p><p>In this quick tutorial, you&#39;ll build your first agent, one that helps you plan your work and saves you time. Don&#39;t have access to GitLab Duo Agent Platform? You can <a href="https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&amp;glm_content=default-saas-trial" rel="">start a free trial</a> to follow along. Two tasks, about 10 minutes total:</p><p><strong>Task 1: Create a custom agent.</strong> In the GitLab UI, <a href="https://docs.gitlab.com/user/duo_agent_platform/agents/custom/#create-an-agent" rel="">create a custom agent</a> called &quot;Daily Planner.&quot; Tell it what priority means to you — for example, issues blocking a teammate, anything due this week, or &quot;treat anything with the customer label as top priority regardless of due date.&quot; Have it look at your assigned issues and merge requests, apply those rules, and tell you what to tackle first, what&#39;s blocking others, and what can wait.</p><p><strong>Task 2: Enable it and review.</strong> <a href="https://docs.gitlab.com/user/duo_agent_platform/agents/custom/#enable-an-agent" rel="">Enable the agent</a> in your project, then open GitLab Duo Agentic Chat, select it, and ask it to plan your day. It has built-in access to GitLab, so it pulls your actual assigned issues and MRs itself. Compare its plan to what you&#39;d have figured out yourself, and adjust the agent&#39;s instructions until the plan is genuinely useful.</p><p>Congratulations, you just built your first agent, and it&#39;s already making your day a little easier. This is where it gets fun: Start thinking about what else you&#39;d hand it, another decision you&#39;re tired of making yourself. Keep going, and that single-purpose agent turns into the assistant that runs your whole workflow.</p>]]></content>
        <author>
            <name>Itzik Gan Baruch</name>
            <uri>https://about.gitlab.com/blog/authors/itzik-gan-baruch/</uri>
        </author>
        <published>2026-08-13T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[How GitLab tracks vulnerabilities through refactors and reformatting]]></title>
        <id>https://about.gitlab.com/blog/improved-scope-offset-fingerprinting/</id>
        <link href="https://about.gitlab.com/blog/improved-scope-offset-fingerprinting/"/>
        <updated>2026-08-12T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>Every day, security scans face the same problem: an agent or a developer adds a comment, reformats a file, or moves a function, and a naive vulnerability tracker suddenly reports the same finding twice. Security teams end up re-triaging issues they already dismissed, which causes futile auditing effort and erodes trust in the scan results.</p><p>In 2022, we <a href="https://about.gitlab.com/blog/introducing-gitlab-advanced-vulnerability-tracking/" rel="">introduced advanced vulnerability tracking</a> to tackle exactly this problem of <em>code volatility</em>. It is based on our <em>Scope+Offset</em> fingerprinting method: instead of identifying a finding by file and line number, we identify it by its narrowest enclosing <em>scope</em> (module, class, function) plus its line <em>offset</em> within that scope. That made tracking robust against code moving around the file and reduced futile re-auditing by about 30% compared to line-based tracking.</p><p>But one class of edits still slipped through: <strong>non-functional changes</strong>. The offset counted every line between the scope boundary and the finding, including comments and blank lines. Add a comment above a vulnerable statement, and the offset shifts. The tracker sees a &quot;new&quot; vulnerability; you see a duplicate.</p><p>Our improved method addresses this by simply ignoring non-functional code (comments and blank lines) when computing the fingerprint. Since these lines do not affect the program&#39;s behavior, they should not affect the identity of a vulnerability either. With this normalization in place, adding a comment or reformatting a file no longer changes the fingerprint, while the precision of the tracking remains the same as before. The details of the approach are described in our accompanying research paper.</p><p>We evaluated the normalized method on a targeted benchmark: 439 source files across C/C++, C#, Go, Java, JavaScript, Python, and Ruby. We generated 2,247 commits, each inserting a single comment or blank line directly before a known vulnerability, and scanned the code as the history was replayed. The benchmark deliberately stresses the worst case: every commit is a non-functional edit right next to a finding.</p><p>On this benchmark, the original <em>Scope+Offset</em> method accumulated 1,361 duplicate fingerprints, a 77% growth over the baseline. The normalized method produced zero duplicates and reduced unique fingerprints by 43% overall.</p><p><em>Normalized Scope+Offset</em> ships in GitLab as the <code>scope_offset_compressed</code> tracking algorithm, supporting C#, C/C++, Go, Java, JavaScript, Python, Ruby, and PHP. It reuses the parse tree the scanner already constructs, so scan times are unaffected. The security report format is unchanged, so it composes with any combination of SAST tools in a heterogeneous setup.</p><p>The preprint of our study &quot;<a href="https://res.cloudinary.com/about-gitlab-com/image/upload/v1786457681/jm8oieyjhwut8ed2cpaq.pdf" rel="">Vulnerability Tracking using Normalized
Scope+Offset</a>&quot; by Julian Thome, Hua Yan, Lucas Charles,
Craig Smith, and Jason Leasure will be presented at the <a href="https://conf.researchr.org/track/ase-2026/ase-2026-industry-showcase" rel="">ASE 2026 Industry Showcase</a>.</p><p><em><a href="https://gitlab.com/hyan3" rel="">Hua Yan</a>, <a href="https://gitlab.com/theoretick" rel="">Lucas Charles</a>, <a href="https://gitlab.com/craigmsmith" rel="">Craig Smith</a>, and Jason Leasure contributed to this article and study.</em></p>]]></content>
        <author>
            <name>Julian Thome</name>
            <uri>https://about.gitlab.com/blog/authors/julian-thome/</uri>
        </author>
        <published>2026-08-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[GitLab Patch Release: 19.2.2, 19.1.4, 19.0.6]]></title>
        <id>https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-2-released/</id>
        <link href="https://docs.gitlab.com/releases/patches/patch-release-gitlab-19-2-2-released/"/>
        <updated>2026-08-12T00:00:00.000Z</updated>
        <published>2026-08-12T00:00:00.000Z</published>
    </entry>
    <entry>
        <title type="html"><![CDATA[A sandbox is only as closed as what an AI agent can reach]]></title>
        <id>https://about.gitlab.com/blog/ai-agent-sandbox/</id>
        <link href="https://about.gitlab.com/blog/ai-agent-sandbox/"/>
        <updated>2026-08-12T00:00:00.000Z</updated>
        <content type="html"><![CDATA[<p>In July, OpenAI and Hugging Face responsibly disclosed an OpenAI model under internal evaluation escaped its sandbox, reached the open internet, and accessed Hugging Face’s internal production infrastructure. The agent took datasets, cluster details, and cloud keys during the intrusion.</p><p>The most critical part of the external phase of this incident was the first hour, when the agent escaped its sandbox by using a vulnerability within a package proxy on its sandbox’s allowlist to access the internet.</p><p>As more frontier model developers <a href="https://www.anthropic.com/news/investigating-incidents-cybersecurity-evals" rel="">disclose similar incidents</a>, the security industry needs to closely consider how agents impact reachability within test environments. You also do not have to run evaluation harnesses for this to be your problem. Any workload that executes code behind an egress list has the same structure: CI runners, hosted sandboxes, and network-reachable tool servers. Most of those allowlists were built to stop data leaving, but that is now not the only thing they need to stop.</p><h2 id="why-allowlists-extend-reachability">Why allowlists extend reachability</h2><p>When building an allowlist, you typically consider what a workload needs to contact and weigh each entry by what data could leave through it.</p><p>OpenAI’s agent revealed a blind spot for this typical process. The package proxy the agent accessed is a service: it authenticates callers, runs software with vulnerabilities, and talks to the public internet. While the sandbox could not reach the internet, the agent gained access to the package proxy, which did.</p><p>An allowlist hands your AI workload the reach of any destination it can take over.</p><h2 id="how-openais-model-escaped">How OpenAI’s model escaped</h2><p>To escape, OpenAI’s agent identified two zero-day vulnerabilities in the package proxy on its allowlist with a very large payoff.</p><p>The first flaw was a server-side request forgery flaw that let the agent ask the proxy to fetch arbitrary URLs on its behalf. In <a href="https://www.youtube.com/watch?v=87DyyMV0kCY&amp;t=721s" rel="">OpenAI&#39;s Black Hat presentation</a>, the model&#39;s reasoning at that moment reads &quot;<em>excellent, we have arbitrary SSRF</em>.&quot; The sandbox borrowed the proxy’s internet connection.</p><p>The second flaw was a privilege escalation. <a href="https://nvd.nist.gov/vuln/detail/CVE-2026-65616" rel="">CVE-2026-65616</a> (CVSS 8.8) causes a package proxy&#39;s refresh-token endpoint to issue new tokens without validating token signatures. These tokens carry their scope as a claim rather than the server looking it up, so once the signature goes unverified the claim is whatever the caller says.</p><p>In this case, the caller was the agent, which extended the access of its read-scoped token within the sandbox by editing its claim to administrative. It then submitted the token for refresh to the package proxy which returned an administrator-scoped token. As a result, the agent could act with administrator permission instead of its original read-only permission.</p><p>The agents worked as a group to break out. Together, they explored the one service they could reach until they found a way to make it fetch on their behalf, then shared the method so other agents could use it too. One agent noted that external exploitation was outside the scope of its instructions, but continued anyway.</p><p>Hugging Face and OpenAI also put the proxy compromise inside roughly the first half hour of the sandbox test despite the elusive nature of the vulnerabilities. Remember, these were  zero-days, so the agent could not reference a CVE or advisory. The package proxy is also closed-source, and its code was never in the agent’s training set.</p><h2 id="why-the-model-escaped">Why the model escaped</h2><p>We now know why the agent went after the proxy. It was stuck on its evaluation task, and OpenAI&#39;s presentation shows the model reasoning &quot;<em>perhaps answer online</em>&quot; before looking for a way out. Frontier models are rewarded for solving tasks quickly, so a stuck model looks for shortcuts, and OpenAI normally closes that one by disabling internet access.</p><p>There are still open questions about the agent&#39;s behavior, including everything the agent did during its four-day intrusion and what it did once it gained access to the internet. What we do know is that this agent revealed, in practical terms, that we must make some new considerations as we build test environments for security-capable, autonomous AI.</p><h2 id="how-to-reduce-risk-across-ai-test-environments">How to reduce risk across AI test environments</h2><p>If you’re building sandboxes for AI agents, here are four ways to reduce your risk and limit reachability:</p><ol><li><strong>Block the routes a build client never uses</strong>. A build client only downloads files. It has no reason to call the proxy&#39;s admin API, its configuration routes, or its token-refresh route, which swaps an expiring token for a new one and is the route that was abused in this incident.</li><li><strong>Restrict what the proxy itself can reach</strong>. The agent got out because the proxy could reach the whole internet, so anyone controlling the proxy could too. Limit the proxy’s outbound connections to the registries it actually serves.</li><li><strong>Monitor the proxy.</strong> A proxy serving a build-fleet is monotonous, with short connections, small downloads, and requests that mostly succeed. Consider alerting on anything that doesn’t follow that pattern, such as connections that stay open, data moving outward in bulk, a run of requests for packages that are not there, and any call to an admin route.</li><li><strong>Treat untrusted workloads as internet-facing.</strong> If an untrusted workload can reach an internal service, treat that service as internet-facing. Anything that compromises the workload can reach it too. We looked at the <a href="https://about.gitlab.com/blog/harden-pipeline-perimeter-for-ai-assisted-coding/" rel="">same question for CI runners earlier</a> this year, where the untrusted code runs in a pipeline rather than an agent sandbox.</li></ol><h2 id="cyber-capable-models-require-new-sandbox-considerations">Cyber-capable models require new sandbox considerations</h2><p>A sandbox is a list of things the workload inside it can talk to, and everything on that list brings its own reach with it. When a workload is a build job that doesn’t matter, but it does when agents widen that list in ways allowlist designs never anticipated.</p><p>Beyond evaluation harnesses, agentic workloads are also moving into CI, production automation, and into tooling that interacts with internal services. Each of those has a list with similar properties and structure. As models get better at finding and chaining flaws, the reach on those lists extends what agents can impact.</p><p>OpenAI observes that these agents remain &quot;bounded by the privileges they can obtain and the systems they can communicate with,&quot; so existing controls still work.<br />
What must change is how carefully we draw those lists to minimize reachability.</p><blockquote><p>Find more articles from the Threat Research team on our <a href="https://about.gitlab.com/blog/categories/security-labs/" rel="">Security Labs site</a>.</p></blockquote>]]></content>
        <author>
            <name>Daniel Abeles</name>
            <uri>https://about.gitlab.com/blog/authors/daniel-abeles/</uri>
        </author>
        <published>2026-08-12T00:00:00.000Z</published>
    </entry>
</feed>