Platform architecture - the four domains

How guard-agent, the Core API, and the dashboard fit together: subdomains, ports, the telemetry path, and where your data lives.

3 min read · verified against [email protected]

Guard Core is a single monorepo serving four subdomains through one nginx reverse proxy. Each subdomain routes to a different service, but from a networking perspective there is one ingress, one process per service, and one shared data layer.

Four subdomains, one platform

DomainServicePort
guard-core.comFrontend (Next.js) - marketing landing page3000
app.guard-core.comFrontend (Next.js) - authenticated SaaS dashboard3000
playground.guard-core.comFrontend (Next.js) - interactive playground3000
api.guard-core.comCore API (FastAPI) - telemetry ingest and SaaS API8000

All three frontend domains are served by the same Next.js process on port 3000. The middleware detects the subdomain from the Host header and rewrites internally to the appropriate route group. Nginx reverse-proxies all four domains; api.guard-core.com routes directly to port 8000, bypassing Next.js entirely.

The services

guard-core-api (port 8000) - the Core SaaS API. Receives telemetry events from guard-agent, aggregates security metrics, manages projects, organizations, users, API keys, webhooks, and encryption key rotation. Accessed externally at api.guard-core.com. Built with FastAPI, SQLAlchemy 2.x async, and asyncpg.

guard-playground (port 8001, internal only) - the interactive playground backend. Dogfoods fastapi-guard features so users can explore blocking, rate limits, passive mode, and detection patterns without connecting a real application. Port 8001 is not exposed externally; the Next.js playground pages proxy requests through Next.js API routes.

Frontend (port 3000) - unified Next.js 16 application. Serves the landing page, the authenticated SaaS dashboard at app.guard-core.com, and the playground at playground.guard-core.com. The dashboard is the surface where agents' buffered telemetry is visualized.

Nginx - terminates TLS and reverse-proxies all four domains. api.guard-core.com routes to port 8000 directly. The three frontend domains route to port 3000; Next.js middleware handles subdomain routing from there.

The telemetry path end to end

A security event travels this path from detection to dashboard:

  1. fastapi-guard (installed in your application) detects an event - a SQLi probe, a rate-limit hit, a behavioral rule trip.
  2. guard-agent (the embedded agent library) appends the event to an in-memory buffer.
  3. On a size-or-time flush trigger, the agent POSTs a batch to the Core API - either POST /api/v1/events (plain) or POST /api/v1/events/encrypted (when a project encryption key is configured).
  4. The Core API authenticates the request via X-API-Key, validates the project scope, and persists the events.
  5. The dashboard at app.guard-core.com queries the Core API and surfaces the events - in the Events page, the Threats view, and the Metrics charts.

The telemetry data flow - buffering triggers, encryption lifecycle, and every place an event can be lost - is covered in the telemetry data flow concept doc.

Where your data lives

Redis - shared cross-instance state: rate-limit counters (per IP, per route), the active ban list, and optionally the agent event buffer for delivery durability. All fastapi-guard instances in a deployment must share the same Redis instance and prefix so ban decisions and rate-limit counters are globally consistent. See Redis backend & failure modes.

Persistent store (Core API) - security events, aggregated metrics, project and organization records, API key hashes, encryption key versions, user accounts. Backed by PostgreSQL via SQLAlchemy async. If a project has an encryption key, events are persisted encrypted; the Core API holds the historic key versions needed to decrypt them on read.

What talks to what

  • guard-agent → Core API: POSTs telemetry batches to api.guard-core.com/api/v1. Authenticated with X-API-Key. Optional AES-256-GCM encryption over TLS.
  • guard-agent → Core API: the agent reports status to POST /api/v1/status (Push Agent Status, per the API catalog).
  • Dashboard → Core API: authenticated REST calls for events, metrics, threats, project management.
  • Nginx → Frontend: proxies guard-core.com, app.guard-core.com, playground.guard-core.com to port 3000.
  • Nginx → Core API: proxies api.guard-core.com to port 8000.
  • Frontend → Playground API: Next.js API routes proxy playground requests to port 8001 (internal; never directly exposed).
  • Core API → Redis: reads and writes rate-limit ZSETs and ban-list keys.
  • Core API → PostgreSQL: reads and writes all persistent records.