Architecture

July 23, 2026 ยท View on GitHub

CyberEdge is a single-organization, self-hosted modular monolith. AI Agents are the only operators. Skills call the Rust Core through gRPC; humans use an optional strictly read-only Web projection.

Baseline

  • Rust 1.97: API, scheduler, workers, and scanner adapters
  • tonic + Tokio: gRPC and asynchronous runtime
  • Protobuf: the only control-plane contract
  • SQLx: transactional PostgreSQL repositories and migrations
  • PostgreSQL: assets, observations, findings, tasks, and audit events
  • Read Model: isolated query projection for the optional enterprise Web
  • OCI images + Docker Compose: the first deployment target

Domain flow

scope -> asset -> observation -> finding -> evidence -> remediation

The optional Web is compiled against a dedicated WebReadRepository contract. Its handlers cannot call Scope, Task, Schedule, Finding, worker, or outbox mutations even if the backing deployment currently reads the same PostgreSQL data. A separately stored event projection remains a later scaling boundary, not a prerequisite for enforcing read-only behavior.

Tasks are claimed with FOR UPDATE SKIP LOCKED. State changes, task events, discovery records, and outbox events are committed transactionally. A dedicated broker is introduced only when measured throughput proves PostgreSQL insufficient.

Scanner tools run behind adapters with explicit timeouts, resource limits, and normalized output. Raw tool output is evidence, never the domain model.

The passive adapters collect system DNS and Certificate Transparency observations. CT queries use crt.sh first and the documented Cert Spotter issuance API as an independent fallback; both outputs pass through the same in-scope normalization and wildcard filtering. The capability-gated active baseline performs a fixed TCP connect set, TLS leaf collection, bounded HTTP/path/crawl observation, offline screenshots, technology fingerprints, exposure detectors, and Host collision comparison. A separately authorized vulnerability baseline sends only derived Website targets to an isolated Nuclei adapter running a mounted signed-template allowlist. Separate intelligence policies send exact authorized domain names to isolated GitHub and licensed registration providers, and exact evidence-backed CPE names to an isolated NVD adapter. They retain normalized metadata, never source content, secret text, personal registration details, broad product guesses, or raw NVD applicability trees. Callers cannot provide ports, URLs, paths, headers, templates, flags, commands, CPEs, organization terms, or provider queries. Every result or coverage error becomes immutable Evidence before it affects inventory or Findings.

Local Agent calls use a Unix Domain Socket. Remote calls use HTTP/2 with mandatory mutual TLS. cyberedge-agent is a JSON stdin/stdout bridge intended for Skills, not a human command interface.

The optional Web reads a bounded projection from the repository. Its HTTP router registers only GET endpoints and static files; all state changes remain exclusive to gRPC. It binds only when explicitly enabled.

Boundaries

  • proto/: versioned Agent RPC contract
  • src/: domain, RPC, task engine, and infrastructure code
  • web/: optional read-only observation interface
  • docs/: architecture decisions and operator documentation

No human CLI, mutable Web console, multi-tenancy, microservices, message broker, plugin framework, or distributed workflow engine until a real constraint requires one.