Nick Duong · Architecture notes
← GitHubScanner: full notes

Cheatsheet · AI security review · GCP deployment

GitHubScanner

The whole system on one page: numbers, flows, design decisions and lessons. Hover or tap an underlined acronym for its meaning.

Full notes with diagrams →
6specialist agents
OSV + EPSSCVE intelligence
3,400+tests
86%coverage

Developer / API caller

FastAPI service

Root agent (Google ADK)
Gemini 3 Flash

Shallow clone
(GitHub App token)

Security agent
OWASP / CWE / Java-Spring

Dependency agent
OSV CVEs + EPSS + EOL

Deterministic
validators

Report
A–F grade · HTML/JSON → GCS

Remediation
patch in temp clone → developer reviews

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

  1. POST /scan → root agent.
  2. Shallow clone with a GitHub App token, detect the stack.
  3. Planner → Security agent (regex hints → LLM judgment) and Dependency agent (manifests and lockfiles → OSV, EPSS, EOL, licences, typosquats).
  4. Hallucination validator → report agent.
  5. Grade, HTML/JSON report to GCS, signed URL back.
  6. 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)

  1. Grounding: cite file + line + snippet, 8-item pre-output checklist, ID prefixes (JAVA-, PY-, JS-, DEP-, SEC-), max 20 findings.
  2. Regex hints: the model judges hints instead of inventing from nothing.
  3. HallucinationValidator (no LLM judge): approved CWE list · severity ↔ exploitability · line-number sanity · snippet SHA-1 · 22 "synthetic evidence" phrases, ≥ 2 indicators = flagged.
  4. Gate: > 5% invalid → strip invalid findings and flag the scan.
  5. 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

  1. CodePipeline (dev / qa) → CodeBuild (Python 3.12, hardened base image).
  2. Security gates: SAST · OSS licence + vuln · image scan · code quality.
  3. Task-role credentials → GCP STS token exchange (aws4_request) → impersonate one deploy SA.
  4. Push to Artifact Registry, tagged latest, vX.Y.Z and git SHA.
  5. 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_SERVICE set → 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 /scan returns scan_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 permitAll on a sensitive route? do two mediums chain into a critical?).

Engineering lessons

  1. LLM "fixes" overwrote whole files with a snippet → size guards, read-only by default. Validate LLM output like user input.
  2. Non-deterministic re-scans couldn't answer "is it fixed?" → verification mode with deterministic IDs and fingerprints.
  3. Gemini 3 looped at temperature < 1.0 → pinned to 1.0, thinking budget moved to the planner.
  4. Network controls blocked Vertex AI; proxies broke HTTP/2 → error classifier reports infrastructure errors, not "no findings".

Testing an LLM agent

  • conftest.py mocks google.adk globally.
  • 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