Rewrite architecture docs and add Vexer connector template
This commit is contained in:
@@ -1,388 +1,430 @@
|
||||
# 7 · High‑Level Architecture — **Stella Ops**
|
||||
Below is the **revised, consolidated** `high_level_architecture.md`.
|
||||
It **absorbs** all content from `components.md` so you have a single, authoritative file. No separate components doc is required.
|
||||
|
||||
---
|
||||
|
||||
## 0 Purpose & Scope
|
||||
# High‑Level Architecture — **Stella Ops** (Consolidated • 2025Q4)
|
||||
|
||||
Give contributors, DevOps engineers and auditors a **complete yet readable map** of the Core:
|
||||
|
||||
* Major runtime components and message paths.
|
||||
* Where plug‑ins, CLI helpers and runtime agents attach.
|
||||
* Technology choices that enable the sub‑5 second SBOM goal.
|
||||
* Typical operational scenarios (pipeline scan, mute, nightly re‑scan, etc.).
|
||||
|
||||
Anything enterprise‑only (signed PDF, custom/regulated TLS, LDAP, enforcement) **must arrive as a plug‑in**; the Core never hard‑codes those concerns.
|
||||
---
|
||||
## 1 Component Overview
|
||||
|
||||
| # | Component | Responsibility |
|
||||
|---|-----------|---------------|
|
||||
| 1 | **API Gateway** | REST endpoints (`/scan`, `/quota`, **`/token/offline`**); token auth; quota enforcement |
|
||||
| 2 | **Scan Service** | SBOM parsing, Delta‑SBOM cache, vulnerability lookup |
|
||||
| 3 | **Policy Engine** | YAML / (optional) Rego rule evaluation; verdict assembly |
|
||||
| 4 | **Quota Service** | Per‑token counters; **333 scans/day**; waits & HTTP 429 |
|
||||
| 5 | **Client‑JWT Issuer** | Issues 30‑day offline tokens; bundles them into OUK |
|
||||
| 5 | **Registry** | Anonymous internal Docker registry for agents, SBOM uploads |
|
||||
| 6 | **Web UI** | React/Blazor SPA; dashboards, policy editor, quota banner |
|
||||
| 7 | **Data Stores** | **Redis** (cache, quota) & **MongoDB** (SBOMs, findings, audit) |
|
||||
| 8 | **Plugin Host** | Hot‑load .NET DLLs; isolates community plug‑ins |
|
||||
| 9 | **Agents** | `sbom‑builder`, `Stella CLI` scanner CLI, future `StellaOpsAttestor` |
|
||||
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph "External Actors"
|
||||
DEV["Developer / DevSecOps / Manager"]
|
||||
CI["CI/CD Pipeline (e.g., Stella CLI)"]
|
||||
K8S["Kubernetes Cluster (e.g., Zastava Agent)"]
|
||||
end
|
||||
|
||||
subgraph "Stella Ops Runtime"
|
||||
subgraph "Core Services"
|
||||
CORE["Stella Core<br>(REST + gRPC APIs, Orchestration)"]
|
||||
REDIS[("Redis<br>(Cache, Queues, Trivy DB Mirror)")]
|
||||
MONGO[("MongoDB<br>(Optional: Long-term Storage)")]
|
||||
POL["Mute Policies<br>(OPA & YAML Evaluator)"]
|
||||
REG["StellaOps Registry<br>(Docker Registry v2)"]
|
||||
ATT["StellaOps Attestor<br>(SLSA + Rekor)"]
|
||||
end
|
||||
|
||||
subgraph "Agents & Builders"
|
||||
SB["SBOM Builder<br>(Go Binary: Extracts Layers, Generates SBOMs)"]
|
||||
SA["Stella CLI<br>(Pipeline Helper: Invokes Builder, Triggers Scans)"]
|
||||
ZA["Zastava Agent<br>(K8s Webhook: Enforces Policies, Inventories Containers)"]
|
||||
end
|
||||
|
||||
subgraph "Scanners & UI"
|
||||
TRIVY["Trivy Scanner<br>(Plugin Container: Vulnerability Scanning)"]
|
||||
UI["Web UI<br>(Vue3 + Tailwind: Dashboards, Policy Editor)"]
|
||||
CLI["Stella CLI<br>(CLI Helper: Triggers Scans, Mutes)"]
|
||||
end
|
||||
end
|
||||
|
||||
DEV -->|Browses Findings, Mutes CVEs| UI
|
||||
DEV -->|Triggers Scans| CLI
|
||||
CI -->|Generates SBOM, Calls /scan| SA
|
||||
K8S -->|Inventories Containers, Enforces Gates| ZA
|
||||
|
||||
UI -- "REST" --> CORE
|
||||
CLI -- "REST/gRPC" --> CORE
|
||||
SA -->|Scan Requests| CORE
|
||||
SB -->|Uploads SBOMs| CORE
|
||||
ZA -->|Policy Gates| CORE
|
||||
|
||||
CORE -- "Queues, Caches" --> REDIS
|
||||
CORE -- "Persists Data" --> MONGO
|
||||
CORE -->|Evaluates Policies| POL
|
||||
CORE -->|Attests Provenance| ATT
|
||||
CORE -->|Scans Vulnerabilities| TRIVY
|
||||
|
||||
SB -- "Pulls Images" --> REG
|
||||
SA -- "Pulls Images" --> REG
|
||||
ZA -- "Pulls Images" --> REG
|
||||
|
||||
style DEV fill:#f9f,stroke:#333
|
||||
style CI fill:#f9f,stroke:#333
|
||||
style K8S fill:#f9f,stroke:#333
|
||||
style CORE fill:#ddf,stroke:#333
|
||||
style REDIS fill:#fdd,stroke:#333
|
||||
style MONGO fill:#fdd,stroke:#333
|
||||
style POL fill:#dfd,stroke:#333
|
||||
style REG fill:#dfd,stroke:#333
|
||||
style ATT fill:#dfd,stroke:#333
|
||||
style SB fill:#fdf,stroke:#333
|
||||
style SA fill:#fdf,stroke:#333
|
||||
style ZA fill:#fdf,stroke:#333
|
||||
style TRIVY fill:#ffd,stroke:#333
|
||||
style UI fill:#ffd,stroke:#333
|
||||
style CLI fill:#ffd,stroke:#333
|
||||
```
|
||||
|
||||
* **Developer / DevSecOps / Manager** – browses findings, mutes CVEs, triggers scans.
|
||||
* **Stella CLI** – generates SBOMs and calls `/scan` during CI.
|
||||
* **Zastava Agent** – inventories live containers; Core ships it in *passive* mode only (no kill).
|
||||
|
||||
### 1.1 Client‑JWT Lifecycle (offline aware)
|
||||
|
||||
1. **Online instance** – user signs in → `/connect/token` issues JWT valid 12 h.
|
||||
2. **Offline instance** – JWT with `exp ≈ 30 days` ships in OUK; backend
|
||||
**re‑signs** and stores it during import.
|
||||
3. Tokens embed a `tier` claim (“Free”) and `maxScansPerDay: 333`.
|
||||
4. On expiry the UI surfaces a red toast **7 days** in advance.
|
||||
> **Purpose.** A complete, implementation‑ready map of Stella Ops: product vision, all runtime components, trust boundaries, tokens/licensing, control/data flows, storage, APIs, security, scale, DevOps, and verification logic.
|
||||
> **Scope.** This file **replaces** the separate `components.md`; all component details now live here.
|
||||
|
||||
---
|
||||
|
||||
## 2 · Component Responsibilities (runtime view)
|
||||
## 0) Product vision & principles
|
||||
|
||||
| Component | Core Responsibility | Implementation Highlights |
|
||||
| -------------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| **Stella Core** | Orchestrates scans, persists SBOM blobs, serves REST/gRPC APIs, fans out jobs to scanners & policy engine. | .NET {{ dotnet }}, CQRS, Redis Streams; pluggable runner interfaces. |
|
||||
| **SBOM Builder** | Extracts image layers, queries Core for *missing* layers, generates SBOMs (multi‑format), uploads blobs. | Go binary; wraps Trivy & Syft libs. |
|
||||
| **Stella CLI** | Pipeline‑side helper; invokes Builder, triggers scan, streams progress back to CI/CD. | Static musl build. |
|
||||
| **Zastava Agent** | K8s admission webhook enforcing policy verdicts before Pod creation. | Rust for sub‑10 ms latencies. |
|
||||
| **UI** | Angular 17 SPA for dashboards, settings, policy editor. | Tailwind CSS; Webpack module federation (future). |
|
||||
| **Redis** | Cache, queue, Trivy‑DB mirror, layer diffing. | Single instance or Sentinel. |
|
||||
| **MongoDB** (opt.) | Long‑term SBOM & policy audit storage (> 180 days). | Optional; enabled via flag. |
|
||||
| **StellaOps.Registry** | Anonymous read‑only Docker v2 registry with optional Cosign verification. | `registry :2` behind nginx reverse proxy. |
|
||||
| **StellaOps.MutePolicies** | YAML/Rego evaluator, policy version store, `/policy/*` API. | Embeds OPA‑WASM; falls back to `opa exec`. |
|
||||
| **StellaOpsAttestor** | Generate SLSA provenance & Rekor signatures; verify on demand. | Side‑car container; DSSE + Rekor CLI. |
|
||||
**Vision.** Stella Ops is a **deterministic SBOM + VEX platform** for CI/CD and runtime, tuned for **speed** (per‑layer deltas), **quiet output** (usage‑scoped views), and **verifiability** (DSSE + Rekor v2). It is **self‑hostable**, **air‑gap capable**, and **commercially enforceable**: only licensed installations can produce **Stella Ops‑verified** attestations.
|
||||
|
||||
All cross‑component calls use dependency‑injected interfaces—no
|
||||
intra‑component reach‑ins.
|
||||
**Operating principles.**
|
||||
|
||||
* **Scanner‑owned SBOMs.** We generate our own BOMs; we do not warehouse third‑party SBOM content (we can **link** to attested SBOMs).
|
||||
* **Deterministic evidence.** Facts come from package DBs, installed metadata, linkers, and verified attestations; no fuzzy guessing in the core.
|
||||
* **Per‑layer caching.** Cache fragments by **layer digest** and compose image SBOMs via **CycloneDX BOM‑Link** / **SPDX ExternalRef**.
|
||||
* **Inventory vs Usage.** Always record the full **inventory** of what exists; separately present **usage** (entrypoint closure + loaded libs).
|
||||
* **Backend decides.** PASS/FAIL is produced by **Policy** + **VEX** + **Advisories**. The scanner reports facts.
|
||||
* **Attest or it didn’t happen.** Every export is signed as **in‑toto/DSSE** and logged in **Rekor v2**.
|
||||
* **Sovereign‑ready.** Cloud is used only for licensing and optional endorsement; everything else is first‑party and self‑hostable.
|
||||
|
||||
---
|
||||
|
||||
## 3 · Principal Backend Modules & Plug‑in Hooks
|
||||
## 1) Service topology & trust boundaries
|
||||
|
||||
| Namespace | Responsibility | Built‑in Tech / Default | Plug‑in Contract |
|
||||
| --------------- | -------------------------------------------------- | ----------------------- | ------------------------------------------------- |
|
||||
| `configuration` | Parse env/JSON, health‑check endpoint | .NET {{ dotnet }} Options | `IConfigValidator` |
|
||||
| `identity` | Embedded OAuth2/OIDC (OpenIddict 6) | MIT OpenIddict | `IIdentityProvider` for LDAP/SAML/JWT gateway |
|
||||
| `pluginloader` | Discover DLLs, SemVer gate, optional Cosign verify | Reflection + Cosign | `IPluginLifecycleHook` for telemetry |
|
||||
| `scanning` | SBOM‑ & image‑flow orchestration; runner pool | Trivy CLI (default) | `IScannerRunner` – e.g., Grype, Copacetic, Clair |
|
||||
| `feedser` (vulnerability ingest/merge/export service) | Nightly NVD merge & feed enrichment | Hangfire job | drop-in `*.Schedule.dll` for OSV, GHSA, NVD 2.0, CNNVD, CNVD, ENISA, JVN and BDU feeds |
|
||||
| `tls` | TLS provider abstraction | OpenSSL | `ITlsProvider` for custom suites (incl. **SM2**, where law or security requires it) |
|
||||
| `reporting` | Render HTML/PDF reports | RazorLight | `IReportRenderer` |
|
||||
| `ui` | Angular SPA & i18n | Angular {{ angular }} | new locales via `/locales/{lang}.json` |
|
||||
| `scheduling` | Cron + retries | Hangfire | any recurrent job via `*.Schedule.dll` |
|
||||
### 1.1 Runtime inventory (first‑party)
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class configuration
|
||||
class identity
|
||||
class pluginloader
|
||||
class scanning
|
||||
class feedser
|
||||
class tls
|
||||
class reporting
|
||||
class ui
|
||||
class scheduling
|
||||
| Service / Tool | Container image | Core role | Scale pattern |
|
||||
| ------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| **Scanner.WebService** | `stellaops/scanner-web` | Control plane for scans; catalog; SBOM composition (inventory & usage); diff; exports. | Stateless; N replicas behind LB. |
|
||||
| **Scanner.Worker** | `stellaops/scanner-worker` | Runs analyzers (OS, Lang: Java/Node/Python/Go/.NET/Rust, Native ELF/PE/Mach‑O, EntryTrace); emits per‑layer SBOMs and composes image SBOMs. | Horizontal; queue‑driven; sharded by layer digest. |
|
||||
| **Scanner.Sbomer.BuildXPlugin** | `stellaops/sbom-indexer` | BuildKit **generator** for build‑time SBOMs as OCI **referrers**. | CI‑side; ephemeral. |
|
||||
| **Scanner.Sbomer.DockerImage** | `stellaops/scanner-cli` | CLI‑orchestrated scanner container for post‑build scans. | Local/CI; ephemeral. |
|
||||
| **Feedser.WebService** | `stellaops/feedser-web` | Vulnerability ingest/normalize/merge/export (JSON + Trivy DB). | HA via Mongo locks. |
|
||||
| **Vexer.WebService** | `stellaops/vexer-web` | VEX ingest/normalize/consensus; conflict retention; exports. | HA via Mongo locks. |
|
||||
| **Policy Engine** | (in `scanner-web`) | YAML DSL evaluator (waivers, vendor preferences, KEV/EPSS, license, usage‑gating); produces **policy digest**. | In‑process; cache per digest. |
|
||||
| **Signer** | `stellaops/signer` | **Hard gate:** validates entitlement + release integrity; mints signing cert (Fulcio keyless) or uses KMS; signs DSSE. | Stateless; HPA by QPS. |
|
||||
| **Attestor** | `stellaops/attestor` | Posts DSSE bundles to **Rekor v2**; verification endpoints. | Stateless; HPA by QPS. |
|
||||
| **Authority** | `stellaops/authority` | On‑prem OIDC issuing **short‑lived OpToks** with DPoP/mTLS sender constraint. | HA behind LB. |
|
||||
| **Zastava** (Runtime) | `stellaops/zastava` | Runtime inspector/enforcer (observer + optional Admission Webhook). | DaemonSet + Webhook. |
|
||||
| **Web UI** | `stellaops/ui` | Angular app for scans, diffs, policy, VEX, runtime, reports. | Stateless. |
|
||||
| **StellaOps.Cli** | `stellaops/cli` | CLI for init/scan/export/diff/policy/report/verify; Buildx helper. | Local/CI. |
|
||||
|
||||
class AllModules
|
||||
### 1.2 Third‑party (self‑hosted)
|
||||
|
||||
configuration ..> identity : Uses
|
||||
identity ..> pluginloader : Authenticates Plugins
|
||||
pluginloader ..> scanning : Loads Scanner Runners
|
||||
scanning ..> feedser : Triggers Feed Merges
|
||||
tls ..> AllModules : Provides TLS Abstraction
|
||||
reporting ..> ui : Renders Reports for UI
|
||||
scheduling ..> feedser : Schedules Nightly Jobs
|
||||
* **Fulcio** (Sigstore CA) — issues short‑lived signing certs (keyless).
|
||||
* **Rekor v2** (tile‑backed transparency log).
|
||||
* **MinIO** — S3‑compatible object store with lifecycle & Object Lock.
|
||||
* **MongoDB** — catalog, advisories, VEX.
|
||||
* **Queue** — Redis Streams / NATS / RabbitMQ (pluggable).
|
||||
* **OCI Registry** — must support **Referrers API** (discover SBOMs/signatures).
|
||||
|
||||
note for scanning "Pluggable: ISScannerRunner<br>e.g., Trivy, Grype"
|
||||
note for feedser "Pluggable: *.Schedule.dll<br>e.g., OSV, GHSA Feeds"
|
||||
note for identity "Pluggable: IIdentityProvider<br>e.g., LDAP, SAML"
|
||||
note for reporting "Pluggable: IReportRenderer<br>e.g., Custom PDF"
|
||||
```
|
||||
### 1.3 Cloud licensing (Stella Ops)
|
||||
|
||||
**When remaining = 0:**
|
||||
API returns `429 Too Many Requests`, `Retry‑After: <UTC‑midnight>` (sequence omitted for brevity).
|
||||
* **Licensing Service** (`www.stella-ops.org`) — issues long‑lived **License Tokens (LT)**; exchanges LT → **Proof‑of‑Entitlement (PoE)** bound to an installation key; revoke/introspect PoE; optional cross‑log **endorsement**.
|
||||
|
||||
---
|
||||
|
||||
## 4 · Data Flows
|
||||
|
||||
### 4.1 SBOM‑First (≤ 5 s P95)
|
||||
|
||||
Builder produces SBOM locally, so Core never touches the Docker
|
||||
socket.
|
||||
Trivy path hits ≤ 5 s on alpine:3.19 with warmed DB.
|
||||
Image‑unpack fallback stays ≤ 10 s for 200 MB images.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant CI as CI/CD Pipeline (Stella CLI)
|
||||
participant SB as SBOM Builder
|
||||
participant CORE as Stella Core
|
||||
participant REDIS as Redis Queue
|
||||
participant RUN as Scanner Runner (e.g., Trivy)
|
||||
participant POL as Policy Evaluator
|
||||
|
||||
CI->>SB: Invoke SBOM Generation
|
||||
SB->>CORE: Check Missing Layers (/layers/missing)
|
||||
CORE->>REDIS: Query Layer Diff (SDIFF)
|
||||
REDIS-->>CORE: Missing Layers List
|
||||
CORE-->>SB: Return Missing Layers
|
||||
SB->>SB: Generate Delta SBOM
|
||||
SB->>CORE: Upload SBOM Blob (POST /scan(sbom))
|
||||
CORE->>REDIS: Enqueue Scan Job
|
||||
REDIS->>RUN: Fan Out to Runner
|
||||
RUN->>RUN: Perform Vulnerability Scan
|
||||
RUN-->>CORE: Return Scan Results
|
||||
CORE->>POL: Evaluate Mute Policies
|
||||
POL-->>CORE: Policy Verdict
|
||||
CORE-->>CI: JSON Verdict & Progress Stream
|
||||
Note over CORE,CI: Achieves ≤5s P95 with Warmed DB
|
||||
```
|
||||
|
||||
### 4.2 Delta SBOM
|
||||
|
||||
Builder collects layer digests.
|
||||
`POST /layers/missing` → Redis SDIFF → missing layer list (< 20 ms).
|
||||
SBOM generated only for those layers and uploaded.
|
||||
|
||||
### 4.3 Feedser Harvest & Export
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant SCHED as Feedser Scheduler
|
||||
participant CONN as Source Connector Plug-in
|
||||
participant FEEDSER as Feedser Core
|
||||
participant MONGO as MongoDB (Canonical Advisories)
|
||||
participant EXPORT as Exporter (JSON / Trivy DB)
|
||||
participant ART as Artifact Store / Offline Kit
|
||||
|
||||
SCHED->>CONN: Trigger window (init/resume)
|
||||
CONN->>CONN: Fetch source documents + metadata
|
||||
CONN->>FEEDSER: Submit raw document for parsing
|
||||
FEEDSER->>FEEDSER: Parse & normalize to DTO
|
||||
FEEDSER->>FEEDSER: Merge & deduplicate canonical advisory
|
||||
FEEDSER->>MONGO: Write advisory, provenance, merge_event
|
||||
FEEDSER->>EXPORT: Queue export delta request
|
||||
EXPORT->>MONGO: Read canonical snapshot/deltas
|
||||
EXPORT->>EXPORT: Build deterministic JSON & Trivy DB artifacts
|
||||
EXPORT->>ART: Publish artifacts / Offline Kit bundle
|
||||
ART-->>FEEDSER: Record export state + digests
|
||||
```
|
||||
|
||||
### 4.4 Identity & Auth Flow
|
||||
|
||||
OpenIddict issues JWTs via client‑credentials or password grant.
|
||||
An IIdentityProvider plug‑in can delegate to LDAP, SAML or external OIDC
|
||||
without Core changes.
|
||||
---
|
||||
## 5 · Runtime Helpers
|
||||
|
||||
| Helper | Form | Purpose | Extensible Bits |
|
||||
|-----------|---------------------------------------|--------------------------------------------------------------------|-------------------------------------------|
|
||||
| **Stella CLI** | Distroless CLI | Generates SBOM, calls `/scan`, honours threshold flag | `--engine`, `--pdf-out` piped to plug‑ins |
|
||||
| **Zastava** | Static Go binary / DaemonSet | Watches Docker/CRI‑O events; uploads SBOMs; can enforce gate | Policy plug‑in could alter thresholds |
|
||||
|
||||
---
|
||||
|
||||
## 6 · Persistence & Cache Strategy
|
||||
|
||||
| Store | Primary Use | Why chosen |
|
||||
|----------------|-----------------------------------------------|--------------------------------|
|
||||
| **MongoDB** | Feedser canonical advisories, merge events, export state | Deterministic canonical store with flexible schema |
|
||||
| **Redis 7** | CLI quotas, short-lived job scheduling, layer diff cache | Sub-1 ms P99 latency for hot-path coordination |
|
||||
| **Local tmpfs**| Trivy layer cache (`/var/cache/trivy`) | Keeps disk I/O off hot path |
|
||||
### 1.4 Diagram (control/data planes & trust)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "Persistence Layers"
|
||||
REDIS[(Redis: Quotas & Short-lived Queues<br>Sub-1ms P99)]
|
||||
MONGO[(MongoDB: Canonical Advisories<br>Merge Events & Export State)]
|
||||
TMPFS[(Local tmpfs: Trivy Layer Cache<br>Low I/O Overhead)]
|
||||
end
|
||||
subgraph Cloud["www.stella-ops.org (Cloud)"]
|
||||
LS[Licensing Service<br/>LT→PoE / revoke / introspect]
|
||||
end
|
||||
|
||||
CORE["Stella Core"] -- Queues & SBOM Cache --> REDIS
|
||||
CORE -- Long-term Storage --> MONGO
|
||||
TRIVY["Trivy Scanner"] -- Layer Unpack Cache --> TMPFS
|
||||
subgraph OnPrem["Customer Site (Self-hosted)"]
|
||||
Auth[Authority (OIDC)\nOpTok (DPoP/mTLS)]
|
||||
SW[Scanner.WebService]
|
||||
WK[Scanner.Worker xN]
|
||||
FEED[Feedser]
|
||||
VEX[Vexer]
|
||||
POL[Policy Engine (in Scanner.Web)]
|
||||
SGN[Signer\n(entitlement + signing)]
|
||||
ATT[Attestor\n(Rekor v2 submit/verify)]
|
||||
UI[Web UI (Angular)]
|
||||
Z[Zastava\n(Runtime Inspector/Enforcer)]
|
||||
MIN[(MinIO S3)]
|
||||
MGO[(MongoDB)]
|
||||
QUE[(Queue/Streams)]
|
||||
end
|
||||
|
||||
style REDIS fill:#fdd,stroke:#333
|
||||
style MONGO fill:#dfd,stroke:#333
|
||||
style TMPFS fill:#ffd,stroke:#333
|
||||
CLI[StellaOps.Cli / Buildx Plugin]
|
||||
REG[(OCI Registry with Referrers)]
|
||||
FUL[ Fulcio ]
|
||||
REK[ Rekor v2 (tiles) ]
|
||||
|
||||
CLI -->|scan/build| SW
|
||||
SW -->|jobs| QUE
|
||||
QUE --> WK
|
||||
WK --> MIN
|
||||
SW --> MGO
|
||||
FEED --> MGO
|
||||
VEX --> MGO
|
||||
UI --> SW
|
||||
Z --> SW
|
||||
|
||||
SGN <--> Auth
|
||||
SGN --> FUL
|
||||
SGN -->|mTLS| ATT
|
||||
ATT --> REK
|
||||
|
||||
SGN <-->|verify referrers| REG
|
||||
```
|
||||
|
||||
**Trust boundaries.** Only **Signer** can sign; only **Attestor** can write to **Rekor v2**. Scanner/UI never sign.
|
||||
|
||||
---
|
||||
|
||||
## 2) Licensing & tokens (installation‑ready, theft‑resistant)
|
||||
|
||||
**Two‑token model.**
|
||||
|
||||
* **License Token (LT)** — long‑lived JWT from **Licensing Service**; used **once** to enroll the installation; never used in hot path.
|
||||
* **Proof‑of‑Entitlement (PoE)** — bound to the installation key (mTLS client cert **or** DPoP‑bound JWT with `cnf`); medium‑lived; renewable; revocable.
|
||||
* **Operational token (OpTok)** — 2–5 min OIDC token from **Authority**, **sender‑constrained** (DPoP or mTLS). Used to authenticate to **Signer**/**Scanner.WebService**.
|
||||
|
||||
**Signer enforces both:** PoE proves entitlement; OpTok proves “who is calling now”. It also **independently verifies** the **scanner image digest** is **Stella Ops‑signed** via **Referrers + cosign** before signing anything.
|
||||
|
||||
**Enrollment sequence (LT → PoE).**
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
actor Operator
|
||||
participant "Install Agent" as IA
|
||||
participant "Licensing Service" as LS
|
||||
Operator -> IA: Provide LT
|
||||
IA -> IA: Generate K_inst
|
||||
IA -> LS: /license/enroll {LT, pub(K_inst)}
|
||||
LS --> IA: PoE (mTLS client cert or JWT with cnf=K_inst), CRL/OCSP/introspect
|
||||
@enduml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7 · Typical Scenarios
|
||||
## 3) Scanner subsystem (facts engine)
|
||||
|
||||
| # | Flow | Steps |
|
||||
|---------|----------------------------|-------------------------------------------------------------------------------------------------|
|
||||
| **S‑1** | Pipeline Scan & Alert | Stella CLI → SBOM → `/scan` → policy verdict → CI exit code & link to *Scan Detail* |
|
||||
| **S‑2** | Mute Noisy CVE | Dev toggles **Mute** in UI → rule stored in Redis → next build passes |
|
||||
| **S‑3** | Nightly Re‑scan | `SbomNightly.Schedule` re‑queues SBOMs (mask‑filter) → dashboard highlights new Criticals |
|
||||
| **S‑4** | Feed Update Cycle | `Feedser (vulnerability ingest/merge/export service)` refreshes feeds → UI *Feed Age* tile turns green |
|
||||
| **S‑5** | Custom Report Generation | Plug‑in registers `IReportRenderer` → `/report/custom/{digest}` → CI downloads artifact |
|
||||
### 3.1 Analyzers (deterministic only)
|
||||
|
||||
* **OS packages:** apk/dpkg/rpm (Linux); Windows MSI/SxS/GAC (M2).
|
||||
* **Language (installed state):**
|
||||
|
||||
* Java (pom.properties / MANIFEST) → `pkg:maven/...`
|
||||
* Node (`node_modules/*/package.json`) → `pkg:npm/...`
|
||||
* Python (`*.dist-info/METADATA`) → `pkg:pypi/...`
|
||||
* Go (buildinfo) → `pkg:golang/...`
|
||||
* .NET (`*.deps.json`) → `pkg:nuget/...`
|
||||
* **Rust:** deterministic **language markers** (symbol mangling) and crates only when present; otherwise `bin:{sha256}`.
|
||||
* **Native:** ELF/PE/Mach‑O imports, DT_NEEDED, RPATH/RUNPATH, symbol versions, PE version info.
|
||||
* **EntryTrace:** parse `ENTRYPOINT`/`CMD`; shell AST; resolve launchers (Java/Node/Python) to terminal program; record file:line chain.
|
||||
|
||||
### 3.2 Caching & composition
|
||||
|
||||
* **Layer cache:** `{layerDigest → SBOM fragment + analyzer meta}`.
|
||||
* **File CAS:** `{sha256(file) → parse result (ELF/JAR metadata/etc.)}`.
|
||||
* **Composition:** build **image SBOMs** from fragments via **BOM‑Link/ExternalRef**; emit **two views**:
|
||||
|
||||
* **Inventory** (complete filesystem inventory).
|
||||
* **Usage** (entrypoint closure + linked libs).
|
||||
* **Transport:** JSON **and** **CycloneDX Protobuf** (compact, fast to parse).
|
||||
* **Index:** BOM‑Index sidecar with purl table + roaring bitmap + `usedByEntrypoint` flag for fast joins.
|
||||
|
||||
### 3.3 Diff (image → layer → package)
|
||||
|
||||
* Added / Removed / Version‑changed changes, **attributed** to the layer that caused them.
|
||||
* Raw diffs preserved; backend view applies **VEX + Policy**.
|
||||
|
||||
### 3.4 Build‑time SBOMs (fast CI path)
|
||||
|
||||
* Buildx **generator** runs analyzers during `docker buildx build --attest=type=sbom,generator=stellaops/sbom-indexer`, attaches SBOMs as **OCI referrers**.
|
||||
* Scanner.WebService can trust these (policy‑configurable) and **skip** re‑scan; DSSE + Rekor v2 can be done either at build time or post‑push via Signer/Attestor.
|
||||
|
||||
---
|
||||
|
||||
## 4) Backend evaluation (decider)
|
||||
|
||||
### 4.1 Feedser (advisories)
|
||||
|
||||
* Ingests vendor, distro, OSS feeds; normalizes & merges; persists canonical advisories in Mongo; exports **deterministic JSON** and **Trivy DB**.
|
||||
* Offline kit bundles for air‑gapped sites.
|
||||
|
||||
### 4.2 Vexer (VEX)
|
||||
|
||||
* Ingests **OpenVEX / CSAF VEX / CycloneDX VEX**; normalizes claims; retains conflicts; computes **consensus** with provider trust weights and justification gates.
|
||||
|
||||
### 4.3 Policy Engine (YAML DSL)
|
||||
|
||||
* Matchers: `image/repo/env/purl/cve/vendor/source/path/layerDigest/usedByEntrypoint`
|
||||
* Actions: `ignore(until, justification)`, `fail`, `warn`, `defer`, `requireVEX{vendors, justifications}`, `escalate {sev, KEV, EPSS}`, license constraints.
|
||||
* Produces a **policy digest** (SHA‑256 of canonicalized policy).
|
||||
|
||||
### 4.4 PASS/FAIL flow
|
||||
|
||||
1. SBOM (Inventory / Usage) → join with **Feedser** advisories.
|
||||
2. Apply **Vexer** consensus (statuses & justifications).
|
||||
3. Apply **Policy**; compute PASS/FAIL with waiver TTLs.
|
||||
4. Sign the **final report** (DSSE via **Signer**) and log to **Rekor v2** via **Attestor**.
|
||||
|
||||
---
|
||||
|
||||
## 5) Runtime enforcement (Zastava)
|
||||
|
||||
* **Observer:** inventories running containers, checks image signatures, SBOM presence (referrers), detects drift (entrypoint chain divergence), flags unapproved images.
|
||||
* **Admission Webhook (optional):** blocks policy‑fail pods (dry‑run first).
|
||||
* **Integration:** posts runtime events to Scanner.WebService; can request **delta scans** on changed layers.
|
||||
|
||||
---
|
||||
|
||||
## 6) Storage & catalogs (MinIO/Mongo)
|
||||
|
||||
**MinIO layout**
|
||||
|
||||
```
|
||||
s3://stellaops/
|
||||
layers/<sha256>/sbom.cdx.json.zst
|
||||
layers/<sha256>/sbom.spdx.json.zst
|
||||
images/<imgDigest>/inventory.cdx.pb
|
||||
images/<imgDigest>/usage.cdx.pb
|
||||
indexes/<imgDigest>/bom-index.bin
|
||||
attest/<artifactSha256>.dsse.json
|
||||
```
|
||||
|
||||
**Catalog (Mongo)**
|
||||
|
||||
* `artifacts` (type/format/sha/size/rekor/ttl/immutable/refCount/createdAt)
|
||||
* `images`, `layers`, `links`, `lifecycleRules`
|
||||
|
||||
**Retention**
|
||||
|
||||
* MinIO **ILM** for coarse TTL; Scanner.WebService GC decrements `refCount` and deletes unreferenced metadata; **Object Lock** for immutable classes (auditable artifacts).
|
||||
|
||||
---
|
||||
|
||||
## 7) APIs (consolidated surface)
|
||||
|
||||
### 7.1 Scanner.WebService
|
||||
|
||||
```
|
||||
POST /api/scans { imageRef|digest, force? } → { scanId }
|
||||
GET /api/scans/{id} → { status, digests, artifacts[] }
|
||||
GET /api/sboms/{imageDigest} ?format=cdx-json|cdx-pb|spdx-json&view=inventory|usage
|
||||
GET /api/diff?old=<digest>&new=<digest> → { added[], removed[], changed[], byLayer[] }
|
||||
POST /api/exports { imageDigest, format, view } → { artifactId, rekorUrl }
|
||||
POST /api/reports { imageDigest, policyRevision? } → { reportId, rekorUrl }
|
||||
GET /api/catalog/artifacts/{id} → { size, ttl, immutable, rekor, refs }
|
||||
GET /healthz | /readyz | /metrics
|
||||
```
|
||||
|
||||
### 7.2 Signer (mTLS; hard gate)
|
||||
|
||||
```
|
||||
POST /sign/dsse # body: {subjectHash, imageDigest, predicate}; headers: OpTok (DPoP/mTLS) + PoE
|
||||
GET /verify/referrers?imageDigest=sha256:... # is this image StellaOps-signed?
|
||||
```
|
||||
|
||||
### 7.3 Attestor (mTLS)
|
||||
|
||||
```
|
||||
POST /rekor/entries # DSSE bundle → {uuid, index, proof, logURL}
|
||||
GET /rekor/entries/{uuid}
|
||||
```
|
||||
|
||||
### 7.4 Authority (OIDC)
|
||||
|
||||
* `/.well-known/openid-configuration`, `/oauth/token` (DPoP/mTLS), `/oauth/introspect`, `/jwks`
|
||||
|
||||
### 7.5 Licensing (cloud)
|
||||
|
||||
```
|
||||
POST /license/enroll { LT, pubKey } → PoE + introspection endpoints
|
||||
POST /license/revoke { license_id } → ok
|
||||
POST /license/introspect { poe } → { active, claims, exp }
|
||||
POST /attest/endorse { bundle } → endorsement bundle (optional)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8) Security & verifiability
|
||||
|
||||
* **Sender‑constrained tokens.** All operational calls use **DPoP** (RFC 9449) or **mTLS‑bound** tokens (RFC 8705).
|
||||
* **Entitlement.** **PoE** is mandatory; revocation honored online.
|
||||
* **Release integrity.** **Signer** independently verifies **scanner image digest** via **Referrers + cosign** before signing.
|
||||
* **Separation of duties.** Scanner/UI cannot sign; only **Signer** can sign; only **Attestor** can write to **Rekor v2**.
|
||||
* **Verifiers.** Anyone can verify: DSSE signature → certificate chain to **Stella Ops Fulcio/KMS root** → **Rekor v2** inclusion.
|
||||
* **Community vs Authorized.** Free/community runs throttled with no official attestations; authorized runs full speed and produce **Stella Ops‑verified** bundles.
|
||||
|
||||
**DSSE predicate (SBOM/report)**
|
||||
|
||||
```json
|
||||
{
|
||||
"predicateType": "https://stella-ops.org/attestations/sbom/1",
|
||||
"subject": [{ "name": "s3://stellaops/images/<digest>/inventory.cdx.pb", "digest": { "sha256": "<sha256>" } }],
|
||||
"predicate": {
|
||||
"image_digest": "<sha256:...>",
|
||||
"stellaops_version": "2.3.1 (2027.04)",
|
||||
"license_id": "LIC-9F2A...",
|
||||
"customer_id": "CUST-ACME",
|
||||
"plan": "pro",
|
||||
"policy_digest": "sha256:...",
|
||||
"views": ["inventory","usage"],
|
||||
"created": "2025-10-17T12:34:56Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**BOM‑Index sidecar**
|
||||
Binary header + purl table + roaring bitmaps; optional `usedByEntrypoint` flags for fast policy joins.
|
||||
|
||||
---
|
||||
|
||||
## 9) Scale, performance & quotas
|
||||
|
||||
* **Workers:** horizontal; **distributed lock per layer digest**; global CAS in MinIO.
|
||||
* **Queues:** Redis Streams / NATS / RabbitMQ. HPA by queue depth, CPU, memory.
|
||||
* **Registry throttling:** per‑registry concurrency budgets.
|
||||
* **Targets:**
|
||||
|
||||
* Build‑time path P95 ≤ 3–5 s on warmed bases.
|
||||
* Post‑build delta scan P95 ≤ 10 s for 200 MB images.
|
||||
* Policy + VEX evaluation ≤ 500 ms for 5k components using BOM‑Index.
|
||||
* **Quotas:** license plan enforces QPS/concurrency/size; **Signer** throttles and can deny DSSE.
|
||||
|
||||
---
|
||||
|
||||
## 10) DevOps & distribution
|
||||
|
||||
* **Releases:** all first‑party images **cosign‑signed**; labels embed `org.stellaops.version` and `org.stellaops.release_date`.
|
||||
* **Channels:**
|
||||
|
||||
* **Community** (public registry): throttled, non‑attesting.
|
||||
* **Authorized** (private registry): full speed, DSSE enabled.
|
||||
* **Client update flow:** containers self‑verify signatures at boot; report version; **Signer** enforces `valid_release_year` / `max_version` from PoE before signing.
|
||||
* **Compose skeleton:**
|
||||
|
||||
```yaml
|
||||
services:
|
||||
authority: { image: stellaops/authority }
|
||||
fulcio: { image: sigstore/fulcio }
|
||||
rekor: { image: sigstore/rekor-v2 }
|
||||
minio: { image: minio/minio, command: server /data --console-address ":9001" }
|
||||
mongo: { image: mongo:7 }
|
||||
signer: { image: stellaops/signer, depends_on: [authority, fulcio] }
|
||||
attestor: { image: stellaops/attestor, depends_on: [rekor, signer] }
|
||||
scanner-web:{ image: stellaops/scanner-web, depends_on: [mongo, minio, signer, attestor] }
|
||||
scanner-worker:
|
||||
image: stellaops/scanner-worker
|
||||
deploy: { replicas: 4 }
|
||||
depends_on: [scanner-web]
|
||||
feedser: { image: stellaops/feedser-web, depends_on: [mongo] }
|
||||
vexer: { image: stellaops/vexer-web, depends_on: [mongo] }
|
||||
ui: { image: stellaops/ui, depends_on: [scanner-web, feedser, vexer] }
|
||||
```
|
||||
|
||||
* **Backups:** Mongo dumps; MinIO versioned buckets & replication; Rekor v2 DB snapshots; JWKS/Fulcio/KMS key rotation.
|
||||
|
||||
---
|
||||
|
||||
## 11) Observability & audit
|
||||
|
||||
* **Metrics:** scan latency, layer cache hit %, artifact bytes, DSSE/Rekor latency, policy evaluation time, queue depth, admission decisions (Zastava).
|
||||
* **Tracing:** per‑stage spans; correlation IDs across Scanner→Signer→Attestor.
|
||||
* **Audit logs:** every signing records `license_id`, `image_digest`, `policy_digest`, and Rekor UUID.
|
||||
* **Compliance:** MinIO **Object Lock** for immutable artifacts; reproducible outputs via policy digest + SBOM digest in predicate.
|
||||
|
||||
---
|
||||
|
||||
## 12) Roadmap (anchored to this architecture)
|
||||
|
||||
* M2: Windows MSI/SxS/GAC analyzers; deeper Rust (DWARF enrichers).
|
||||
* M2: Buildx generator certified flows; cross‑registry trust policies.
|
||||
* M3: Patch‑Presence plugin (signature‑based backport detection), opt‑in.
|
||||
* M3: Zastava Admission control GA with policy presets and dry‑run→enforce stages.
|
||||
* Continuous: Policy UX (waiver TTLs, vendor rules), Vexer connectors expansion.
|
||||
|
||||
---
|
||||
|
||||
## 13) Canonical sequences (verification & signing)
|
||||
|
||||
**Sign & log (OpTok + PoE, image verify, DSSE, Rekor).**
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant DEV as Developer
|
||||
participant UI as Web UI
|
||||
participant CORE as Stella Core
|
||||
participant REDIS as Redis
|
||||
participant RUN as Scanner Runner
|
||||
autonumber
|
||||
participant Scan as Scanner.WebService
|
||||
participant Auth as Authority (OIDC)
|
||||
participant Sign as Signer
|
||||
participant Reg as OCI Registry
|
||||
participant Ful as Fulcio/KMS
|
||||
participant Att as Attestor
|
||||
participant Rek as Rekor v2
|
||||
|
||||
DEV->>UI: Toggle Mute for CVE
|
||||
UI->>CORE: Update Mute Rule (POST /policy/mute)
|
||||
CORE->>REDIS: Store Mute Policy
|
||||
Note over CORE,REDIS: YAML/Rego Evaluator Updates
|
||||
|
||||
alt Next Pipeline Build
|
||||
CI->>CORE: Trigger Scan (POST /scan)
|
||||
CORE->>RUN: Enqueue & Scan
|
||||
RUN-->>CORE: Raw Findings
|
||||
CORE->>REDIS: Apply Mute Policies
|
||||
REDIS-->>CORE: Filtered Verdict (Passes)
|
||||
CORE-->>CI: Success Exit Code
|
||||
end
|
||||
Scan->>Auth: Get OpTok (DPoP/mTLS)
|
||||
Scan->>Sign: sign(request) + OpTok + PoE + DPoP proof
|
||||
Sign->>Auth: Validate OpTok & sender-constraint
|
||||
Sign->>Sign: Validate PoE (introspect/revocation)
|
||||
Sign->>Reg: Verify scanner image is StellaOps-signed (Referrers + cosign)
|
||||
alt OK
|
||||
Sign->>Ful: Get signing cert (keyless) or use KMS key
|
||||
Sign-->>Scan: DSSE bundle (cert chain)
|
||||
Scan->>Att: Submit bundle
|
||||
Att-->>Rek: Create entry
|
||||
Rek-->>Att: {uuid,index,proof}
|
||||
Att-->>Scan: Rekor URL
|
||||
else Deny
|
||||
Sign-->>Scan: 403 (no attestation)
|
||||
end
|
||||
```
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant CRON as SbomNightly.Schedule
|
||||
participant CORE as Stella Core
|
||||
participant REDIS as Redis Queue
|
||||
participant RUN as Scanner Runner
|
||||
participant UI as Dashboard
|
||||
**Verification (third party).**
|
||||
|
||||
CRON->>CORE: Re-queue SBOMs (Mask-Filter)
|
||||
CORE->>REDIS: Enqueue Filtered Jobs
|
||||
REDIS->>RUN: Fan Out to Runners
|
||||
RUN-->>CORE: New Scan Results
|
||||
CORE->>UI: Highlight New Criticals
|
||||
Note over CORE,UI: Focus on Changes Since Last Scan
|
||||
```plantuml
|
||||
@startuml
|
||||
actor Verifier
|
||||
participant "stellaops verify" as Tool
|
||||
database "Fulcio/KMS root" as Root
|
||||
participant "Rekor v2" as R2
|
||||
Verifier -> Tool: bundle (URL/file)
|
||||
Tool -> Tool: Verify DSSE signature
|
||||
Tool -> Root: Verify cert chain to StellaOps root
|
||||
Tool -> R2: Verify inclusion proof / query by UUID
|
||||
Tool -> Verifier: OK + claims (license_id, policy_digest, version)
|
||||
@enduml
|
||||
```
|
||||
---
|
||||
|
||||
## 8 · UI Fast Facts
|
||||
|
||||
* **Stack** – Angular 17 + Vite dev server; Tailwind CSS.
|
||||
* **State** – Signals + RxJS for live scan progress.
|
||||
* **i18n / l10n** – JSON bundles served from `/locales/{lang}.json`.
|
||||
* **Module Structure** – Lazy‑loaded feature modules (`dashboard`, `scans`, `settings`); runtime route injection by UI plug‑ins (road‑map Q2‑2026).
|
||||
|
||||
---
|
||||
|
||||
## 9 · Cross‑Cutting Concerns
|
||||
|
||||
* **Security** – containers run non‑root, `CAP_DROP:ALL`, read‑only FS, hardened seccomp profiles.
|
||||
* **Observability** – Serilog JSON, OpenTelemetry OTLP exporter, Prometheus `/metrics`.
|
||||
* **Upgrade Policy** – `/api/v1` endpoints & CLI flags stable across a minor; breaking changes bump major.
|
||||
|
||||
---
|
||||
|
||||
## 10 · Performance & Scalability
|
||||
|
||||
| Scenario | P95 target | Bottleneck | Mitigation |
|
||||
|-----------------|-----------:|-----------------|-------------------------------------------------|
|
||||
| SBOM‑first | ≤ 5 s | Redis queue | More CPU, increase `ScannerPool.Workers` |
|
||||
| Image‑unpack | ≤ 10 s | Layer unpack | Prefer SBOM path, warm Docker cache |
|
||||
| High concurrency| 40 rps | Runner CPU | Scale Core replicas + side‑car scanner services |
|
||||
|
||||
---
|
||||
|
||||
## 11 · Future Architectural Anchors
|
||||
|
||||
* **ScanService micro‑split (gRPC)** – isolate heavy runners for large clusters.
|
||||
* **UI route plug‑ins** – dynamic Angular module loader (road‑map Q2‑2026).
|
||||
* **Redis Cluster** – transparently sharded cache once sustained > 100 rps.
|
||||
|
||||
---
|
||||
|
||||
## 12 · Assumptions & Trade‑offs
|
||||
|
||||
Requires Docker/CRI‑O runtime; .NET 9 available on hosts; Windows containers are out‑of‑scope this cycle.
|
||||
Embedded auth simplifies deployment but may need plug‑ins for enterprise IdPs.
|
||||
Speed is prioritised over exhaustive feature parity with heavyweight commercial scanners.
|
||||
|
||||
---
|
||||
|
||||
## 13 · References & Further Reading
|
||||
|
||||
* **C4 Model** – <https://c4model.com>
|
||||
* **.NET Architecture Guides** – <https://learn.microsoft.com/dotnet/architecture>
|
||||
* **OSS Examples** – Kubernetes Architecture docs, Prometheus design papers, Backstage.
|
||||
|
||||
*(End of High‑Level Architecture v2.2)*
|
||||
**End of `high_level_architecture.md` (Consolidated).**
|
||||
|
||||
Reference in New Issue
Block a user