Stella Ops — High‑Level Architecture

This document offers a birds‑eye view of how the major components interact, why the system leans monolith‑plus‑plug‑ins, and where extension points live.

For a timeline of when features arrive, see the public
road‑map — no version details are repeated here.


0 · Guiding principles

PrincipleRationale
SBOM‑firstScan existing CycloneDX/SPDX if present; fall back to layer unpack.
Δ‑processingRe‑analyse only changed layers; reduces P95 warm path to < 5 s.
All‑managed codeEntire stack is 100 % managed (.NET / TypeScript); no unsafe blocks or native extensions — eases review and reproducible builds.
Restart‑time plug‑insAvoids the attack surface of runtime DLL injection; still allows custom scanners & exporters.
Sovereign‑by‑designNo mandatory outbound traffic; Offline Kit distributes feeds.

1 · Module graph

graph TD
    A(API Gateway)
    B1(Scanner Core
.NET latest LTS) B2(FeedMerge service) B3(Policy Engine OPA) C1(Redis 7) C2(MongoDB 7) D(UI SPA
Angular latest version) A -->|gRPC| B1 B1 -->|async| B2 B1 -->|OPA| B3 B1 --> C1 B1 --> C2 A -->|REST/WS| D

2 · Key components

ComponentLanguage / techResponsibility
API GatewayASP.NET Minimal APIAuth (JWT), quotas, request routing
Scanner CoreC# 12, PollyLayer diffing, SBOM generation, vuln correlation
FeedMergeC# source‑gen workersConsolidate NVD + regional CVE feeds into one SQLite
Policy EngineOPA (Rego)admission decisions, custom org rules
Redis 7Key‑DB compatibleLRU cache, quota counters
MongoDB 7WiredTigerSBOM & findings storage
Angular 20 UIRxJS, TailwindDashboard, reports, admin UX

3 · Plug‑in system

  • Discovered once at start‑up from /opt/stella/plugins/**.

  • Runs under Linux user stella‑plugin (UID 1001).

  • Extension points:

    • ISbomMutator
    • IVulnerabilityProvider
    • IResultSink
    • Policy files (*.rego)
  • Each DLL is SHA‑256 hashed; digest embedded in the run report for provenance.

Hot‑plugging is deferred until after v 1.0 for security review.


4 · Data & control flow

  1. Client calls /api/scan with image reference.

  2. Gateway enforces quota, forwards to Scanner Core via gRPC.

  3. Core:

    • Queries Redis for cached SBOM.
    • If miss → pulls layers, generates SBOM.
    • Executes plug‑ins (mutators, additional scanners).
  4. Policy Engine evaluates scanResult document.

  5. Findings stored in MongoDB; WebSocket event notifies UI.

  6. ResultSink plug‑ins export to Slack, Splunk, JSON file, etc.


5 · Security hardening

SurfaceMitigation
Container runtimeDistroless base, non‑root UID, seccomp + AppArmor
Plug‑in sandboxSeparate UID, SELinux profile, cgroup 1 CPU / 256 MiB
Supply chainCosign signatures, in‑toto SLSA Level 3 (target)
SecretsDocker secrets or K8s Secret mounts; never hard‑coded
Quota abuseRedis rate‑limit gates (see 30_QUOTA_ENFORCEMENT_FLOW1.md)

6 · Build & release pipeline (TL;DR)

  • Git commits trigger CI → unit / integration / E2E tests.

  • Successful merge to main:

    • Build .NET {{ dotnet }} trimmed self‑contained binary.
    • docker build --sbom=spdx-json.
    • Sign image and tarball with Cosign.
    • Attach SBOM + provenance; push to registry and download portal.

7 · Future extraction path

Although the default deployment is a single container, each sub‑service can be extracted:

  • FeedMerge → standalone cron pod.
  • Policy Engine → side‑car (OPA) with gRPC contract.
  • ResultSink → queue worker (RabbitMQ or Azure Service Bus).

Interfaces are stable as of v0.2 β; extraction requires a recompilation only, not a fork of the core.


Last updated {{ “now” | date: “%Y‑%m‑%d” }} – constants auto‑injected.