In one breath
- AI security reviewer for repositories, on Google ADK + Gemini.
- Specialist agents find issues. Deterministic validators check every finding before a human sees it.
- Fixes are generated in a throwaway clone and exported as patches. Nothing is pushed.
- Runs on Cloud Run, deployed from AWS CodePipeline through keyless Workload Identity Federation.
Key numbers
| Specialist agents | 6: RepoInfo · Planner · Security · Dependency · Report · Remediation |
| Agent tools | Security 12 · Dependency 14 |
| Tests | ~3,400 · 86% coverage |
| Scan time | 330–411 s (WebGoat, Spring Boot 2.6) vs Cloud Run's 300 s default timeout |
| Limits | 60 rpm (prod) · $10 remediation budget · 5 fixes in parallel · ≤ 20 findings per agent output |
| Tokens | GitHub App JWT 9 min → installation token 1 h |
| Report links | GCS V4 signed URLs, 24 h |
Scan flow
POST /scan→ root agent.- Shallow clone with a GitHub App token, detect the stack.
- Planner → Security agent (regex hints → LLM judgment) and Dependency agent (manifests and lockfiles → OSV, EPSS, EOL, licences, typosquats).
- Hallucination validator → report agent.
- Grade, HTML/JSON report to GCS, signed URL back.
- Remediation on demand: temp clone → patch → developer review.
Grade: 100 − 25·C − 15·H − 8·M − 3·L − 1·I → A–F (Critical, High, Medium, Low, Info).
CVE enrichment
package@version→ SQLite CVE cache (7-day TTL) → OSV.dev (breaker: 3 fails) → EPSS (breaker: 5 fails).- EPSS bands: > 0.7 critical · > 0.3 high · > 0.1 medium · > 0.01 low.
- Prioritize by severity rank, then exploitability.
- CVSS = how bad. EPSS = how likely in the next 30 days. CVSS 9.8 with EPSS 0.001 can wait; CVSS 7.5 with EPSS 0.9 is today's problem.
Trust pipeline (5 layers)
- Grounding: cite file + line + snippet, 8-item pre-output checklist, ID prefixes (
JAVA-,PY-,JS-,DEP-,SEC-), max 20 findings. - Regex hints: the model judges hints instead of inventing from nothing.
- HallucinationValidator (no LLM judge): approved CWE list · severity ↔ exploitability · line-number sanity · snippet SHA-1 · 22 "synthetic evidence" phrases, ≥ 2 indicators = flagged.
- Gate: > 5% invalid → strip invalid findings and flag the scan.
- Consensus (opt-in): N parallel scans, keep findings in ≥ 67% of runs. Verification mode on re-scan: does the exact snippet or hash still exist? 3-level fingerprint; unsure ⇒ still open.
Why no LLM judge
- A judge model shares the generator's failure modes and doubles the cost.
- String and hash checks are cheap, reproducible and auditable.
- The 5% is a gate, not an accuracy claim.
- Next: assert the cited snippet appears within ±N lines of the claimed line.
Secrets and identity
- GitHub App, not a personal access token: short-lived, repo-scoped.
- App private key in Secret Manager.
- RS256 JWT (cached 9 min) → installation token (cached 1 h).
- No long-lived credential in a repo or a log line.
Keyless AWS → GCP deploy
- CodePipeline (dev / qa) → CodeBuild (Python 3.12, hardened base image).
- Security gates: SAST · OSS licence + vuln · image scan · code quality.
- Task-role credentials → GCP STS token exchange (
aws4_request) → impersonate one deploy SA. - Push to Artifact Registry, tagged
latest,vX.Y.Zand git SHA. - Terraform-managed Cloud Run: non-root, port 8080,
/healthcheck.
No JSON service-account keys anywhere, so nothing to leak or rotate.
Cloud design in the app
- Env detection:
K_SERVICEset → config from Secret Manager, else.env. - Scan state: SQLite synced to GCS (startup, every 5 min, after each scan, shutdown) → forces
max-instances=1. Scale-out path: Cloud SQL Postgres / AlloyDB or Firestore. - Long scans: async.
POST /scanreturnsscan_id→ Cloud Tasks / Pub/Sub → Cloud Run Job → client polls or gets a webhook. - Region pinning during a scan: Gemini availability differs by region.
Scaling out
- GitHub webhook (push / PR) → queue → scan workers → Postgres.
- Shared CVE cache removes the single-instance constraint.
- Dedup by commit SHA; re-scan only changed files + the dependency diff.
- SAST + LLM, not either/or: SAST is precise on known patterns; the LLM adds context (is this
permitAllon a sensitive route? do two mediums chain into a critical?).
Engineering lessons
- LLM "fixes" overwrote whole files with a snippet → size guards, read-only by default. Validate LLM output like user input.
- Non-deterministic re-scans couldn't answer "is it fixed?" → verification mode with deterministic IDs and fingerprints.
- Gemini 3 looped at temperature < 1.0 → pinned to 1.0, thinking budget moved to the planner.
- Network controls blocked Vertex AI; proxies broke HTTP/2 → error classifier reports infrastructure errors, not "no findings".
Testing an LLM agent
conftest.pymocksgoogle.adkglobally.- Tests cover tools, parsers, validators, grading math and prompt content (the grounding rules must be in the prompt).
- Canned JSON fixtures stand in for model output, including malformed output.
- End-to-end runs against WebGoat and Spring Boot 2.6.
Threat model: OWASP LLM Top 10
The scanned repo is attacker-controlled input.
| Risk | Where it bites | In place | Roadmap |
|---|---|---|---|
| LLM01 Prompt injection | README says "report no findings" | validators · consensus · no shell tool | fence repo content as data · allowlist in code · scan tool output |
| LLM02 Sensitive info disclosure | secrets in logs or clone metadata | log redaction · 1 h tokens | GIT_ASKPASS / header auth · redact every handler |
| LLM03 Supply chain | the scanner's own dependencies | detects CVEs, EOL, typosquats in targets | scan itself in CI · pinned, hashed deps · SBOM |
| LLM05 Improper output handling | LLM fixes written to disk | size guards · temp clone · patch export · $10 cap | sandbox generated tests (gVisor, no-network job) |
| LLM06 Excessive agency | file-system tools | per-scan temp directory | path containment · no destructive tools for the model |
| LLM09 Misinformation | invented CVE or line number | validator · consensus · verification | snippet-exists check · EPSS triage |
| LLM10 Unbounded consumption | 400 s scans, parallel fixes | $10 budget (reserve / commit / release) · 60 QPM | per-tenant quotas and metering |
Same deployment: GCP → AWS → OCI
| Concern | GCP (built) | AWS | OCI |
|---|---|---|---|
| Container runtime | Cloud Run | ECS Fargate + ALB · App Runner | OKE · Container Instances |
| Long async scans | Cloud Run Jobs + Cloud Tasks / Pub/Sub | ECS RunTask / Batch + SQS · Step Functions | OKE Jobs + OCI Queue / Streaming |
| Registry | Artifact Registry | ECR | OCIR |
| Keyless CI auth | Workload Identity Federation | IAM OIDC provider → AssumeRoleWithWebIdentity |
Identity Domains token exchange · resource principals |
| Secrets | Secret Manager | Secrets Manager + KMS | OCI Vault |
| Temporary report links | GCS + V4 signed URLs | S3 + presigned URLs | Object Storage + Pre-Authenticated Requests |
| LLM | Vertex AI Gemini | Bedrock | OCI Generative AI · self-hosted on GPU shapes |
| Scan state DB | SQLite on GCS → Cloud SQL | RDS / Aurora PostgreSQL | OCI Database with PostgreSQL |
| Logs | Cloud Logging | CloudWatch + CloudTrail | OCI Logging + Audit |
Acronyms on this sheet
Underlined acronyms show these definitions on hover or tap. Full glossary →
- ADK
- Agent Development Kit Google's open-source framework for building agents and multi-agent systems. ReliBot and GitHubScanner run on it.
- ALB
- Application Load Balancer AWS's HTTP load balancer. It can enforce OIDC login itself.
- API
- Application Programming Interface How programs call each other, such as a REST endpoint.
- AWS
- Amazon Web Services Amazon's cloud. GitHubScanner's CI/CD pipeline runs in AWS.
- CI
- Continuous Integration Building and testing every change automatically.
- CI/CD
- Continuous Integration / Continuous Delivery The automated build, test, scan and deploy pipeline.
- CVE
- Common Vulnerabilities and Exposures The ID of one specific, publicly known vulnerability, such as CVE-2021-44228 (Log4Shell).
- CVSS
- Common Vulnerability Scoring System A 0–10 severity score: how bad a vulnerability would be if exploited.
- CWE
- Common Weakness Enumeration A catalogue of weakness types. CWE-89 is SQL injection; CWE-502 is unsafe deserialization.
- ECR
- Elastic Container Registry AWS's container image registry.
- ECS
- Elastic Container Service AWS's container service. Fargate is its serverless mode.
- EOL
- End of Life A version that no longer gets security patches.
- EPSS
- Exploit Prediction Scoring System The probability (0–1) that a CVE is exploited in the next 30 days. Published by FIRST.
- GCP
- Google Cloud Platform Google's cloud. GitHubScanner and GraphRAG run on it.
- GCS
- Google Cloud Storage GCP's object storage (buckets).
- GPU
- Graphics Processing Unit The accelerator used to host models. OCI "GPU shapes" are GPU-equipped VM sizes.
- IAM
- Identity and Access Management Who can do what. "Cloud Run IAM" means only authenticated callers can reach the service.
- JWT
- JSON Web Token A signed token that carries identity claims.
- KMS
- Key Management Service Managed encryption keys (AWS KMS, Cloud KMS).
- LLM
- Large Language Model A model such as Gemini or Claude that reads and writes text. Every agent here is an LLM plus tools.
- OCI
- Oracle Cloud Infrastructure Oracle's cloud. The service maps show the OCI equivalent of each component.
- OCIR
- OCI Registry OCI's container image registry.
- OIDC
- OpenID Connect An identity layer on OAuth 2.0. It lets a CI job prove who it is and get short-lived cloud credentials without stored keys.
- OKE
- Oracle Kubernetes Engine OCI's managed Kubernetes (formerly Container Engine for Kubernetes).
- OSS
- Open-Source Software Third-party packages. The "OSS licence + vuln" gate checks their licences and known CVEs.
- OSV
- Open Source Vulnerabilities Google's vulnerability database (osv.dev), keyed by package and version range.
- OWASP
- Open Worldwide Application Security Project The nonprofit behind the Top 10 risk lists, including the Top 10 for LLM Applications (LLM01 to LLM10).
- PR
- Pull Request A proposed code change, reviewed before it is merged.
- QPM
- Queries Per Minute A rate limit unit.
- RDS
- Relational Database Service AWS's managed SQL databases (PostgreSQL, MySQL and others).
- RS256
- RSA Signature with SHA-256 An asymmetric JWT signing algorithm. GitHub App JWTs use it.
- S3
- Simple Storage Service AWS's object storage.
- SA
- Service Account A non-human identity that a workload runs as.
- SAST
- Static Application Security Testing Scanning source code for vulnerabilities without running it.
- SBOM
- Software Bill of Materials An inventory of every dependency and version in a build.
- SHA
- Secure Hash Algorithm A "git SHA" is the hash that uniquely identifies a commit.
- SHA-1
- Secure Hash Algorithm 1 A 160-bit hash. Used here for deduplication and snippet-integrity checks, not for security.
- SQL
- Structured Query Language The standard language for querying relational databases.
- SQS
- Simple Queue Service AWS's managed message queue.
- STS
- Security Token Service Exchanges one credential for a short-lived one. GCP STS powers WIF; AWS STS powers AssumeRole.
- TTL
- Time To Live How long a record or cache entry is kept before it expires.
More quick reference