Skip to content

Risk register

This register is broader than the threat model. The threat model is a STRIDE inventory of security threats at boundaries. This register captures product, schedule, cost, operational, supply-chain, and security risks together, with state, mitigations, and ownership.

State legend: Watch = monitored, no action required this stage. Triggered = the leading indicator fired; PM must escalate per the SOP Risk Management Process. Mitigated = control is in place; the risk persists but is reduced to an acceptable level. Accepted = explicitly accepted, no further action. Resolved = the underlying condition no longer applies; risk is closed.

R1. Corpus swap exposes new data class without revalidation

Section titled “R1. Corpus swap exposes new data class without revalidation”
FieldValue
CategorySecurity / data classification
StateWatch
LikelihoodLow (operator-controlled)
ImpactHigh (notifiable-breach class if PII corpus is loaded)
TriggerAny change to the corpus identifier in the ingestion loader or pyproject.toml
Mitigation todayCorpus pinned in code (RAG003). Data classification doc names one class only
Mitigation plannedFeature #66 / #67 add a CI gate that compares the corpus identifier in the loader to the value in data-classification.md
Cross-refThreat model T3; data-classification.md; #66, #67
OwnerSecurity Specialist
FieldValue
CategoryCost / operational
StateWatch — no automated detection; a breach is visible only on deliberate operator review
LikelihoodMedium (any test loop, retry storm, or compromised key)
ImpactMedium (capped by AWS account but personal-budget-painful)
TriggerDaily Bedrock spend over $5/env. Nothing detects this automatically today
Mitigation todayPer-key lifetime request quota (RAG009); Lambda concurrency limit; manual checking. The two hand-created AWS Budgets do not mitigate this: they filter on user:Environment$<env>, and no cost allocation tag is active on the account (aws ce list-cost-allocation-tags --status Active returns empty, verified 2026-08-11), so they match no spend and cannot fire at any threshold. Treat the notification channel as absent, not degraded
Mitigation planned#295 makes the budgets match spend at all: activate the Environment cost allocation tag, then confirm whether on-demand Bedrock usage is attributable per environment (unverified) or whether the filter must move to the service dimension, where Bedrock spend does appear. Story #64 then wires the alarm at $5/env with SNS to operator email — it depends on a budget that can fire
Cross-refRAG007 (Haiku-class selection reduces unit cost); #64, #295; cost.md
OwnerDevOps Lead

R3. Prompt injection via corpus chunks (indirect)

Section titled “R3. Prompt injection via corpus chunks (indirect)”
FieldValue
CategorySecurity
StateWatch
LikelihoodLow today (curated public dataset); high if corpus is swapped
ImpactMedium (off-policy output attributed to product)
TriggerOutput review flags off-template responses; or corpus change
Mitigation todayDelimited retrieved content in prompt; explicit “data not instructions” note
Mitigation plannedCapability #44 Safety Gate; Bedrock Guardrails approved per Decision #55 (closed), gated on #44 entering Stage 3
Cross-refThreat model T1; #44, Decision #55
OwnerSecurity Specialist

R7. Authorization header leak via CloudWatch logs before scrub ships

Section titled “R7. Authorization header leak via CloudWatch logs before scrub ships”
FieldValue
CategorySecurity
StateWatch
LikelihoodHigh during the window between authorizer go-live and Story #62 ship
ImpactHigh (bearer tokens in plaintext in CloudWatch)
TriggerRAG009 stories #59-#63 deploy ahead of #62
Mitigation plannedSequencing: #62 (log scrub) must ship in the same release as #60 (authorizer). PM enforces
Cross-refThreat model; per-feature requirements; #62
OwnerPM + Security Specialist

R8. Supply-chain compromise via Python or Node deps

Section titled “R8. Supply-chain compromise via Python or Node deps”
FieldValue
CategorySecurity / supply chain
StateWatch
LikelihoodLow per-dep, accumulating with surface area
ImpactHigh
Triggerpip-audit or npm audit reports new High/Critical CVE on direct or transitive dep
Mitigation plannedpip-audit and npm audit jobs in CI (non-blocking initially, blocking once baseline is clean). SBOM process per sbom.md
Cross-refsbom.md; #29
OwnerDevOps Lead + Security Specialist
FieldValue
CategoryOperational / developer experience
StateWatch
LikelihoodCertain (already observed)
ImpactLow (productivity drag, no shipping risk)
TriggerAlready triggered for npm install, pip install, dev servers
Mitigation todayVite cache redirected to ext4 (astro.config.mjs)
Mitigation plannedIssue #41 relocates Python .venv to ext4
Cross-ref#41; planning repo CLAUDE.md “Architecture notes”
OwnerOperator
FieldValue
CategorySchedule / delivery
StateWatch
LikelihoodHigh (the gate is a hard-fail)
ImpactLow (intended behavior; surfaces gaps early)
TriggerPR fails pytest --cov-fail-under=90
Mitigation todayCoverage exclusion policy at coverage-exclusions.md
Mitigation plannedQA plans (qa/plan-*.md) call out per-Feature coverage approach; DoD template requires the check pass
Cross-refRAG006; qa/summary.md; dod-template.md
OwnerQA Lead
FieldValue
CategoryDeployment / security
StateWatch
LikelihoodCertain (no issue exists)
ImpactMedium (Stage 4 deploys can’t run without it)
TriggerFirst Terraform apply story enters Stage 4
Mitigation todayOIDC trust policy design documented in deployment-plan.md
Mitigation plannedPM opens a tracking issue under Capability #26; DevOps Lead provisions the role in Stage 4
Cross-refdeployment-plan.md; #25, #29
OwnerPM (to open issue), DevOps Lead (to design)

Risks move here when the underlying condition no longer applies or a control is in place with explicit operator acceptance.

R4. Direct prompt injection via /query body

Section titled “R4. Direct prompt injection via /query body”
FieldValue
CategorySecurity
Initial stateWatch
Current stateMitigated
LikelihoodMedium (any public endpoint receives adversarial inputs)
ImpactLow (same audience as requester for single-tenant demo)
Trigger422 oversized-question rate elevated; output review
MitigationRAG013 prompt-attack filter via ApplyGuardrail before the pipeline runs; question length cap (retrieval spec); RAG009 bearer auth limits caller pool
Cross-refThreat model T2; RAG013
OwnerSecurity Specialist

R5. Aurora Data API access path lacks an ADR

Section titled “R5. Aurora Data API access path lacks an ADR”
FieldValue
CategoryArchitecture / governance
Initial stateTriggered
Current stateResolved
TriggerArchitect-reviewer Stage 3 review §2 flagged it
ResolutionRAG011 written, documenting the public-path access contract and rationale for no Lambda VPC attachment
Cross-refRAG001; RAG011
OwnerSolution Architect (Operator)
FieldValue
CategoryArchitecture / governance
Initial stateTriggered
Current stateResolved
TriggerArchitect-reviewer Stage 3 review §2
ResolutionRAG012 written, covering Vite + React, S3 + CloudFront target, no SSR, and the rationale against Next.js
Cross-refRAG012; #17, #18
OwnerSolution Architect (Operator)
FieldValue
CategorySchedule / scope
Initial stateTriggered
Current stateResolved
TriggerArchitect-reviewer §3 flagged as top gold-plating candidate
ResolutionScope decision made: harness retained under Capability #44 Safety / Quality, scoped to BERTScore + SentenceTransformers with no threshold enforcement. RAG014 records the decision and rejected alternatives
Cross-refRAG014; architect-reviewer §3, §4 item 7; #14, #44
OwnerOperator

This register is updated at every PM Notification trigger and at every stage gate. The Risk Management Process loads at every stage start; Triggered risks escalate immediately to the operator.