All writing

Threat modelling bfstore with STRIDE

A practical STRIDE threat model for bfstore’s checkout and delivery paths. The exercise begins with scope, assets, actors, data flows and explicit trust boundaries before turning threats into prioritised, testable security work.

about 23 minutes min read

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:

  1. What are we working on?
  2. What can go wrong?
  3. What are we going to do about it?
  4. 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.