Skip to main content
The web app wraps the same scan engine the CLI uses, and adds the parts that don’t make sense in a one-shot binary:
  • Sign in with GitHub. Identity is established via Supabase Auth’s GitHub provider.
  • Connect a GitHub account or organization. A separate GitHub App grants the API read-only access to repo workflows.
  • Continuous posture across every repo. One scan per repo, orchestrated client-side with bounded concurrency.
  • History and trends. Every scan persists to Postgres with row-level security scoped to the signed-in user.
  • Deep links back to GitHub. Each finding links to the exact file:line on the default branch.

Pages

RouteWhat
/loginGitHub OAuth login via Supabase Auth.
/connectPrompts you to install the GitHub App on accounts/orgs.
/connect/callbackReceives installation_id from GitHub and links it to the signed-in user.
/dashboardAggregate posture, donut by severity, trend chart, “scan all” button.
/repositoriesAll connected repos with per-repo severity counts. Search by name, filter findings by severity (counts narrow to the chosen level), and sort.
/repositories/:idPer-repo finding list, an Attacker Mind card with this repo’s toxic combinations, plus a card to override rule settings for this repo. An Export button (enabled once the repo has been scanned) downloads the latest results as JSON (findings + toxic combinations, matching the CLI’s -o json) or CSV (findings only).
/attacker-mindCross-repo toxic combinations. Search by name, filter by criticality, and sort.
/landscapeOwner-only OSS Posture Survey — upload a survey JSON (from the survey CLI) and explore findings + Attacker Mind for open-source repos. Search by name, filter findings by severity and combinations by criticality, and sort. The file is parsed in your browser; nothing is uploaded.
/rulesPer-user rule settings — disable rules you don’t care about globally or per repository.

Data flow

You click "Scan all"
  → SPA loops repos with bounded concurrency
    → POST /api/scan { repo_id } (one request per repo)
      → Go API fetches .github/workflows/* via GitHub API
      → scanner.ScanBytes(name, content)        ←── same engine as CLI
      → write scan + findings to Postgres (pgx, service role)
    → response includes severity counts + scan_id
  → SPA updates posture donut + trend line live
No git clone happens server-side — the API pulls workflow YAML via the GitHub Git Trees/Blobs API and scans the bytes in memory. Each per-repo request fits comfortably in a serverless time budget.

Read/write split around RLS

The React app reads from Postgres directly through supabase-js. Every table has row-level security scoped to auth.uid() = user_id, so users can only see their own data even though they’re hitting Postgres directly with their JWT.
The Go API only does the privileged work — minting GitHub installation tokens, fetching workflow YAML, scanning, and writing scans + findings via pgx as the service role (which bypasses RLS).

Next

GitHub setup

Connect a GitHub account or org so the dashboard can scan its workflows.

Rule settings

Disable rules you don’t care about — globally or per repository.

API reference

The HTTP endpoints under /api/* if you want to drive scans programmatically.