Inspiration
Agents can now write the code, open the merge request and run the pipeline. The step nobody should hand over quietly is the last one: shipping to production. Once an agent or a pipeline can deploy on its own, the honest question after every release is "who said yes?" I wanted GitLab to be able to answer that with a name, a commit and a record, without slowing down the deploys that are already inside the rules.
What it does
Aegis GitLab Gate puts a human approval checkpoint in front of any job in a GitLab pipeline.
- A gate job asks before a deploy job runs. The gate sends the action, its cost, its scope and the exact commit to Aegis, an approval service for AI agents. The deploy job
needsthe gate, so it only runs on an explicit "allowed". - Three outcomes, all shown in the demo on a real pipeline. The staging deploy is inside policy and goes straight through. The production deploy is above the approval threshold, so the pipeline stops and waits for the owner. A teardown job asks for a scope nobody allowed and is blocked, so its destructive step never runs.
- The pipeline cannot approve itself. GitLab holds only the agent's key. The owner approves from outside GitLab with their own key, and the gate refuses to start if it is ever given an owner key.
- Approval is single-use and tied to the commit. The job releases the held action with a one-time token bound to the project, branch, commit and pipeline. A different commit needs a new approval.
- It fails closed. A timeout, a network error, an unexpected answer or an expired hold all fail the job.
- A GitLab Duo Agent Platform flow briefs the approver. A custom flow, "Aegis Release Gate", is triggered when it is assigned as reviewer or mentioned on a merge request. It reads the change and the gate job logs and posts one brief: what changed, what the gate will ask, the decision so far, and exactly what the owner is being asked to approve. It is read-only and cannot approve anything.
How I built it
- The gate is a small Python package (
aegis_gate) with no dependencies beyond the standard library, run aspython -m aegis_gateinside a CI job. It writes its outcome to a dotenv report so later jobs can read it. - The pipeline (
.gitlab-ci.yml) has a reusable.aegis-gatejob that any deploy can extend, dry-run previews on merge requests that show the exact request each gate will send after merge, and a GitLab Pages deploy that stamps the page with the commit, pipeline and approval record. - The Duo Agent Platform pieces are a two-step custom flow (an analyst that reads the merge request, diff and job logs, then a writer that posts the brief), an agent definition and a skill, all kept in the repository and validated in CI by GitLab's AI Catalog sync component.
- Tests: 86 unit tests run against a local mock of the approval service, in the pipeline on every push.
Challenges
- Secrets and flows. Custom CI/CD variables are not available to flow jobs, so the approval key cannot live in a flow. I kept the gate in an ordinary CI job and gave the flow a read-only job: explain the gate, never operate it.
- Making "held" safe. A waiting job must not turn into a deploy by accident, so every way of not getting a clear "allowed" ends in a failed job.
- Keeping the approver separate. If the pipeline could hold the owner's key, it could approve itself, so the gate checks for that and refuses to run.
What I'm proud of
- The whole cycle ran for real in the hackathon project: allowed, held then approved then released, and blocked, with the site published to GitLab Pages only after the approval.
- The flow's first real brief was honest about what it had not read and did not claim a decision that did not exist yet.
- I weakened the gate ten different ways on purpose (for example, proceeding on a timeout) and the test suite now fails on every one.
What I learned
Giving the agent less to do made the result more trustworthy. The flow explains and the gate enforces, and neither one can do the other's job.
What's next
- Trigger the flow automatically when a gate job goes into a hold, so the brief arrives at the moment the owner is asked.
- Publish the flow and agent to the AI Catalog.
- Add a merge request widget that shows the gate's pending action and its expiry.
Built With
- aegis
- gitlab
- gitlab-ci
- gitlab-duo
- gitlab-pages
- python
Log in or sign up for Devpost to join the conversation.