Shielda — STRIDE Threat Model
_Gate ID: G-7 / P3.3-TM1 · Last reviewed: 2026-04-23 · Owner: Security lead._
Gate ID: G-7 / P3.3-TM1 · Last reviewed: 2026-04-23 · Owner: Security lead.
This document enumerates Shielda's components and applies Microsoft's STRIDE taxonomy (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) to each. Mitigations reference the production controls already in place; follow-ups are tracked against the Phase 3 / Phase 4 gate IDs.
System decomposition
Trust boundaries
TB1 Browser ↔ Cloudflare edge (TLS). TB2 Edge ↔ Control-plane origin (mTLS-equivalent via Cloudflare cert). TB3 Control-plane ↔ RDS / S3 (VPC, IAM). TB4 Control-plane ↔ Agent (bearer + per-agent token, timing-safe). TB5 Control-plane ↔ LLM providers (API key per route). TB6 Control-plane ↔ OAuth vendors (OIDC discovery, state param).
---
Component (1) — Cloudflare edge
STRIDE Threat Mitigation Residual --- --- --- --- S DNS hijack / edge impersonation DNSSEC signed; HSTS preload on apex accepted T TLS downgrade / stripping HSTS + includeSubDomains + preload accepted R Request provenance Cloudflare logs + cf-ray propagated to app logs accepted I Edge-cached secret response Cache-Control: private, no-store on all authed routes; verified by lint:cache-headers accepted D L7 DDoS Cloudflare rate-limit + WAF ruleset accepted E Rule misconfig IaC in infra/modules; reviewed PRs accepted
Component (2) — Control-plane SaaS
STRIDE Threat Mitigation Residual --- --- --- --- S Session forgery Auth0 RS256 JWT + rotating cookies accepted S Agent impersonation Bearer + per-agent token-hash + crypto.timingSafeEqual accepted T Parameter tampering (IDOR) orgId scoped Drizzle queries; quarterly IDOR fuzz (P3.1-I1) quarterly retest T Mass assignment Zod body schemas on every mutation route accepted R Action attribution writeAuditLog on every admin + mutation route; actor, orgid, ip, ua captured accepted I NL2SQL leakage Drizzle parameterised via nl2query-prompt.ts accepted I Prompt-injection exfiltration prompt-guardrails.ts + Garak corpus (P3.1-PI1) pentest retest I Error-message leakage Sentry scrub + apiError() normalises 500s accepted I SSRF from webhook/report delivery webhook-ssrf-guard.ts, denylist-private-ranges, DNS resolve-and-reverify accepted D Rate-limit abuse Cloudflare + app-level per-org throttle accepted E Privilege escalation via role bypass Role checks in withApiHandler({ access }); 267/267 routes wrapped accepted E Break-glass misuse Break-glass token + audit event + alert accepted
Component (3) — Storage (RDS + S3)
STRIDE Threat Mitigation Residual --- --- --- --- S Credential theft AWS IAM roles (no long-lived keys on hosts) accepted T Database tampering RDS automated backups + WAL; restore drill (G-4) drill pending T Object mutation S3 versioning + object lock on compliance bundles accepted R DB-layer provenance writeAuditLog at app layer; Postgres audit-log extension optional accepted I At-rest disclosure RDS SSE-KMS; S3 SSE-KMS; field-level AES-GCM (encrypt.ts) accepted D DB overload Read replicas + connection-pool limits accepted E DB direct access VPC-only; bastion with short-lived creds; no public endpoint accepted
Component (4) — Background workers
STRIDE Threat Mitigation Residual --- --- --- --- S Replay of job payloads Per-job dedup key + at-most-once semantics accepted T Job-queue tampering Queue in same VPC; IAM-scoped accepted R Worker action logging Structured logs with jobid, orgid accepted I PII in job payloads Pass IDs, not payloads; workers read fresh from DB accepted D Queue flood Per-org quota + DLQ accepted E Worker exploit via deserialization Payloads are JSON + Zod-validated accepted
Component (5) — Agent (Go) in customer env
STRIDE Threat Mitigation Residual --- --- --- --- S Malicious agent registration Invite code + one-time-use registration token accepted T Binary tampering Cosign-signed release + SBOM attestation (§ F of SECURITYREPORT) accepted T Symlink escape during scan agent/internal/safewalk refuses to cross mount points accepted R Command provenance Every outbound request carries agentid + signed nonce accepted I Secret exfiltration via scan output Scan findings are redacted by trufflehog post-processor; payloads hashed accepted D Resource exhaustion on host exec.CommandContext timeouts on every external tool accepted E Privilege escalation on host Agent runs non-root; capabilities dropped; rootfs read-only in container mode accepted
Component (6) — MCP server
STRIDE Threat Mitigation Residual --- --- --- --- S Tool-spoof via prompt Tool spec validated against schemas/toolspec.schema.json accepted T Prompt-injection to exfil Guardrails applied before tool invocation accepted I Token leakage via model No tokens passed as tool args; server fetches per-call accepted
Component (7) — LSP server
STRIDE Threat Mitigation Residual --- --- --- --- T Malicious workspace path Path canonicalisation + allowlist accepted I Source-code exfil via diagnostics Diagnostics stream stays local; no network calls without user consent accepted D Large-file scan OOM Streaming parser with file-size cap accepted
Component (8) — CLI
STRIDE Threat Mitigation Residual --- --- --- --- S Token theft from env Prefer OS keychain; fall back to file with 0600 accepted T Exit-code contract abuse Exit-code contract test (G-14 residual) residual
Component (9) — VS Code extension
STRIDE Threat Mitigation Residual --- --- --- --- T Extension supply-chain Publisher verification + signed VSIX accepted I Workspace leakage Opt-in telemetry only; redact paths accepted
---
Highest-residual-risk summary
Ordered by residual risk, what remains open:
Prompt-injection retest (Component 2, I) — pending Garak + curated corpus run (P3.1-PI1). Target ≥ 99% refusal on OWASP LLM Top 10. Quarterly IDOR full-grid fuzz (Component 2, T) — scheduled under P3.1-I1; first run Q2-2026. DB restore drill (Component 3, T) — gate G-4 / P3.3-DR1. External gray-box pentest retest — gate G-8 / P3.2. CLI exit-code contract test — residual from Phase 4 UX list.
Review cadence
Re-review every release (tick the "Threat model reviewed" checkbox in the release PR template). Full re-derivation annually or after any component boundary change.