Inspiration

Likeness lets creators license their face to AI ads: every licence is approved by the creator, every render is paid, and consent can be revoked any time. In this product a bug isn't downtime: it means someone's face used without permission. So after the code is written, every change is consent-critical. We wanted the whole post-code lifecycle to defend consent automatically, with a human approving the outcome.

What it does

Likeness (an existing MIT project, built 10–18 Oct for the Google AI Builder Cup) was imported to GitLab, and we built supervised, consent-aware delivery around it with the GitLab Duo Agent Platform:

  • Likeness delivery (supervised): assign an issue to the agent; it implements it on a duo/feature/* branch, reviews its own MR against our consent policy, and reports back. It has no merge tool.
  • Consent Guardian: reviews MRs against CONSENT_POLICY.md (12 rules, read from main, never the MR branch; diffs treated as untrusted data) and labels them consent::safe, consent::review or consent::block. A consent-gate CI job turns that verdict into a hard gate.
  • Duo Fix CI/CD Pipeline (GitLab foundational flow): diagnoses failed pipelines and suggests the fix; a human applies it.
  • Release & Monitor: after a green main pipeline, reads the staging smoke and consent end-to-end results and posts release notes on the source issue or MR, matching the GitLab Release.
  • Issue Triage: labels new issues, splits them into tasks, and flags consent-sensitive work for Guardian review.

The human gate is the merge (with a DCO sign-off) and a manual production deploy.

How we built it

  • Verify: typecheck, 45 unit tests, 16 consent invariant tests running the real render, charge, receipt and verify code against in-memory Firestore, Storage and KMS stand-ins (with a real P-256 key).
  • Secure: SAST, Secret Detection (full history), Dependency and Container Scanning. Container findings went from 1,004 to 162, critical from 9 to 0.
  • Package: Docker image with SBOM, promoted by digest to Artifact Registry; a license check gates packaging.
  • Configure / Release: Cloud Run staging and production, Firestore, Cloud KMS, Secret Manager, all created by an idempotent, guarded script. GitLab authenticates to Google Cloud with Workload Identity Federation (no keys). Every green main pipeline creates a GitLab Release.
  • Monitor: GitLab CI/CD observability, plus post-deploy smoke (10/10) and consent end-to-end (9/9) tests against staging.
  • Govern: production deploys are pinned to the release approver's GitLab user via WIF, a deploy guard refuses the frozen production app, a per-pipeline audit report is kept for a year, and the consent policy lives in the repo as code.

Challenges we ran into

  • Triggers only fire on human actions, so flows can't chain. We designed one multi-step delivery flow plus deliberate human touchpoints.
  • Flow runtime: a slim container image without curl stopped the agent from starting; we switched to GitLab's default image and added a CI check so it can't regress.
  • Release notes went nowhere at first: the flow had no tool to comment on an MR. We added it and a fallback order (issue, then MR, then a new issue).
  • Composite identity makes flow-created MRs count as authored by the triggering human, so approval rules can't gate them. The merge itself became the documented gate.
  • No protected environments for our role, and thousands of inherited Developers could run manual jobs, so we pinned production access to one GitLab user id at the Google Cloud level.

Accomplishments we're proud of

All nine DevSecOps stages run for real, with evidence in docs/STAGES.md. A change that removes the licence check is blocked twice: by the Consent Guardian (consent::block) and by four failing consent tests.

What we learned

Agents are most useful when their powers are narrow and explicit: read the policy from main, treat diffs as data, never merge. Deterministic tests and an AI reviewer complement each other.

What's next

Run the incident and rollback path of Release & Monitor on a real staging failure, and apply the same consent gates to the creator payout flow.

Built With

  • artifact-registry
  • c2pa
  • cloud-kms
  • cloud-run
  • cyclonedx
  • docker
  • firebase-auth
  • firestore
  • gemini
  • gitlab
  • gitlab-ci
  • gitlab-duo-agent-platform
  • gitlab-observability
  • google-cloud
  • next.js
  • node.js
  • secret-manager
  • semgrep
  • trivy
  • typescript
  • veo
  • vertex-ai
  • vitest
  • workload-identity-federation
Share this project:

Updates

Submission history