Security Steward — Devpost
Tagline: Given the file a security finding flags, route it to the active engineer with the strongest evidence-based claim to that code — from GitLab's knowledge graph, not a stale CODEOWNERS file or a guess.
Inspiration
GitLab's blast-radius demo assigns each vulnerable component to its owner. But in real triage the hard question comes first: who owns this finding at all? Scanners (SAST, dependency, secret) emit findings with no assignee. Deciding who should fix them is manual, slow, and stalls remediation — and CODEOWNERS is often coarse, stale, or missing, worst exactly where it matters: on legacy and long-tail code whose authors have moved on. We wanted that routing decision to be evidence-based and auditable, not a guess.
What it does
Security Steward takes an affected file (or a vulnerability id it resolves to a file) and reasons from two facts in the GitLab Knowledge Graph (Orbit):
AUTHORED— who has actually changed this file/area (real merge-request history)MEMBER_OF— which of those people are still active on the project
…and returns one of three honest outcomes:
- the file's own authors are still active → assign the best-supported one;
- the authors aren't on the team but an active contributor maintains the area → assign them;
- nobody active → say so and escalate to CODEOWNERS / a lead, rather than invent an owner.
It then gates on a human confirmation and files one assigned GitLab issue
with the evidence in the description. Orbit is read-only; the single write is one
glab issue create.
How we built it
- Evidence comes entirely from read-only Orbit graph traversals:
User -[AUTHORED]-> MergeRequest -[HAS_DIFF]-> MergeRequestDiff -[HAS_FILE]-> MergeRequestDiffFile(matched onold_path), intersected withUser -[MEMBER_OF]-> Project. - Reasoning is a small, deterministic
continuity.py— no LLM in the decision path, so every recommendation traces to graph edges you can verify. - The only write is
glab issue create(assignee +security::remediationlabel + evidence body + Orbit provenance footer). - Ships in three forms: a reference CLI (
steward.sh) with a real confirmation gate, a committed GitLab Duo external agent, and an AI Catalog custom flow with a nativeHumanInputComponentapproval step.
Challenges we ran into
- No vulnerability→file edge in Orbit (
DETECTED_INpoints at a pipeline), so the file path comes from thelocationonVulnerabilityOccurrence. - Shared file paths across projects. In a multi-project namespace, dozens of
projects share
src/auth/.... A naïve author query collides across them, so we scope every query to the project with anIN_PROJECThop. - Orbit indexing is a per-namespace beta flag GitLab allow-lists; we couldn't enable it on our own group, so we ran the live demo on an already-indexed namespace.
- First-class vulnerability→issue linking is Ultimate-only, so we put the vulnerability URL in the issue body and never depend on the API — and never fabricate a finding link.
Accomplishments we're proud of
- It ran live, end to end, on a real indexed graph — not a mock. A file whose last author is not on the team is correctly routed to the active maintainer, and the assigned issue is filed with the evidence.
- Zero false positives. We ran the same logic across all 53 projects with
authorship history in the hackathon group: it surfaced zero false gaps —
it only fires on a genuine
AUTHORED-without-MEMBER_OF, and the project-scoped queries never cross-match shared paths. The recommendation is precise and auditable. - Safe by construction: read-only graph, one human-gated write.
What we learned
Code ownership is dynamic — it lives in contribution history and current team
membership, not a static file. For the long tail of legacy code that CODEOWNERS
misses, the knowledge graph is a better source of truth, and intersecting two
simple edges (AUTHORED ∩ MEMBER_OF) is enough to make a defensible,
explainable routing decision.
What's next
- Ingest scanner findings directly (the vuln-id → file resolution is already implemented) so it triggers on every new finding.
- Recency weighting using
merged_atto rank among multiple active maintainers. - Reconcile with CODEOWNERS — use it where it's accurate, fill its gaps where it isn't.
- Batch triage: route a whole security dashboard in one pass.
Built with
GitLab Knowledge Graph (Orbit) · glab · GitLab Duo Agent Platform / AI Catalog ·
bash · python · MIT.
Links
- Code (public, MIT): https://gitlab.com/selimsevim-group/security-steward
- Live demo project: https://gitlab.com/gitlab-ai-hackathon/transcend/35644762
- Filed issue (the result): https://gitlab.com/gitlab-ai-hackathon/transcend/35644762/-/issues/2
- Published AI Catalog flow: https://gitlab.com/gitlab-ai-hackathon/transcend/35644762/-/automate/flows/1012034/
Log in or sign up for Devpost to join the conversation.