Architecture Overview (High-Level)
This document is the current architecture of Stella Ops Suite: where it sits, what runs, what talks to what, where the trust boundaries are, and how it behaves when something fails.
Audience: operators, architects, and integrators evaluating or deploying the platform. For the index into per-subsystem detail — module dossiers, API contracts, schemas — see ARCHITECTURE_REFERENCE.md. For a one-line-per-component map of the codebase, see Platform component map.
What Stella Ops Suite is
Stella Ops Suite is a centralized, auditable release control plane for non-Kubernetes container estates.
It sits between your CI and your runtime targets, governs promotion across environments, enforces security and policy gates, and produces verifiable evidence for every release decision.
CI Build → Registry → Stella (Scan + Release + Promote + Gate + Deploy) → Targets → Evidence
Build → Scan → Create Release → Request Promotion → Gate Evaluation → Deploy → Evidence
↑ ↓
└── Re-evaluate on CVE Updates ┘
Design principles
- Digest-first releases: a release is an immutable set of OCI digests, never mutable tags. Tags are mutable; digests give a release an identity that survives audit.
- Deterministic replay: the same inputs yield the same outputs — stable ordering, canonical hashing, UTC timestamps.
- Evidence-linked decisions: every release decision links to concrete evidence artifacts (scan verdicts, approvals, policy evaluations), packaged so the decision can be replayed later.
- Pluggable everything: integrations are plugins; the core orchestration engine is stable. Extensibility does not require core code changes.
- Offline-first: all core operations work in air-gapped environments.
- Agentless execution toward targets: deployment reaches Docker, Compose, SSH and WinRM targets from the Stella side. Nothing is installed on the target hosts. “Agent” in this codebase means the executor service that runs inside your own Stella installation (
StellaOps.Agent.Host, which registers the SSH and WinRM capabilities) — not software placed on the machines being deployed to. - Compiled C# steps plus shell hooks: C# for complex orchestration; shell hooks for the simple cases, executed by the deployment agent under a timeout. The hook runner starts
sh -c(orcmd.exe /con Windows) as a child process with the agent’s own privileges — treat hook content as trusted input and keep it under the same review as deployment code. - No feature gating: all plans include all features; limits are environments + new digests/day.
Deployment model and trust boundary
Stella Ops is self-hosted. Every service, the data plane it writes to, and the signing material it uses run inside the operator’s own boundary; there is no vendor-hosted control plane.
Inside that boundary Stella Ops supports multiple logical tenants — environments, business units, or logical scopes that share the same operator, security team, and incident-response authority. The current architecture does not support unrelated, mutually adversarial tenants on one shared deployment. See ADR-005; token-selection mechanics inside this posture are covered by ADR-002.
Trust zones, outside in:
| Zone | Contents | Reachable from |
|---|---|---|
| Client | stella CLI, Angular console, CI pipelines, deployment agents | Operators and CI, over TLS |
| Ingress | Router (StellaOps.Gateway.WebService) — TLS termination, token validation, tenant resolution, rate limiting | Clients only |
| Private service network | Scanner, Concelier, Policy Engine, Release Orchestrator, Attestor, Authority and the rest | The gateway and each other, least privilege with explicit allowlists |
| Stateful infrastructure | PostgreSQL, Valkey, RustFS / S3-compatible object storage | Services only; not directly internet-exposed |
Externally reachable services enforce token validation (short-lived, tenant-scoped), sender constraints where configured (DPoP / mTLS), scope-based authorization, and tenant filtering on data access. The deployment bundles under devops/ are the authoritative source for the concrete network layout of a given profile.
Detail: Security boundaries · Platform topology · Data isolation model · Port registry · Scopes and roles
System map
Service tiers
| Tier | Services | Key responsibilities |
|---|---|---|
| Edge / Identity | StellaOps.Authority | Issues short-lived tokens (DPoP + mTLS), exposes OIDC flows, rotates JWKS |
| Release Control | StellaOps.ReleaseOrchestrator.* (the release-orchestrator service) | Release bundles, promotion workflows, gate evaluation |
| Integration Hub | StellaOps.Integrations.WebService + StellaOps.Integrations.Plugin.* (the integrations-web service) | SCM / CI / registry / Vault / Consul connectors as signed plugins, loaded by the default stack |
| Scan & Attest | StellaOps.Scanner, StellaOps.Attestor (includes Signer) | Accept SBOMs/images, produce DSSE bundles, transparency logging |
| Evidence Graph | StellaOps.Concelier, StellaOps.Excititor, StellaOps.Policy.Engine | Advisories/VEX, linksets, lattice policy |
| Deployment | StellaOps.ReleaseOrchestrator.Deployment + StellaOps.Agent.* (the agent-core service) | Deployment execution — Docker/Compose/SSH/WinRM live-verified; ECS and Nomad ship as built-in agent capabilities |
| Experience | StellaOps.Web, StellaOps.Cli, StellaOps.Notify, StellaOps.ExportCenter | Operator UX, automation, notifications |
| Data Plane | PostgreSQL, Valkey, RustFS / object storage | Canonical store, queues, artifact storage |
Ownership that is easy to get wrong:
- Ingress and routing — Router owns both the HTTP ingress gateway (
StellaOps.Gateway.WebService) and the internal binary protocol transport. - Promotion policy gates — Policy Engine owns PASS/FAIL decision semantics; Concelier remains ingestion and linkset only.
- Environment topology and promotion lanes — owned by the Release Orchestrator, not Cartographer.
The full inventory, including which historical component names now run inside a parent service, is the Module matrix and docs/modules/.
Capability areas
Capabilities are grouped into themes — functional labels used for orientation. The project layout under src/ is mapped separately, in the Platform component map.
Analysis and evidence
| Theme | Purpose | Components |
|---|---|---|
| INGEST | Advisory ingestion and unified search retrieval | Concelier, Advisory-AI, Unified Search |
| VEXOPS | VEX document handling | Excititor, VEX Lens, VEX Hub |
| REASON | Policy and decisioning | Policy Engine, OPA Runtime |
| SCANENG | Scanning and SBOM | Scanner, SBOM Service, Reachability |
| EVIDENCE | Evidence and attestation | Evidence Locker, Attestor, Export Center |
| RUNTIME | Runtime signals | Signals, Graph, Zastava |
| JOBCTRL | Job orchestration | JobEngine (includes Scheduler, TaskRunner, PacksRegistry) |
| OBSERVE | Observability | Notifier, Telemetry |
| REPLAY | Deterministic replay | Replay Engine |
| DEVEXP | Developer experience | CLI, Web UI, Tools (includes SDK) |
Release orchestration
| Theme | Purpose | Status (verified against src/, 2026-07-28) |
|---|---|---|
| INTHUB | Integration hub | Shipped — StellaOps.Integrations.WebService plus signed connector plugins (Gitea, GitHub App, GitLab, Jenkins, Harbor, Nexus, Docker Registry, Vault, Consul) loaded by the default stack |
| ENVMGR | Environment management | Shipped — persisted environment/target CRUD, health, freeze windows, and agent assignment |
| RELMAN | Release management | Shipped — release truth create/ready/update, component version registry, registry-driven version sync |
| WORKFL | Workflow engine | Partial — workflow surfaces are live under Release Orchestrator (/api/v1/workflows); a general-purpose standalone workflow engine is not part of the default stack |
| PROMOT | Promotion and approval | Shipped — promote and deploy fail closed on release truth, approval quorum, and persisted gate results; DB-backed approval policies with a UI editor. Promotion runs via /api/v1/release-orchestrator/releases/{id}/promote |
| DEPLOY | Deployment execution | Shipped — target executor, generated artifacts, and rollback; Docker/Compose/SSH/WinRM targets live-verified |
| AGENTS | Deployment agents | Shipped — built-in docker, compose, ssh, winrm, ecs, and nomad capabilities, plus Ansible playbook execution |
| PROGDL | Progressive delivery | Partial — all-at-once, rolling, canary, and A/B strategies are test- and live-VM-proven; real router / load-balancer traffic data-plane integration is not claimed |
| RELEVI | Release evidence | Shipped — signed deployment decision records, evidence threads, version stickers for drift detection |
| PLUGIN | Plugin infrastructure | Shipped — registry, host/loader, sandbox (including a gRPC plugin bridge), SDK, and manifest + signature verification |
Data plane and required infrastructure
Required
- PostgreSQL — canonical persistent store. Each service owns a schema, which is what makes the ownership boundary and the tenant-isolation strategy enforceable rather than conventional.
- Valkey — Redis-compatible cache and coordination substrate: DPoP nonces, streams and events, worker queues, tenant-prefixed caching, rate-limit counters.
- RustFS (or an equivalent S3-compatible store) — object storage for artifacts, bundles, and evidence. Evidence stores are append-only, which is what keeps a verdict replayable.
Optional, and deliberately never load-bearing for core flows
- NATS JetStream — alternative messaging transport in some deployments; Valkey is the default.
- Transparency log services — a Rekor mirror, and CA services, when transparency is enabled.
Detail: Infrastructure dependencies · Schema mapping · Data schemas
End-to-end flows
Vulnerability scanning
- Evidence enters via Concelier and Excititor connectors (Aggregation-Only Contract).
- SBOM arrives from CLI/CI; Scanner deduplicates layers and enqueues work.
- Analyzer bundle runs inside the Worker and stores evidence in content-addressed caches.
- Policy Engine merges advisories, VEX, and inventory/usage facts; emits explain traces and stable dispositions.
- Signer + Attestor wrap outputs into DSSE bundles and, optionally, anchor them in a Rekor mirror.
- Console / CLI / Export surface findings and package verifiable evidence; Notify emits digests and incidents.
Release orchestration
- CI pushes an image to the registry by digest; a webhook triggers Stella.
- Stella scans the new digest and stores the verdict.
- Release created, bundling component digests with a semantic version.
- Promotion requested to move the release from Dev → Stage → Prod. The promote and deploy paths fail closed when release truth, approvals, or gate results are missing.
- Gate evaluation checks the security verdict, approval count, freeze windows, and custom policies.
- Decision record produced with evidence references, and signed.
- Deployment executed via an agent to the target (Docker, Compose, SSH/WinRM; ECS and Nomad as built-in agent capabilities).
- Version sticker written to the target for drift detection.
- Evidence packet sealed and stored.
Detail, including the per-hop sequence and where each hop persists state: Request and data flows · Data flows · End-to-end workflow flows
Signing, credentials, and anchored trust
- Identity — Authority issues short-lived, tenant-scoped tokens and rotates JWKS. Sender constraints (DPoP nonces, mTLS) are enforced where configured.
- Signing — Signer produces DSSE signatures; Attestor assembles evidence bundles and can anchor them in a Rekor transparency log. Under air-gap the mirror is local, and Attestor can cache transparency proofs so verification still works.
- Key location — signing and verification keys are not baked into images and are not carried in the repository. A service reads its key at runtime from an environment variable or a mounted file, and fails closed when one is absent.
- Trust roots — issuer and KMS bindings are held in the Issuer Directory and distributed with the Offline Kit for air-gapped installs.
- Verification by the reader — evidence packets are exportable for external audit, and every release decision can be replayed with frozen inputs.
Detail: Security hardening guide · Key rotation runbook · Verification key rotation · Attestor architecture · Signer architecture
Failure behaviour and recovery
- Gates fail closed. Promotion and deployment stop when release truth, approvals, or gate results are missing, rather than proceeding on an assumption.
- Failure domains follow the service boundary. Each service owns its own schema and its own queues, so a stalled worker or an unavailable connector degrades one capability rather than the control plane. Symptom-to-action procedures per service live under
docs/operations/runbooks/. - Backup and restore cover the PostgreSQL state volume, the object store, and Valkey, using shipped tooling: Backup and restore operations. The restore path is exercised as a drill — wipe the state, restore the backup, confirm no loss — in the PostgreSQL backup + restore drill.
- Upgrade and rollback run through Docker Compose or the Offline Kit, with signed release manifests, image-digest verification, service health checks, and a release evidence pack: Deployment upgrade and rollback runbook. Database migrations are forward-only (ADR-004), so a rollback is a deployment operation, not a schema reversal.
- Trust-infrastructure disaster recovery — Rekor outage, key compromise, or a TUF repository failure: Disaster recovery guide.
Connected and air-gapped operation
The same deployment runs in three connectivity postures, and policy must stay compatible across all three:
| Mode | Egress | Typical use |
|---|---|---|
| Connected | Full egress to configured upstreams | Staging and connected estates |
| Constrained | Limited egress to allowlisted registries and NTP | Regulated networks |
| Sealed | Deny-all egress; only preloaded mirror and bootstrap bundles | Air-gapped estates |
In sealed mode the Offline Kit carries vulnerability feeds, container images, signatures, and verification material, so the workflow is identical to the connected one. Authority and token verification remain local. Capabilities that genuinely differ between modes are enumerated rather than glossed over: see the degradation matrix.
Detail: Offline Kit · Air-gap overview · Air-gap operations runbook
Extension points
Integrations are plugins, and the evidence chain does not change when you add one.
- Scanner analyzers (restart-time plug-ins) for ecosystem-specific parsing and facts extraction.
- Concelier connectors for new advisory sources, preserving aggregation-only guardrails.
- Policy packs for organization-specific gating, waivers, and justifications.
- AI code guard evidence for AI-assisted code changes (Scanner evidence + Policy overrides).
- Export profiles for output formats and offline bundle shapes.
Plugins contribute through three surfaces:
- Manifest — a static declaration of what the plugin provides (integrations, steps, agents, gates), signed and signature-verified before load.
- Sandboxed runtime — plugins execute in a process sandbox behind a gRPC plugin bridge.
- Execution contract —
IExecutionPlugincapabilities registered through the agent’s execution plugin catalog for workflow and deployment steps.
Plugin types: integration connectors (SCM — Gitea, GitHub App, GitLab; CI — Jenkins; registry — Harbor, Nexus, Docker Registry; secrets — Vault, Consul), step providers, agent types for new deployment targets, and gate providers such as the reachability promotion gate. A traffic/router plugin interface is defined for progressive delivery; a real load-balancer data-plane integration is not claimed.
Detail: Plugin SDK guide
Where the detailed architecture lives
| You need | Go to |
|---|---|
| The index into every subsystem | ARCHITECTURE_REFERENCE.md |
| Layer-by-layer service and infrastructure map | Platform topology |
| Trust zones, authn/authz, network segmentation, CORS, auditability | Security boundaries |
| Per-hop request and data flows | Request and data flows |
| What infrastructure is required, and what is optional | Infrastructure dependencies |
| Schema ownership and tenant isolation | Data isolation model |
Every component under src/, one line each | Platform component map |
| Full module inventory and consolidation history | Module matrix |
| Per-module APIs, storage, lifecycle, failure modes | docs/modules/ |
| API and CLI contracts | API_CLI_REFERENCE.md |
| Air-gap operation | OFFLINE_KIT.md |
