A customer adds a pink gopher mug to their basket and checks out.
The order service confirms the basket, reserves inventory, creates an order and asks the payment service to begin payment.
Events move through Kafka.
Records are written to MySQL.
A payment provider later sends a webhook.
From the customer’s perspective, this is one action:
Place order
From a security perspective, it is a procession of identities, messages, stores and trust decisions.
CUSTOMER
│
▼
PUBLIC EDGE
│
▼
ENVOY GATEWAY
│
▼
ORDER SERVICE
│
├── basket
├── inventory
├── payment
├── MySQL
└── Kafka
│
▼
PAYMENT PROVIDER
│
▼
WEBHOOK
Each arrow makes an assumption.
The edge assumes the customer’s session is authentic.
The order service assumes the basket belongs to that customer.
Kafka consumers assume an event came from an approved producer and describes a permitted business transition.
The payment service assumes the provider webhook is authentic, fresh and relevant to the referenced order.
The delivery system assumes the deployed image is the artefact that passed review.
Threat modelling makes those assumptions visible before an attacker, outage or hurried administrator tests them on bfstore’s behalf.
AWS frames threat modelling around four questions:
- What are we working on?
- What can go wrong?
- What are we going to do about it?
- Did we do a good job?
The exercise should therefore produce more than a diagram. It should produce prioritised decisions, owners, tests and evidence. AWS Well-Architected threat-modelling guidance
A threat model is an architecture diagram whose assumptions have been asked difficult questions.
STRIDE supplies six families of those questions.
It does not answer them automatically.
Start with the system, not the acronym
A useful threat model moves through these stages:
| Stage | Question | Output |
|---|---|---|
| Scope | What journey or change are we analysing? | Model boundary |
| Model | Which assets, actors, flows and stores participate? | Data-flow diagram |
| Boundaries | Where does trust, control, identity or ownership change? | Explicit assumptions |
| STRIDE | What can go wrong? | Threat statements |
| Risk | What matters first? | Prioritised register |
| Controls | How will risk be reduced? | Prevent, detect and respond controls |
| Verification | How will we prove it? | Tests and evidence |
| Maintenance | What change reopens the model? | Owner and update triggers |
STRIDE belongs mainly inside “What can go wrong?”
Beginning with:
What spoofing threats exist
in cloud applications?
usually produces generic advice.
The system must provide the detail.
STRIDE is a set of prompts
| Category | Property under pressure | Core question |
|---|---|---|
| Spoofing | Authentication | Can something pretend to be someone or something else? |
| Tampering | Integrity | Can data, code or configuration be changed without authorisation? |
| Repudiation | Accountability | Can an actor deny an action without enough trustworthy evidence to investigate it? |
| Information disclosure | Confidentiality | Can information reach someone who should not receive it? |
| Denial of service | Availability | Can legitimate users or components be prevented from making progress? |
| Elevation of privilege | Authorisation | Can an actor gain capabilities beyond those it was granted? |
Microsoft’s threat-modelling guidance uses data-flow diagrams, trust boundaries and STRIDE to identify design risks while they remain cheaper to change. Microsoft Threat Modeling Tool Microsoft data-flow diagrams
The categories overlap.
A forged webhook may involve spoofing and tampering.
An unauthorised service publishing OrderPaid may involve spoofing, tampering or elevation of privilege.
Deleting audit evidence may involve tampering and repudiation.
The category keeps the discussion moving. The actual system provides the threats.
Scope the checkout journey
This first model covers:
Customer places and pays for an order.
Included:
- customer session use and public ingress
- basket, catalog, inventory, order and payment services
- gRPC communication, Kafka and MySQL
- payment-provider calls and webhooks
- workload identity
- build and deployment paths
- relevant audit and telemetry paths
Not analysed in detail:
- the customer’s device
- the payment provider’s internal infrastructure
- AWS physical facilities
- unrelated administration journeys
The provider’s internal systems remain outside bfstore’s control.
The integration boundary remains inside the model.
The identity provider and session-management components are abstracted from the first diagram. They need a related model covering credential issuance, account recovery, token validation, revocation, session storage and signing-key lifecycle.
Identify the assets
The checkout journey protects more than secrets.
| Asset group | Examples | Important properties |
|---|---|---|
| Customer identity | account, session, recovery path | authenticity, confidentiality |
| Personal data | name, email, delivery address | confidentiality, justified use |
| Commercial state | price, discount, basket, inventory, order total | integrity |
| Payment authority | provider tokens, payment references, refund capability | integrity, restricted access |
| Service identity | service accounts, IAM roles, mTLS identities, Kafka credentials | authenticity, authorisation |
| Supply chain | source, dependencies, images, deployment plans | integrity, provenance |
| Availability | checkout, reservation, payment and fulfilment | timely completion |
| Evidence | audit events, logs, traces, CloudTrail and deployment records | integrity, retention |
The product price is intentionally public.
Changing it from £84 to 84 pence without permission is still a security event.
Draw flows and explain each trust boundary
A trust boundary is not simply another hop. It marks a meaningful change in control, identity, ownership or privilege. Microsoft data-flow diagrams
INTERNET
│
TRUST BOUNDARY A
│
▼
ALB / PUBLIC EDGE
│
TRUST BOUNDARY B
│
▼
ENVOY GATEWAY
│
TRUST BOUNDARY C
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
BASKET ORDER CATALOG
│
┌──────┼──────┐
▼ ▼ ▼
INVENTORY MYSQL KAFKA
│
▼
PAYMENT
│
TRUST BOUNDARY D
│
▼
PAYMENT PROVIDER
│
▼
SIGNED WEBHOOK
| Boundary | What changes | Required decision |
|---|---|---|
| A: internet to edge | Uncontrolled callers enter bfstore infrastructure | Is the connection acceptable, bounded and associated with a valid journey? |
| B: edge to gateway | AWS-managed edge processing hands traffic to bfstore workloads | Which forwarded identity and network metadata are trusted? |
| C: gateway to service | An external identity becomes an internal operation | Does the receiving service authorise this action on this resource? |
| Service and store boundaries | Workload identity, ownership and business authority change | May this caller perform this operation or data access? |
| Kafka boundary | A message becomes durable and asynchronously reusable | Which broker identity may publish, and which transitions may consumers accept? |
| D: provider integration | Data leaves bfstore and externally initiated events return | Is the event authentic, fresh, relevant and idempotent? |
The services should not trust one another merely because they run in the same cluster.
NETWORK POLICY
May traffic travel along this path?
WORKLOAD IDENTITY
Which workload is calling?
SERVICE AUTHORISATION
May that identity perform
this operation on this resource?
Kubernetes NetworkPolicy controls supported Layer 3 and Layer 4 paths and requires an enforcing network implementation. It is not workload identity or operation-level authorisation. Kubernetes NetworkPolicy
A second diagram covers delivery:
ENGINEER
│
▼
GITHUB
│
▼
GITHUB ACTIONS
│
├── build and test
├── produce image
├── attest artefact
└── request deployment
│
▼
AWS IAM ROLE
│
▼
TERRAKUBE / KUBERNETES
│
▼
BFSTORE RUNTIME
A model that covers only customer traffic may defend an application that the pipeline can replace with arbitrary code.
Spoofing: who are you really?
Customer session spoofing
An attacker steals or reuses a customer session and places an order as that customer.
Conditions may include:
- tokens in logs
- weak account recovery
- long-lived access
- missing issuer or audience validation
- no revocation after credential changes
Controls may include short-lived access, secure session storage, issuer and audience checks, reauthentication for sensitive operations, revocation and anomaly detection.
Workload spoofing
A compromised Pod calls the order service while claiming to be the payment service.
A private source IP is insufficient identity.
Controls include distinct Kubernetes service accounts, short-lived workload credentials, explicit service authorisation, network segmentation and producer-specific Kafka ACLs.
EKS can provide scoped temporary AWS credentials through IAM roles for service accounts or EKS Pod Identity. The resulting role still needs narrow permissions, and the node credential path still needs protection. EKS IRSA EKS Pod Identity
Payment webhook spoofing and replay
Plausible JSON is not proof that the payment provider sent an event.
The payment service should verify:
- the signature over the exact received payload, using the provider’s supported library or canonicalisation rules
- signed timestamp or equivalent freshness evidence
- unique event identifier and replay window
- event schema and type
- relationship between provider payment reference and bfstore order
- whether the current state permits the transition
A valid signature proves less than many implementations assume. It does not prove that the event is fresh, previously unprocessed, relevant to the named order or permitted to change its state.
PENDING_PAYMENT
│
▼
PAYMENT_AUTHORISED
│
▼
READY_FOR_FULFILMENT
Only permitted, idempotent transitions should succeed.
Tampering: what changed?
Request tampering
A customer changes:
{
"product_id": "product-42",
"quantity": 1,
"unit_price_pence": 1
}
The order service must retrieve or validate authoritative product, discount and pricing data.
The customer may request:
Buy one product-42.
They may not declare:
Product-42 costs one penny.
Event tampering
A malicious or compromised service publishes OrderPaid for an order whose payment failed.
Controls include broker-authenticated producer identities, topic authorisation, schema validation, immutable event IDs, authoritative state checks, idempotent consumers and provider reconciliation.
An envelope field such as:
{
"producer": "payment-service"
}
is only a claim unless tied to broker-authenticated identity or another trusted provenance mechanism.
TLS protects transit.
It does not prove that an authorised producer generated a truthful business event.
Database tampering
Prepared statements protect SQL structure from injection.
They do not stop an over-privileged runtime identity from performing operations it was granted.
Controls include service-owned schemas, separate migrator and runtime accounts, least-privilege grants, database constraints and reconciliation among order, payment and inventory state.
Supply-chain tampering
The delivery path must answer two questions:
WORKFLOW IDENTITY
Which repository, environment
and workflow may request deployment?
ARTEFACT IDENTITY
Which exact digest was reviewed,
built, attested and approved?
GitHub Actions can use OIDC to obtain short-lived AWS credentials. The AWS trust policy should constrain audience and subject claims, including the expected repository and protected environment or branch. GitHub recommends environment protection rules where environments are used. GitHub OIDC for AWS
OIDC trust does not prove that the correct artefact is deployed.
Use immutable image digests and verify build provenance or attestations before deployment. GitHub artefact attestations can bind a build to its repository, workflow, commit and digest, but only verification gives the attestation operational value. GitHub artefact attestations
The dangerous request may not enter through the ALB. It may arrive as a valid deployment issued by an unexpectedly powerful workflow.
Repudiation: prove enough to investigate
Repudiation appears when an actor denies an action and the system lacks enough trustworthy evidence to reconstruct it.
A useful application audit event records:
event:
type: order.refund_requested
event_id: audit-91c4
occurred_at: 2026-06-24T11:14:32Z
actor:
type: customer
subject_id: customer-421
session_reference: session-72a1
execution:
workload_identity: order-service
policy_decision: refund-owner-check
resource:
type: order
id: order-8042
outcome:
decision: accepted
amount_pence: 4200
correlation:
trace_id: 6d2c4e1f
An audit event may contain an opaque session reference.
It must not contain a bearer token, refresh token or another reusable credential.
CloudTrail can provide AWS control-plane and configured data-event evidence. Its usefulness depends on enabled event sources, destinations, retention and protection against alteration. Management events are generally enabled for trails, while data events require explicit configuration. CloudTrail overview CloudTrail management events CloudTrail data events
bfstore must still create application-level evidence for business actions.
Logs should be centralised with narrow write paths, restricted deletion, access auditing, retention and integrity controls.
They provide evidence whose strength depends on the complete logging path.
Information disclosure: where did the data travel?
Sensitive data can escape through error responses, telemetry, Kafka, support exports, environment variables, broad queries or compromised workload identities.
Telemetry
A payment failure should not log:
customer=mariam@example.com
address=42 Example Road
token=pm_secret_value
Use structured logging, field allow-lists, token redaction, no raw request bodies by default, purpose-based retention and tests for sensitive-field leakage.
Customer IDs, emails and order IDs should not become metric labels merely because labels are convenient.
Events
An OrderCreated event should contain what its consumers need, not a travelling copy of the customer profile.
message OrderCreated {
string event_id = 1;
string order_id = 2;
string customer_id = 3;
int64 total_pence = 4;
}
A shipping workflow may need a delivery address through a narrow path.
A recommendation consumer probably does not.
Event schemas are disclosure boundaries.
Secrets and encryption
Kubernetes recommends encryption at rest, least-privilege access and limiting Secret visibility to the containers that need it. Base64 is not protection. Kubernetes Secrets
AWS KMS encryption context can bind non-secret context to ciphertext and support policy conditions and auditability. It appears in plaintext, so it must not contain customer or secret values. AWS KMS encryption context
Encryption reduces the value of unauthorised storage access.
It does not excuse over-collection or broad decryption permission.
Denial of service: can legitimate work finish?
STRIDE draws attention to loss of availability.
The cause may be hostile, accidental or external. The threat record should state which cause it analyses because security and resilience controls may differ.
Abuse and cost amplification
Threats include request floods, expensive searches, oversized bodies, baskets with thousands of items and repeated checkout calls.
Controls include rate and connection limits, request-size limits, bounded input collections, caching and inexpensive rejection before expensive work.
VALID TYPE
does not automatically mean
SAFE AMOUNT OF WORK
Retry storms
A slow provider can be multiplied by retries from callers, consumers and redelivery.
Use deadlines, bounded retries, backoff and jitter, concurrency limits, circuit breakers, idempotency, dead-letter handling and load shedding.
Platform exhaustion
Kafka may suffer oversized messages, hot partitions, lag or poison-message loops.
A compromised workload may consume shared CPU, memory or Pod capacity.
Use topic limits, ACLs, lag monitoring, resource requests and limits, LimitRange, ResourceQuota and controlled failure testing.
External dependency failure
The storefront may be healthy while the payment provider is unavailable.
That may result from ordinary failure, overload, network partition or attack.
The model should name the assumed cause and consider bounded queueing, explicit delayed states, reconciliation, alerting and provider failover where realistic.
Availability is end to end.
A green Pod is not proof that a customer can place an order.
Elevation of privilege: what can this identity become?
Customer to administrator
An ordinary customer manipulates an endpoint or claim and invokes an administration operation.
The control must be server-side authorisation tied to trusted identity.
Hiding the button is interface design, not access control.
Service to broader authority
The notification service may send messages.
It does not need to refund payments, modify inventory, decrypt customer profiles or publish OrderPaid.
Workload roles, database accounts and Kafka ACLs should match narrow service functions.
Pod to node or cluster authority
A compromised Pod may exploit an over-privileged service account, mounted credentials, host access, Linux capabilities or node credentials.
Kubernetes defines Privileged, Baseline and Restricted Pod Security Standards. Pod Security Admission can enforce, audit or warn against a version-pinned profile at namespace level. Pod Security Standards Pod Security Admission
bfstore application namespaces should target a version-pinned restricted posture unless a reviewed exception is required.
Additional bfstore hardening, such as read-only filesystems, narrow token use and workload-specific egress, should be distinguished from the controls defined by the standard itself.
Kubernetes RBAC must also account for indirect escalation through access to Secrets, workload creation, role bindings and certificate-signing operations. Kubernetes RBAC good practices
A deployment controller may need to update Deployments and read rollout status.
It probably does not need to read every Secret or create ClusterRoleBinding objects.
CI/CD to production authority
The GitHub OIDC trust relationship should restrict which workflow context can assume the production role.
The role itself should then permit the smallest useful deployment operation.
Deployment automation does not need to become an unrestricted production administrator.
Write precise threat statements
A useful threat statement follows this structure:
An actor
can perform an action
through a particular path
because a condition exists
causing a business or technical impact.
For example:
An attacker can replay a previously valid
payment webhook through the public endpoint
because bfstore validates the signature but
not the event identifier or timestamp, causing
duplicate state transitions and incorrect fulfilment.
This is more reviewable than:
Threat: webhook spoofing
Mitigation: encryption
Score inherent and residual risk
Priority labels need defined meaning.
| Dimension | Questions |
|---|---|
| Likelihood | How exposed is the path? Which precondition is required? How difficult is repeatable exploitation? |
| Impact | Could this cause financial loss, unauthorised fulfilment, customer harm, material disclosure or prolonged outage? |
| Current controls | Which implemented and verified controls already reduce likelihood or impact? |
| Residual risk | What remains after those controls are considered? |
CRITICAL
Mitigate, redesign or formally
accept before release.
HIGH
Assign an owner, delivery date
and tracked verification.
MEDIUM
Track and review against
planned architecture changes.
LOW
Document and reconsider when
assumptions or exposure change.
A threat record should separate untreated risk from what remains after current controls.
threat:
id: BF-THREAT-014
title: Replay of payment-success webhook
stride:
- spoofing
- tampering
scenario:
actor: external-attacker
entry_point: payment-webhook
asset: order-payment-state
precondition: valid signed webhook captured
risk:
inherent:
likelihood: high
impact: high
priority: critical
current_controls:
- provider signature verification
planned_controls:
- verify signed timestamp
- reject events outside replay window
- enforce unique provider event ID
- match provider payment reference
- enforce idempotent state transition
residual_risk:
likelihood: low
impact: high
priority: medium
verification:
- replay the same signed event
- replay an expired event
- submit a valid event for the wrong order
- attempt an invalid state transition
A planned control should not lower residual risk until it exists and has evidence.
A first threat register
| ID | STRIDE | Threat | Inherent priority |
|---|---|---|---|
| BF-01 | Spoofing | Stolen customer session used to place an order | High |
| BF-02 | Spoofing / Tampering | Forged or replayed webhook changes order state | Critical |
| BF-03 | Tampering | Client-supplied price accepted at checkout | Critical |
| BF-04 | Spoofing / Tampering | Unauthorised producer publishes OrderPaid |
Critical |
| BF-05 | Repudiation | Refund or price change lacks reliable actor evidence | High |
| BF-06 | Disclosure | Personal or payment data enters telemetry | High |
| BF-07 | Disclosure / Elevation | Workload reads another service’s secrets or data | Critical |
| BF-08 | Denial of service | Retry storm exhausts checkout capacity | High |
| BF-09 | Denial of service | Oversized input creates disproportionate work | Medium |
| BF-10 | Elevation | Compromised Pod obtains node or broad AWS credentials | Critical |
| BF-11 | Elevation | Unapproved workflow assumes production role | Critical |
| BF-12 | Tampering | Unverified container digest reaches production | Critical |
| BF-13 | Disclosure | Kafka event contains unnecessary customer data | High |
| BF-14 | Denial of service | Kafka exhaustion prevents order progression | High |
| BF-15 | Tampering / Repudiation | Workload account can alter audit evidence | High |
Each record still needs an owner, assumptions, current controls, residual risk, verification evidence and review trigger.
A Critical row should cause one of four outcomes:
MITIGATE
REDESIGN
TRANSFER
FORMALLY ACCEPT
“Discussed during threat modelling” is not a fifth treatment.
Prevent, detect, respond and verify
One threat usually needs several controls.
For replayed payment events:
| Control class | Examples |
|---|---|
| Prevent | exact-payload signature verification, freshness checks, unique IDs, payment-reference matching, idempotent transitions |
| Detect | duplicate-event metrics, reconciliation, impossible-transition alerts, complete audit events |
| Respond | suspend fulfilment, quarantine affected orders, query provider state, preserve evidence |
AWS recommends adapting controls to prevent, detect and respond rather than relying on one layer. AWS Well-Architected threat-modelling guidance
Every mitigation should produce a test or evidence requirement.
Examples include:
- use expired and wrong-audience customer tokens
- call a service using another service’s identity
- replay a correctly signed webhook
- alter a client-supplied price
- publish from an unauthorised Kafka principal
- deploy a mutable tag or unattested digest
- reconstruct a refund from application and infrastructure evidence
- scan telemetry for seeded personal data
- attempt a privileged Pod deployment
- introduce dependency latency and observe retries
- verify an unapproved branch cannot assume the production role
A model without verification can become a thoughtful list of controls that everybody assumes somebody else implemented.
Keep the model attached to delivery
A pull request introducing a new flow should answer:
What new asset exists?
Which actor can reach it?
Which boundary changed?
Which data crosses it?
What can go wrong?
Which controls and tests accompany it?
Reopen the model for changes such as:
- new public endpoints or Kafka topics
- new providers or customer-data fields
- new account connections or workload identities
- new controllers or CI/CD permissions
- changes to authentication, payments, refunds, exports or backups
- incidents that expose a false assumption
A stored model might contain:
docs/security/
├── checkout-threat-model.md
├── checkout-data-flow.txt
├── threat-register.yaml
├── assumptions.md
└── verification/
├── webhook-replay.md
├── workload-identity.md
└── audit-evidence.md
The goal is to keep the reasoning attached to the system as it changes.
The mental model
BFSTORE JOURNEY
│
▼
SCOPE, ASSETS, ACTORS
│
▼
FLOWS, STORES AND BOUNDARIES
│
▼
STRIDE
│
▼
THREAT STATEMENTS
│
▼
INHERENT RISK AND CURRENT CONTROLS
│
▼
PREVENT, DETECT, RESPOND, VERIFY
│
▼
RESIDUAL RISK
│
▼
OWNER, EVIDENCE, REVIEW
│
└──────────► MODEL UPDATE
The recurring questions are:
What journey or change are we modelling?
Which assets and actors participate?
Where does trust, control,
identity or ownership change?
What can go wrong at each boundary?
Which controls prevent,
detect and contain it?
What evidence proves
those controls work?
A trust boundary is where bfstore stops accepting one promise on appearance and requires evidence before making the next decision.
That evidence may be a validated token, workload identity, authorised network path, fresh signed webhook, broker-authenticated principal, database constraint, immutable image digest, verified build provenance, narrow IAM role, protected audit record or tested rate limit.
Threat modelling does not make the system invulnerable.
It makes the security reasoning visible enough to challenge, implement, test and improve.
The attacker should not be the first person to notice where bfstore trusted the wrong thing.
References and further reading
Reviewed against official documentation on 31 July 2026.
- AWS Well-Architected: Identify threats and prioritise mitigations using a threat model
- AWS Well-Architected Security Pillar
- Microsoft Threat Modeling Tool overview
- Microsoft data-flow diagram guidance
- Kubernetes NetworkPolicy
- Kubernetes Pod Security Standards
- Kubernetes Pod Security Admission
- Kubernetes RBAC good practices
- Kubernetes Secrets
- Amazon EKS IAM roles for service accounts
- Amazon EKS Pod Identity
- AWS CloudTrail overview
- AWS CloudTrail management events
- AWS CloudTrail data events
- AWS KMS encryption context
- GitHub Actions: Configuring OIDC in AWS
- GitHub Actions artefact attestations