Skip to main content

System architecture

ZenVeil has three components that work together to deliver end-to-end security scanning:

Component overview

Python CLI (zenveil)

The CLI is the primary interface for developers. It orchestrates all scanning, AI analysis, and integrations. Scanning orchestrator — coordinates multiple scanners against a target and aggregates results into a unified ScanResult with consistent finding IDs, severities, OWASP categories, and evidence. Scanners — each scanner is independent and targets specific vulnerability classes: AI agent — Claude-backed modules for explain, fix, triage, and the interactive REPL. All AI calls stream token-by-token to the terminal.

FastAPI scanning API

The scanning API runs as a standalone Python service. It wraps the same scanning engine used by the CLI and exposes it over HTTP for use by the web dashboard and third-party integrations.
  • Auth: X-API-Key header
  • Base URL: https://api.zenveil.dev
  • Endpoints: /v1/scan/github, /v1/scan/api, /v1/explain, /v1/fix, /v1/triage, /v1/fix/pr
  • AI responses stream as text/plain

Node.js web server

The web server handles everything that isn’t scanning:
  • Dashboard — Clerk JWT authentication, user management, scan history
  • Billing — Stripe subscriptions (free / pro / team), checkout flow, webhook handling
  • API key management — issue and revoke CLI API keys tied to Stripe plan limits

Scan lifecycle

1

Target resolution

ZenVeil resolves the scan target:
  • repo — validates the path exists and is readable
  • github — parses owner/repo or full GitHub URL, downloads the archive via the GitHub API
  • api — validates the URL and checks for SSRF targets (private IP ranges are blocked)
2

Scanner dispatch

The orchestrator runs applicable scanners in sequence. Each scanner returns a list of Finding objects with:
  • Unique ID (e.g., ZG-A1B2C3)
  • Severity (CRITICAL, HIGH, MEDIUM, LOW)
  • OWASP categories
  • Location (file, line, column)
  • Evidence (what matched, with secrets redacted)
  • Confidence score (0.0–1.0)
  • Remediation guidance
3

Result aggregation

All findings are merged into a ScanResult and:
  • Rendered to the terminal as a rich table
  • Cached locally as .zenveil-last-scan.json for subsequent explain, fix, list, and triage commands
  • Optionally written to a JSON or HTML report file
4

Exit code

ZenVeil exits with code 1 if any CRITICAL or HIGH finding exists — perfect for CI/CD gates. All other severities exit 0.

Finding ID system

Every finding gets a stable, deterministic ID of the form ZG-XXXXXX (6 hex characters). The ID is based on the finding content — same code, same vulnerability, same ID. This makes ignoring, tracking, and referencing findings reliable across scans.

AI model routing

ZenVeil uses Claude (Anthropic) as the primary AI model for all analysis. Google Gemini is used as a fallback when Anthropic is unavailable. The model routing is transparent — you set your API keys and ZenVeil handles the rest.

Local-first design

For scan repo commands, no code leaves your machine. The scanning engine runs entirely locally:
  • File traversal and pattern matching: local Python process
  • CVE lookups (--check-cves): read-only requests to osv.dev (public, no auth)
  • AI analysis (explain, fix): your code snippet is sent to Anthropic/Gemini — see Security Philosophy
  • GitHub scanning: the repository archive is downloaded to a temporary directory and deleted after scanning

Data flow for GitHub scanning