9.6 KiB
Theta Suite Multi-Site Architecture & Replication Specification
Specification Version: 1.0.0
Status: Draft Architecture Proposal
Target Suite Version: v1.50.0+
Repository: theta-suite
Executive Summary
This specification defines the multi-site replication, fault tolerance, and site isolation architecture for the theta-suite ecosystem (sso-manager-node, openbao, openldap, theta-proxy, jump-host, and theta-agent).
The architecture follows a Symmetric Deployment with Explicit Master Control and Autonomous Site Nodes. Every site runs an identical software stack. At any given time, one site is designated as the Master (Control Plane), while all other sites operate as Autonomous Spoke Nodes.
If a WAN partition or outage disconnects a Spoke site from the Master, no automatic failover is attempted (preventing split-brain data corruption). Instead, the Spoke node remains in Spoke Mode—allowing local user OAuth logins, local SSH jumps, local web application proxying, local secret lookups, and local agent telemetry/controls to continue operating 100% autonomously without WAN dependency.
1. High-Level Architecture Diagram
flowchart TB
subgraph MasterSite["Master Site (HQ / Control Plane)"]
ssoM["sso-manager-node (Master Read/Write)"]
ldapM["OpenLDAP (MMR Master Node 1)"]
baoM["OpenBao (Master Secrets)"]
proxyM["theta-proxy (HQ Web Gateway)"]
jumpM["jump-host (HQ SSH Gateway)"]
agentM["theta-agent (HQ Local Agents)"]
end
subgraph SpokeSiteB["Spoke Site B (Chicago)"]
ssoB["sso-manager-node (Spoke Read-Only Catalog)"]
ldapB["OpenLDAP (MMR Node 2 / Read-Only Replica)"]
baoB["OpenBao (Spoke Local Secret Replica)"]
proxyB["theta-proxy (Site B Local Web Gateway)"]
jumpB["jump-host (Site B SSH Gateway - Filtered)"]
agentB["theta-agent (Site B Local Agents)"]
end
subgraph SpokeSiteC["Spoke Site C (Austin)"]
ssoC["sso-manager-node (Spoke Read-Only Catalog)"]
ldapC["OpenLDAP (MMR Node 3 / Read-Only Replica)"]
baoC["OpenBao (Spoke Local Secret Replica)"]
proxyC["theta-proxy (Site C Local Web Gateway)"]
jumpC["jump-host (Site C SSH Gateway - Filtered)"]
agentC["theta-agent (Site C Local Agents)"]
end
ssoM <==>|"1. SSE/HTTP Catalog Sync"| ssoB
ssoM <==>|"1. SSE/HTTP Catalog Sync"| ssoC
ldapM <==>|"2. OpenLDAP MMR syncrepl"| ldapB
ldapM <==>|"2. OpenLDAP MMR syncrepl"| ldapC
baoM -.->|"3. Secret Version Replicator"| baoB
baoM -.->|"3. Secret Version Replicator"| baoC
2. Core Architectural Guarantees
| Design Aspect | Architectural Choice | System Rationale |
|---|---|---|
| Deployment Symmetry | Identical Stack everywhere | Every site runs the same Docker Compose stack & code base. |
| Catalog Authority | Explicit Master Designation | Single write target for inventory.sqlite catalog mutations. |
| Failover Control | Human god_admin Action Only |
Zero automatic failover; eliminates split-brain risks over WAN. |
| Isolated Autonomy | 100% Operational Locally | OAuth logins, secrets reads, SSH jumps, and agents work offline. |
| Write Usability | Transparent API Proxying | Operators can issue catalog writes from any connected SSO UI. |
| Audit Trails | Non-Canonical Async Log Shipping | Local site logs don't block operations; flushes to Master when online. |
3. Subsystem Implementation & Data Flow
3.1 Directory Catalog (inventory.sqlite)
- Master Site: Holds primary write authority over directory resources (sites, hosts, services, edges, access groups).
- Spoke Sites: Maintain a read-only SQLite catalog replica (
inventory.sqlite). - Realtime Replication: When a resource is modified on Master, Master broadcasts an SSE / WebSocket event (
POST /api/directory-admin/sync/catalog-event). Spoke nodes apply the update locally in real time. - Transparent Write Proxying: When an operator accesses
https://sso.site-b.example.comand performs an edit:- If Site B is connected to Master: Site B proxies
POST /api/directory-admin/*to Master. Master applies the edit and broadcasts the change. - If Site B is isolated from Master: The UI displays a warning banner:
"Master site offline. Directory catalog edits are temporarily paused until WAN connection to Master is restored."
- If Site B is connected to Master: Site B proxies
3.2 User Identity & Credentials (OpenLDAP)
- Replication: OpenLDAP
slapddaemons across all sites run in N-Way Multi-Master Replication (MMR) or Provider/Consumersyncreplmode over LDAPS (ldaps://sso-master:636). - Sub-Millisecond Auth: Linux PAM/SSSD, sudo rules, and user SSH public keys hit
ldaps://localhost:636at each site. - WAN Outage Impact: Zero. Local servers authenticate users against local OpenLDAP replicas with zero latency.
3.3 OAuth 2.0 / OIDC Authentication
- Local Issuer Endpoint: Every site runs a local OIDC issuer (
https://sso.site-b.example.com). - Isolated Login Flow:
- User accesses
https://app.site-b.example.com. - Spoke Proxy redirects to
https://sso.site-b.example.com/oauth/authorize. - Spoke SSO authenticates the user against the local OpenLDAP replica.
- Spoke SSO issues an OIDC JWT signed by the replicated site private key.
- Spoke Proxy verifies the JWT against Spoke SSO JWKS (
/.well-known/jwks.json) and grants access.
- User accesses
- WAN Outage Impact: Zero. Full login and access token issuance continue working during WAN isolation.
3.4 Reverse Proxy (theta-proxy)
- Site-Local Scope: Each site's
theta-proxymanages its own domain routes, upstream backends, and TLS certificates (secret/proxy/confin local OpenBao, ACME / Let's Encrypt certificates). - No Replication Required: Proxy routes and TLS certs are independent per site. They are not stored in global SSO catalog tables and are never locked during master outages.
3.5 SSH Jump Host (jump-host)
- Site-Filtered Target Menus: Each
jump-hostcontainer is passed its local site identity (SITE_SLUG=site-b-chicago). - Target Filter Query:
SELECT * FROM resources WHERE (kind = 'host' OR kind = 'service') AND (site_slug = 'site-b-chicago' OR parent_site_id = 'site-b-id'); - Isolation Resilience: When a user SSHs to
jump.site-b.example.com:2222, Jump Host reads the local catalog copy and local OpenLDAP replica. Users reach Site B target servers with zero WAN dependency.
3.6 Theta Agent WebSocket Hubs (theta-agent)
- Site-Local WS Hub: Machines at Site B connect their
theta-agentdaemon to Site B's local SSO node (wss://sso.site-b.example.com/api/agent/ws). - Local Telemetry & Desktop Controls: Real-time memory, CPU, disk partitions, logged-in users, and desktop controls (lock session, display off, logout, reboot) operate 100% locally at Site B.
- HQ Aggregation: When WAN is connected, Spoke SSO nodes stream telemetry summaries to Master SSO for global dashboard viewing.
3.7 Non-Canonical Audit & Activity Logging
- Local Site Storage: OAuth logins, SSH session events, proxy access logs, and agent execution events are written to local site log buffers (
inventory.sqliteaudit table or local log files). - Asynchronous Shipping: A background log worker flushes log batches to Master via
POST /api/directory-admin/audit/ingestwhen WAN is connected. - Zero Catalog Side Effects: Audit log events never mutate resource definitions or block catalog transactions.
4. Human god_admin Master Re-assignment Flow
Automatic failover across WAN is explicitly disabled to prevent split-brain. Master promotion requires a human god_admin user:
sequenceDiagram
autonumber
actor Admin as god_admin Operator
participant Spoke as Site B SSO Node
participant Master as Site A Master Node (Offline)
Note over Spoke: Master site A goes offline (WAN outage)
Spoke->>Spoke: Retain SPOKE Mode (Catalog Read-Only)
Note over Spoke: Local OAuth, Secrets & Agents stay 100% Active
Admin->>Spoke: Access UI / CLI & trigger "Promote to Master"
Spoke-->>Admin: Prompt Confirmation & Split-Brain Warning
Admin->>Spoke: Confirm Promotion
Spoke->>Spoke: Set ROLE = MASTER, isMaster = true
Spoke->>Spoke: Enable Catalog Write Engine & OpenBao Master Sync
Spoke-->>Admin: Site B is now active Master
5. Site Configuration Schema (/config/sso-secrets.js)
module.exports = {
stack: {
siteName: 'site-b-chicago',
siteSlug: 'site-b-chicago',
role: 'spoke', // 'master' or 'spoke'
masterUrl: 'https://sso.site-a.example.com',
localUrl: 'https://sso.site-b.example.com',
ldapsHost: 'sso-manager',
},
replication: {
syncIntervalMs: 5000,
catalogSyncPath: '/api/directory-admin/sync/catalog',
auditIngestPath: '/api/directory-admin/audit/ingest',
}
};
6. Implementation Phasing Plan
- Phase 1 (v1.50.0): Add
site.roleconfiguration, catalog read-only enforcement on Spokes, transparent write proxying, andSITE_SLUGfiltering forjump-host. - Phase 2 (v1.51.0): Implement local OIDC JWT issuance on Spokes with JWKS cross-site validation and background secret version mirror worker.
- Phase 3 (v1.52.0): Add Spoke-to-Master non-canonical audit log shipping worker and UI
god_adminMaster promotion workflow.
Document generated and committed to codebase under docs/MULTI_SITE_SPEC.md.