Threat Model

AWS

Cloud-hosted, with the boundaries a VPC and IAM imply.

Threat Model — AWS: rendered example
Rendered by Gnomon from the source below. No edits.

The source

64 lines of PlantUML, and pulls in C4-PlantUML and Threat modelling. Copy it, or open the template inside Gnomon and render it as it is.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!include <threat/ThreatModel>

LAYOUT_TOP_DOWN()
hide stereotype
skinparam LegendFontColor #334155
skinparam LegendBackgroundColor #F8FAFC
skinparam LegendBorderColor #CBD5E1

AddBoundaryTag("zone_edge", $bgColor="#F3E5F5", $fontColor="#4A148C", $borderColor="#6A1B9A", $borderStyle="solid", $legendText="Our AWS account — public entry points")
AddBoundaryTag("zone_app", $bgColor="#DBEAFE", $fontColor="#1E3A8A", $borderColor="#2563EB", $borderStyle="solid", $legendText="Our AWS account — application runtime")
AddBoundaryTag("zone_data", $bgColor="#FEF3C7", $fontColor="#78350F", $borderColor="#D97706", $borderStyle="solid", $legendText="Our AWS account — protected data services")

title AWS data platform — trust boundaries (C2)

Person(analyst, "Analyst", "Zone 1 — public internet; submits customer datasets")

TrustBoundary(edge, "Zone 2 — Managed edge", "low", $tags="zone_edge") {
  Container(cdn, "Portal Delivery", "Amazon CloudFront", "Serves the portal and routes /api requests", $tags="internet_facing")
  Container(gateway, "Submission API", "Amazon API Gateway", "Validates OIDC tokens and request schemas", $tags="internet_facing+authn_oauth2")
}

TrustBoundary(app, "Zone 3 — Application runtime", "medium", $tags="zone_app") {
  Container(ingest, "Ingest Handler", "AWS Lambda", "Validates submissions; scoped execution role")
}

TrustBoundary(data, "Zone 4 — Protected data services", "high", $tags="zone_data") {
  ContainerDb(store, "Operational Store", "Amazon RDS PostgreSQL", "Customer records; encrypted at rest and audited", $tags="pii+encrypted_at_rest+audit_logged")
  ContainerDb(exports, "Raw Exports", "Amazon S3", "PII extracts; storage protection TBC", $tags="pii")
  ContainerDb(vault, "Credential Store", "AWS Secrets Manager", "Service credentials; access is audited", $tags="secret+audit_logged")
  ContainerQueue(events, "Event Queue", "Amazon SQS", "Ingest events; queue policy TBC")
}

' These are access zones, not a claim that managed services live in a VPC.
Rel(analyst, cdn, "Submits customer datasets", "HTTPS — Z1→Z2", $tags="encrypted")
Rel_R(cdn, gateway, "Routes /api submissions", "HTTPS / OIDC — Z2 internal", $tags="encrypted")
Rel_R(gateway, ingest, "Invokes validated requests", "HTTPS — Z2→Z3; invoke policy", $tags="encrypted")
Rel(ingest, store, "Writes customer records", "SQL — Z3→Z4; transport TBC")
Rel(ingest, exports, "Writes nightly PII extracts", "HTTPS — Z3→Z4; bucket scope TBC", $tags="encrypted")
Rel(ingest, vault, "Reads service credentials", "HTTPS — Z3→Z4; execution role", $tags="encrypted")
Rel(ingest, events, "Publishes ingest events", "HTTPS — Z3→Z4; queue policy TBC", $tags="encrypted")

Lay_R(cdn, gateway)
Lay_R(store, exports)
Lay_R(exports, vault)
Lay_R(vault, events)

legend bottom left
|= Notation |= Meaning |
| <back:#F3E5F5> Zone 2 </back> | Public entry points; low trust |
| <back:#DBEAFE> Zone 3 </back> | Application runtime; medium trust |
| <back:#FEF3C7> Zone 4 </back> | Protected data services; high trust |
| <back:#FEF3C7> Amber data </back> / <back:#E0E7FF> Lilac data </back> | Contains PII / secrets |
| <color:#DC2626>Red element outline</color> | Internet-facing |
| <color:#16A34A>Green flow</color> / grey flow | Encrypted / transport unverified |
endlegend

footer
Solid zones: our AWS account and access configuration. AWS manages the service infrastructure. Zone 1 is implicit.
Zones describe access scopes, not subnets. S3, SQS and Secrets Manager are AWS managed endpoints.
TBC = a control requiring confirmation. Review database transport, export protection and access policies.
end footer
@enduml

Render this offline

This template ships in Gnomon and renders on your machine, with no account and no diagram uploads. The browser editor is free and needs no install.

Get GnomonOpen the browser editor

Others in Threat model diagrams

Analytics cookies (optional)

May we use Google Analytics to understand visits, product links and feature use? If you accept, Google receives usage and device information, including your IP address, and sets analytics cookies. We do not send your documents, filenames or account details. Advertising features are disabled.

Analytics is off until you accept. Your choice is saved on this browser for 180 days using necessary local storage. You can change it at any time in Analytics preferences. Closing this message rejects analytics. Read our privacy policy.