Skip to content

Threat model — STRIDE

Scope: the on-prem TLSStress.Art appliance (Dashboard, agents, personas, MÓDULOs) and its single channel to the SaaS control plane. Written against the HLD container view. The governing posture is ZTP-prem (SECURITY_ZTP_PREM.md): the operator's own network and host are assumed hostile.

Companion model: the cloud SaaS surfaces (customer-app, cell-0, billing) have their own STRIDE analysis in THREAT_MODEL.md. This document covers the on-prem bench; that one covers the commercial control plane.

Data-flow description

The bench spans five trust zones. Traffic only crosses a zone boundary at the arrows below; each crossing is a place threats are enumerated.

  ┌─ Cloud SaaS control plane (always-online) ─────────────────────┐
  │  customer-app (Next.js)  ── HMAC POST /trigger ──▶ cell-0        │
  │  (signup · Stripe · TSU mint · RLS tenant DB)     (provisioning)│
  └───────────────▲──────────────────────────────┬─────────────────┘
                  │ hourly TSU usage report       │ TBI artifact (S3)
                  │ (on-prem → cloud, HMAC)        │ download
  ┌───────────────┴───────────────────────────────▼─────────────────┐
  │  On-prem appliance (customer datacenter)                         │
  │                                                                  │
  │   Operator ──HMAC cookie──▶ Dashboard ──SQL──▶ Postgres 16       │
  │                                │  (audit_log, UTXO notes)        │
  │                    Bearer + Idempotency-Key                      │
  │                                ▼                                 │
  │                       Agents (Playwright / k6)                   │
  │                                │                                 │
  │   (control + Prometheus scrape ride the OOBI fabric, VLAN 2777)  │
  └────────────────────────────────┼────────────────────────────────┘
                                    │ TLS leg 1 (h2/h3)
                                    ▼
                          ┌──────────────────┐
                          │   NGFW DUT        │  decrypt · inspect · re-sign
                          └────────┬─────────┘
                                    │ TLS leg 2 (re-signed cert)
                                    ▼
                    Personas (100 Caddy webservers, 20 countries)

Five zones: (Z1) Cloud SaaS, (Z2) On-prem control plane (Dashboard + Postgres), (Z3) Agents, (Z4) DUT (untrusted device under test), (Z5) Personas. The OOBI fabric is the out-of-band management plane carrying Z2↔Z3 control + Prometheus scrape; the test data plane (agents → DUT → personas) is deliberately isolated from it (macvlan net1, bypasses iptables/NetworkPolicy).

STRIDE analysis

Ranked roughly by residual risk. Each row: threat → the boundary it crosses → existing mitigation.

Spoofing (identity)

# Threat Boundary Mitigation
S1 Attacker on the operator LAN impersonates the operator to the Dashboard Operator → Z2 HMAC-signed session cookie; ZTP-prem assumes hostile LAN; admin MFA is the tracked residual gap.
S2 Rogue process impersonates an agent to the Dashboard control API Z2 ↔ Z3 Bearer token per agent + Idempotency-Key; agents run in their own namespaces.
S3 Forged hourly usage report inflates/deflates a tenant's billed TSU On-prem → Z1 HMAC on the /api/usage/report POST; UTXO ledger is append-only and reconciled cloud-side.
S4 Forged provisioning trigger onboards a rogue tenant Z1 (app → cell-0) HMAC POST /trigger; PROVISIONING_TRIGGER_SECRET rotation is a tracked operational task.

Tampering (integrity)

# Threat Boundary Mitigation
T1 Tampered container image swapped into a release Z1 → on-prem (TBI/pull) Cosign keyless OIDC signatures + SBOM + release-feed digest pinning; verified via verify-release.md.
T2 Operator (or malware on their host) mutates bench config out-of-band, bypassing audit Operator → Z2 Dashboard is the ONLY config surface; every mutation writes audit_log (WORM hash-chain, AUDIT_LOG.md); CPOS 2PC makes multi-step changes atomic.
T3 DUT re-signs persona traffic with an attacker cert the agents wrongly trust Z3 → Z4 → Z5 Two-leg TLS is intentional: agents trust only the NGFW CA (leg 1); DUT trusts only persona-ca-issuer (leg 2). REJECT_INVALID_CERTS=true on agents.

Repudiation (non-attribution)

# Threat Boundary Mitigation
R1 Operator denies having run a destructive/production action Operator → Z2 Append-only audit_log with RFC 5424 + hash-chain; PIE-PA forces an explicit click-through for production writes.
R2 Cloud disputes on-prem usage On-prem → Z1 Signed hourly reports + UTXO note lineage reconcile on both sides.

Information disclosure (confidentiality)

# Threat Boundary Mitigation
I1 Sniffing the test data plane leaks persona/agent traffic Z3 ↔ Z5 Data plane is TLS end-to-end; macvlan isolation keeps it off the management fabric.
I2 Cross-tenant data read in the SaaS control plane within Z1 Postgres RLS on the cell control DB; per-tenant isolation is enforced, not app-level filtered.
I3 Secrets (Stripe, provisioning HMAC, TSU keys) exposed in logs or images Z1 / Z2 No hardcoded secrets (Go/Python standards + gates); secrets via env/secret store; SBOM lets an auditor confirm image contents.
I4 OOBI management traffic sniffed on a shared switch OOBI fabric Encrypted OOBI Hello/KeepAlive payloads (ADR 0046); no VXLAN overlay (ADR 0043) reduces attack surface.

Denial of service (availability)

# Threat Boundary Mitigation
D1 Runaway agent scaling saturates the operator's own network / the DUT beyond intent Z3 → Z4 HPA caps (Playwright max=80, k6 max=200); per-target circuit breaker; blast-radius pod quota.
D2 A wedged agent busy-spins / leaks connections within Z3 Graceful SIGTERM shutdown + fractional sleep in daemons (Python/Go standards); tcp_sockets_open metric surfaces leaks.
D3 Cloud provisioning saga stuck, blocking new tenants within Z1 Temporal saga with retries; cell-0 HA (ADR 0105).

Elevation of privilege

# Threat Boundary Mitigation
E1 Agent pod breaks out to node-level privilege Z3 Agents run non-privileged; NET_ADMIN scoped to init only; PSA baseline rejects unexpected capabilities.
E2 Operator without admin performs an admin-only mutation Operator → Z2 Dashboard authorizes every mutation; RBAC/SSO with separation-of-duties is the tracked residual (E1 RBAC epic).
E3 Compromised DUT pivots back into the appliance Z4 → Z2/Z3 The DUT is untrusted by design and only reachable on the isolated test data plane; it has no path onto the OOBI management fabric.

Residual risks (tracked, not yet closed)

These are known gaps carried in the backlog / memory, surfaced here so the threat model is honest rather than aspirational:

  • Admin MFA (S1) — dashboard admin login lacks a second factor.
  • RBAC / SSO with SoD (E2) — role separation for operators is deferred (E1 RBAC epic).
  • Secret rotation cadence (S4) — PROVISIONING_TRIGGER_SECRET and OOBI PSK/WG keys rotate manually; no automated cadence yet.