Skip to main content

SecurityV0 Platform Architecture Overview

Context

SecurityV0 is an Autonomous Execution Exposure Management platform — a system of record for execution authority over time. It discovers standing execution paths where autonomous identities (NHIs, agents, service principals) continue operating after human ownership decays, scope drifts, or intent is fulfilled.

This document defines the system-level architecture: services, data flow, deployment topology, and security boundaries. It is the entry point for all other design documents.

Design Constraints (from CLAUDE.md)

  • Deterministic — No ML classifiers, probabilistic judgments, or heuristic scoring
  • Read-only ingestion — Connectors never modify source systems; ingestion is metadata-only. Platform-issued tickets to external systems (Jira / GitHub / ServiceNow / Linear) initiated by the user as part of a remediation action are a separate, permitted outbound action — see ADR-019.
  • Explainable — Every finding must be walkable end-to-end with no interpretation
  • Temporal — Track how the execution/authority graph changes over time (drift, not just current state)
  • Evidence-grade — Outputs must be immutable, timestamped, and verifiable

Architecture Diagram

SV0 System Overview

Full-resolution source: diagrams/sv0-system-overview.excalidraw


System Architecture

┌──────────────────────────────────────────────────────────────────────┐
│ EXTERNAL SOURCES │
│ Entra ID (Graph API) ServiceNow (REST) GitHub (API) ... │
└──────────────┬───────────────────┬──────────────────┬────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────────────────────────────────────────────┐
│ CONNECTOR LAYER │
│ ┌─────────────┐ ┌──────────────────┐ ┌─────────────┐ │
│ │ Entra ID │ │ ServiceNow │ │ GitHub │ ... │
│ │ Connector │ │ Connector │ │ Connector │ │
│ └──────┬──────┘ └────────┬─────────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┼────────────────────┘ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Normalizer + │ │
│ │ Diff Engine │ │
│ └────────┬────────┘ │
└────────────────────────────┼─────────────────────────────────────────┘


┌─────────────────────────────┐
│ MongoDB │
│ │
│ entities (current state) │
│ entity_versions (history) │
│ events (change log) │
│ baselines (snapshots) │
│ sync_cursors (audit log │
│ sync progress) │
│ connector_syncs │
│ findings │
│ evidence_packs │
└──────────────┬───────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ CORE SERVICES │
│ ┌──────────────────┐ ┌──────────────────┐ ┌─────────────────┐ │
│ │ Query Service │ │ Trigger │ │ Evidence Pack │ │
│ │ (paths + history)│ │ Evaluator │ │ Generator │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬────────┘ │
│ │ │ │ │
│ ┌────────┴──────────────────────┴──────────────────────┴────────┐ │
│ │ INTEROPERABILITY LAYER │ │
│ │ ┌─────────────────┐ ┌──────────────────────────────┐ │ │
│ │ │ OAA Exporter │ │ SCIM API (read-only) │ │ │
│ │ │ (canonical perms)│ │ /Users, /Groups, /Schemas │ │ │
│ │ └─────────────────┘ └──────────────────────────────┘ │ │
│ └────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────┬──────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ API GATEWAY │
│ Auth (OAuth 2.0 / API Keys) │ Rate Limiting │ Tenant Routing │
└──────────────────────────────────┬───────────────────────────────────┘


┌──────────────────────────────────────────────────────────────────────┐
│ CONSUMERS │
│ Web UI (findings) │ API clients │ IGA/PAM tools │ GRC exports │
│ │ │ (SailPoint, │ │
│ │ │ Saviynt) │ │
└──────────────────────────────────────────────────────────────────────┘

Entity Model

SecurityV0 models execution authority as a directed graph of 9 entity types in three functional groups:

  • Execution: workload → connection → credential (how code reaches external systems)
  • Authorization: identity → role → permission → resource (what an identity can do)
  • Governance: owner (accountability), execution_evidence (proof of execution)

Two paths converge at the identity node:

  1. Execution chain: Automation →INVOKES→ Connection →USES→ Credential →AUTHENTICATES_AS→ Identity
  2. Authorization path: Identity →HAS_ROLE→ Role →GRANTS→ Permission →APPLIES_TO→ Resource

A workload's blast radius = follow the execution chain to the identity, then follow that identity's authorization path to the resources it can reach.

See 01-data-model.md for the full relationship set including runtime cycles (CALLS, TRIGGERS_ON, EXECUTES_ON), org hierarchy (BELONGS_TO), cross-system auth (AUTHENTICATES_TO), and execution evidence.


Technology Decisions

  • Database: MongoDB — single document store for all entity data, relationships, temporal versions, events, and evidence packs. Rationale in ADR-001.
  • Graph visualization: @xyflow/react + ELK.js layout engine. Technology selection and migration history in ADR-011.
  • Connector interface: Connector-agnostic NormalizedGraph schema — connectors transform source data, platform owns ingestion. Rationale in 05-connectors.md.

Service Boundaries

1. Connector Layer

Responsibility: Extract data from external sources, transform to normalized schema, diff against previous state, emit change events.

  • Each connector is an independent, deployable unit
  • Connectors are database-agnostic — they produce a NormalizedGraph output
  • Scheduling: configurable per-connector (hourly, daily, on-demand)
  • Isolation: each connector sync runs in its own container/process with tenant-scoped credentials
  • See: architecture/05-connectors.md

2. Normalizer + Diff Engine

Responsibility: Compare incoming NormalizedGraph against previous known state. Write documents and events to MongoDB.

  • Computes: nodes added/removed/modified, edges added/removed/modified
  • Writes: full entity documents + change events to MongoDB
  • Recomputes: materialized execution paths on affected entities
  • Idempotent: re-running the same sync produces no duplicate events

3. Document Store (MongoDB)

Responsibility: Single source of truth for all data — entities, relationships, history, events, findings, evidence.

  • Collections: entities, entity_versions, events, baselines, sync_cursors, connector_syncs, findings, evidence_packs
  • Rich documents: full policy JSON, raw API responses, nested metadata
  • Relationships: stored as references within entity documents + denormalized for query performance
  • Temporal: versioned documents with valid_at/expired_at for point-in-time queries
  • Events: append-only change log with TTL indexes
  • Materialized paths: pre-computed execution paths stored on identity documents
  • Tenant isolation: tenant_id field on all documents, compound indexes
  • See: architecture/03-database.md

4. Query Service

Responsibility: Execute graph path queries and document queries against MongoDB.

  • Path queries: application-level traversal following relationship references
  • Cross-system path traversal: follows AUTHENTICATES_TO edges to discover execution paths spanning multiple systems (e.g., Entra SP → ServiceNow resources)
  • Materialized paths: pre-computed execution_paths arrays on identity documents for fast blast radius (includes auth_chain_depth for cross-system paths)
  • Reverse queries: denormalized accessible_by arrays on resources
  • Ownership hierarchy queries: traverses BELONGS_TO relationships to resolve inherited ownership
  • History queries: direct reads from entity_versions collection
  • Combined: "show me execution paths that changed in the last 90 days for orphaned identities"
  • Caching: short-lived cache for repeated path computations (invalidated on sync)

5. Trigger Evaluator

Responsibility: Run deterministic rules against entity data to detect findings. No ML, no scoring.

  • Rules: Orphaned Ownership, Ownership Degraded, Dormant Authority, Scope Drift, Privilege-Justification Gap
  • Ownership evaluation: checks all ownership levels (primary/secondary/inherited via BELONGS_TO hierarchy). orphaned_ownership fires only when ALL levels have decayed; ownership_degraded fires when primary decays but secondary/inherited remains active
  • Input: entity documents + recent events from MongoDB
  • Output: Finding records with deterministic explanations
  • Scheduling: runs after each connector sync completes
  • Idempotent: same entity state produces same findings

6. Evidence Pack Generator

Responsibility: Assemble immutable, timestamped evidence packs for each finding.

  • Joins: identity summary + authority snapshot + temporal context (events) + blast radius (materialized paths)
  • Seals: SHA256 hash of pack contents
  • Stores: sealed pack in MongoDB evidence_packs collection
  • Exports: JSON and Markdown (MVP); PDF as optional post-MVP conversion from Markdown/HTML

7. Interoperability Layer (OAA/SCIM)

Responsibility: Export SecurityV0 data in industry-standard formats for external tool integration.

This layer follows patterns proven by OAA (Open Authorization API) and SCIM, enabling SecurityV0 to integrate with the broader identity security ecosystem without custom integration code.

OAA Exporter

Exports authorization data in OAA-compatible format:

  • Application payloads: Export all identities, roles, permissions, resources for an Application
  • Canonical permissions: All permissions classified using 10-type OAA taxonomy (DataRead, DataWrite, etc.)
  • Endpoints:
    • GET /api/v1/oaa/applications — list all Applications
    • GET /api/v1/oaa/applications/{id} — full OAA payload for one Application
    • POST /api/v1/oaa/export — bulk export

Why OAA: The OAA format is proven across enterprise deployments (Snowflake, Choice Hotels). SecurityV0 adopts the format for interoperability, not vendor lock-in.

SCIM API (Read-Only)

Exposes identities and groups via SCIM 2.0 protocol:

  • Read-only: All write operations return HTTP 501 Not Implemented
  • Discovery: /ServiceProviderConfig, /Schemas, /ResourceTypes endpoints
  • Filtering: Standard SCIM filter syntax (e.g., filter=userType eq "service_principal")
  • Pagination: Cursor-based pagination per RFC 9865
  • Endpoints:
    • GET /scim/v2/Users — list identities as SCIM Users
    • GET /scim/v2/Groups — list groups/teams as SCIM Groups
    • GET /scim/v2/Schemas — schema discovery

Why SCIM: IGA platforms (SailPoint, Saviynt, ConductorOne) and PAM tools (CyberArk, BeyondTrust) consume SCIM data for identity governance. A read-only SCIM endpoint allows these tools to discover SecurityV0's NHI inventory.

See: 06-scim-oaa-integration.md

8. API Gateway

Responsibility: Authentication, authorization, rate limiting, tenant routing.

  • Auth: OAuth 2.0 for web UI, API keys for programmatic access
  • Tenant scoping: all requests bound to authenticated tenant
  • Rate limiting: per-tenant, per-endpoint
  • No direct database access from consumers — all queries go through Query Service

9. Web UI Layer

Responsibility: Interactive visualization of execution authority graphs, findings dashboards, entity detail views, temporal analysis.

Technology Stack:

  • Frontend Framework: React 19.2.0 + TypeScript + Vite 7.x
  • Graph Visualization: @xyflow/react + ELK.js layout engine (see ADR-011)
  • Styling: Tailwind CSS 4.x
  • Data Fetching: TanStack Query (React Query)
  • Routing: React Router v7

Technology selection, layout algorithm rationale, and the Dagre → ELK.js migration history are documented in ADR-011.

Node Representation:

  • Entity types have distinct colors (identity=blue, workload=teal, role=purple, permission=orange, resource=red)
  • Status overlays (deleted=dashed border, decayed=red border)
  • Finding badges (red dot with count) for security issues
  • Custom React components per node type for rich detail panels

Data Flow: Connector Sync Lifecycle

The detailed execution and operations model for this lifecycle (state machine, retries, telemetry, SLOs, alerts) is specified in 02-processing-pipeline.md.

1. Scheduler (or manual trigger) initiates sync for Connector C, Tenant T
2. Connector C authenticates to external source using Tenant T's stored credentials
3. Connector C extracts raw data (paginated, rate-limited)
4. Connector C transforms raw data to NormalizedGraph
5. Diff Engine loads previous state for Tenant T from MongoDB
6. Diff Engine computes change set (added/removed/modified nodes and edges)
7. Entity documents written/updated in MongoDB
8. Previous versions archived to entity_versions collection
9. Change events appended to events collection
10. Materialized execution paths recomputed for affected identities
11. Connector sync record written to connector_syncs
12. Trigger Evaluator runs against all changed entities
13. New findings written to findings collection
14. Evidence Pack Generator assembles packs for new findings
15. Sealed evidence packs stored in evidence_packs collection

Multi-Tenancy Model

LayerIsolation Strategy
Connector credentialsEncrypted per-tenant vault (Secrets Manager)
Connector executionIsolated container/process per sync per tenant
MongoDBtenant_id field on all documents; compound indexes enforce scoping
APIOAuth/API key scoped to tenant; gateway enforces
Evidence packsTenant-scoped storage; integrity hash includes tenant_id

Scaling consideration: At early scale (< 50 tenants), field-based isolation is sufficient. If tenant count grows significantly, migrate to database-per-tenant.


Security Boundaries

External Source Access

  • Read-only API access for connector ingestion — connectors never modify source systems they read from
  • Platform-issued tickets to external systems (Jira / GitHub / ServiceNow / Linear) initiated by the user as part of a remediation action are a separate outbound capability and do not run through the connector ingestion path; see ADR-019 for the carve-out and the redaction policy applied to outbound bodies
  • Credentials stored encrypted, never logged, never included in evidence packs
  • Connector execution isolated per tenant to prevent credential cross-contamination
  • API calls to sources are metadata-only (no payload/content inspection)

Internal Data Security

  • Evidence packs are sealed with SHA256; integrity verifiable at any time
  • Events collection is append-only; no updates or deletes (except TTL retention)
  • All inter-service communication over TLS
  • Tenant data never crosses tenant boundaries at any layer

Authentication & Authorization

  • API consumers: OAuth 2.0 (web UI) or API keys (programmatic)
  • Service-to-service: mutual TLS or service mesh identity
  • Connector-to-source: per-tenant OAuth 2.0 client credentials or API keys

Deployment Topology

Current Production

Single Hetzner VPS running Docker Compose with TLS:

  • TLS: Managed by Caddy (automatic HTTPS, Let's Encrypt)
  • Reverse proxy: Caddy terminates TLS externally; Nginx handles internal SPA routing on the container network
  • API: Docker-internal only (no host port), accessible only through Caddy
  • MongoDB: Localhost-only (:27017), no internet exposure

Uses docker-compose.deploy.yml for production config (Caddy TLS, locked-down ports). docker-compose.prod.yml is a legacy config (Nginx+Certbot) — not the active deployment. See sv0-platform/docs/deploy/deployment.md for full runbook.

Target (Post-Inetum)

┌─────────────────────────────────────────────────┐
│ Container Orchestration (Kubernetes / ECS) │
│ │
│ ┌──────────────┐ ┌────────────────────────┐ │
│ │ API Gateway │ │ Connector Workers │ │
│ │ (2+ replicas) │ │ (scaled per workload) │ │
│ └──────────────┘ └────────────────────────┘ │
│ │
│ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Query Service │ │ Trigger Evaluator │ │
│ │ (2+ replicas) │ │ (event-driven) │ │
│ └──────────────┘ └────────────────────────┘ │
└─────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────┐
│ MongoDB Atlas (managed) or self-hosted │
│ Secrets Manager │ Object Store (S3/GCS) │
└─────────────────────────────────────────────────┘

Dependencies Between Design Documents

00-overview.md (this doc)
├── 03-database.md (MongoDB schema, graph queries, scaling path)
├── 01-data-model.md (entity types, relationships, examples)
│ └── 04-api-layer.md (query endpoints, structured queries)
├── 02-processing-pipeline.md (pipeline mechanics, observability, SLOs, alerts)
├── 05-connectors.md (interface contract, normalization)
│ ├── 06-scim-oaa-integration.md (SCIM/OAA interop export)
│ └── 08-reference-impl-entra-servicenow.md (concrete connector)
└── 07-ui-reporting.md (depends on API layer)