← Back to Blog

Security Compliance in Simple English

Part 2: STRIDE Threat Modeling for SOC 2 and CASA

Security Threat Modeling SOC 2

In Part 1 we looked at ISO 27001, SOC 2, GDPR and CASA. They all ask a similar question: do you know how your system can be attacked, and what did you do about it? STRIDE is a simple way to answer it, and to leave behind the evidence an auditor wants to see.

STRIDE is not required by SOC 2 or CASA. It is a practical method that produces the risk records and secure-design proof they look for.

Where STRIDE Fits

SOC 2 and CASA are the exam. STRIDE is the study plan. You use it early, at design time, to find problems while they are cheap to fix. Then your controls and your records become the answers.

Where STRIDE fits: design, controls, evidence, audit1 Designfind threatswith STRIDE2 Controlsfix them withreal controls3 Evidencesave proof:tickets, logs4 AuditSOC 2 or CASAreviews it
The method

Learn STRIDE

What the six threats are, and how to run a short session with your team.

What it is · How to run it

01

What STRIDE Is

“Six questions for every part of the system.”

STRIDE is a threat modeling checklist from Microsoft. Its name is the first letter of six threat types. For each part of your system you ask: "Could an attacker do this?"

The six STRIDE threats and the security property each one breaksSSpoofingbreaks: authenticationTTamperingbreaks: integrityRRepudiationbreaks: accountabilityIInfo disclosurebreaks: confidentialityDDenial of servicebreaks: availabilityEElevation of privilegebreaks: authorization
LetterThreatPlain meaningExampleTypical fix
SSpoofingPretending to be someone elseUsing a stolen login tokenStrong login, MFA, short sessions
TTamperingChanging data you should not changeEditing a request to change a priceInput checks, signatures, access limits
RRepudiationDenying you did somethingAn admin deletes data and no log shows itAudit logs that cannot be edited
IInformation disclosureLeaking dataAn API returns other users' emailsEncryption, access checks, less data
DDenial of serviceMaking the service unavailableFlooding the login endpointRate limits, queues, autoscaling
EElevation of privilegeGetting more access than allowedA normal user reaches admin featuresRole checks on every request

Each letter breaks one security property: authentication, integrity, accountability, confidentiality, availability, authorization. That makes it easy to link each threat to a control.

↑ Back to contents
02

How to Run a Session

“Draw, ask, rank, fix, record.”

You do not need special tools. A whiteboard and an hour are enough for the first round.

STRIDE workflow: draw, mark boundaries, apply STRIDE, rank, fix, record1 Drawdata flowdiagram2 Marktrustboundaries3 ApplySTRIDE toeach part4 Rankby risk:H, M or L5 Fixadd acontrol6 Recordsave theevidence
  1. Draw a data flow diagram: users, services, databases, and the arrows between them.
  2. Mark trust boundaries. A boundary is a line where the level of trust changes, such as the internet to your backend, or your backend to a vendor.
  3. Apply STRIDE to each part. The table below shows which letters usually apply.
  4. Rank each threat as high, medium or low.
  5. Fix the threat with a control, or accept it and write down why.
  6. Record the result and link it to tickets and tests.

Which letters apply to which part

PartWhat it isSTRIDE threats that usually apply
External entityA user or another system you do not controlS, R
ProcessCode that does work, like an API or a workerS, T, R, I, D, E
Data storeA database, a bucket, a cacheT, I, D (and R if it holds logs)
Data flowData moving between two partsT, I, D

A simple risk ranking

RiskMeaningWhat to do
HighEasy to attack and a big impact (for example all user data)Fix before launch
MediumHarder to attack, or a smaller impactFix soon, with a date
LowHard to attack and a small impactAccept it, and write down why
↑ Back to contents
Practice

Worked Examples

Three small apps with three different shapes. Each one has a diagram, a threat table, and fixes you can copy. A fourth card follows one threat all the way to the evidence.

Gmail summarizer · File sharing · Payment webhooks · One threat end to end

ExampleWhat it isWhy it is useful to studyLetters you will see most
1. Inbox SummarizerWeb app that reads Gmail and summarizes it with AINeeds both SOC 2 and CASA. Has OAuth and AI risksS, E, I
2. File Sharing AppUsers upload files and share linksStorage, untrusted files and links that leave your trust boundaryI, T, D
3. Payment WebhooksReceives billing events from a payment providerA public endpoint that trusts outside messagesS, T
03

Example 1: Inbox Summarizer

“An app that reads Gmail.”

Imagine a web app called Inbox Summarizer. Users connect their Gmail, and the app uses AI to summarize their email. It needs a Gmail restricted scope, so it will need CASA. Business customers will also ask for SOC 2.

Step 1 and 2: draw it and mark the boundary

Data flow diagram of the Inbox Summarizer app with a trust boundary around the backendUserbrowserS · Ryour backend (trust boundary)Web API+ AI stepS T R I D EDatabasetokens + dataT · IGmail API(Google)S · IHTTPSqueryOAuth + HTTPSletters = STRIDE threats to check for each part

Step 3 to 5: threats, fixes and ranks

IDPartTypeThreatFixRisk
T1Web APISAttacker reuses a stolen session cookieSecure, HttpOnly and SameSite cookies, new session ID at login, server-side revocation, idle timeout (MFA at login does not stop a stolen cookie)Medium
T2Web APIEA user changes an ID in the URL and reads another user's summariesCheck the owner on every request, add a testHigh
T3DatabaseIGmail refresh tokens leak from the database or a backupEncrypt tokens with a managed key, limit DB access, never log tokensHigh
T4DatabaseTSomeone edits summary rows directlyLeast-privilege DB roles, audit trail, approved changes onlyMedium
T5Web APIRAn admin reads a user's data and no record existsLog every admin action in append-only storage.Medium
T6Web APIDA flood of requests uses up the server and the AI budgetPer-user rate limits, a queue, budget alertsMedium
T7Gmail API flowSA fake redirect steals the OAuth codeExact redirect allowlist, state value, PKCEHigh
T8Web API + AIT, IText inside an email tricks the AI into leaking dataTreat email text as untrusted, give the model only that user's data, limit the tools it can call, do not auto-render model-written links or images, ask the user to confirm actionsHigh

Look at how the table reads like a to-do list. Every row has a fix and a rank. That is exactly what an auditor wants: risks that are found, rated and followed to the end.

↑ Back to contents
04

Example 2: File Sharing App

“Untrusted files and shared links.”

A team app where people upload files and share them with a link. The new risk here is untrusted files and links that leave your system.

Data flow diagram of a file sharing app with storage, a scan worker and an external link recipientUserbrowserS · Ryour cloud (trust boundary)Web API(uploads)S T R I D EObject storagethe filesT · I · DScan workerchecks filesT · D · ELinkrecipientS · IHTTPSuploadnewsigned linkletters = STRIDE threats to check for each part

The dashed line is the trust boundary. A person who opens a shared link is outside it, so if a setting is wrong, every file they can reach is exposed.

IDPartTypeThreatFixRisk
D1Object storageIA public bucket or guessable file URLs expose private filesPrivate bucket by default, short-lived signed URLs, random file IDsHigh
D2Web APIEA viewer-role user calls the delete or share endpointRole check for each action, one test per roleHigh
D3Object storageTSomeone uploads a malicious file (malware, or HTML that runs script when opened)Check type by content, serve files from a separate domain with Content-Disposition: attachment and X-Content-Type-Options: nosniff, run the scan workerHigh
D4Scan workerDA huge file or zip bomb uses up the workerSize limits, timeouts, a sandboxed workerMedium
D5Signed linkIA link is forwarded and a stranger opens itExpiry time, optional login, view historyMedium
D6Web APIRA user shares a file outside the company and denies itLog every share with user, time and recipientMedium
D7Scan workerEA parser bug lets a file reach the worker's cloud permissionsLeast-privilege role, no network except storageMedium

What is different from Example 1

  • The big risks are information disclosure (a wrong link or bucket setting) and tampering (a bad file).
  • One config setting (a public bucket) can break everything. Put the setting and a check for it in your evidence.
  • For CASA, uploads fall under data validation: limit them to expected file types, and make sure uploaded content cannot run by itself.
↑ Back to contents
05

Example 3: Payment Webhooks

“A public endpoint that must be trusted.”

Your app receives events from a payment provider, such as "invoice paid". The endpoint is public, and you must trust what arrives. This is a small system, but spoofing and replay are classic problems.

Data flow diagram of a payment webhook: provider and attacker send events to an endpoint, a queue, a billing worker and a databasePaymentproviderS · TAttackerfake senderfake eventsyour backend (trust boundary)S · T · I · DWebhookendpointT · DQueueeventsT · R · EBillingworkerSigningsecretIDatabaseplans, invoicesT · IHTTPSOKeventupdateverifyletters = STRIDE threats to check for each part

The red dashed arrow is an attacker pretending to be the payment provider. The only thing that tells the two senders apart is the signature, which the endpoint checks with the signing secret.

IDPartTypeThreatFixRisk
W1WebhookSAn attacker posts a fake "payment succeeded" eventVerify the provider's signature on the raw body, with the provider's library or a timing-safe compareHigh
W2WebhookTThe event body is changed on the waySignature over the exact bytes, HTTPS onlyHigh
W3WebhookTAn old valid event is sent again (replay)Check the timestamp, store event IDs, ignore duplicates. Events can also arrive out of order, so check the current stateMedium
W4BillingEAn event for account A upgrades account BFind the account from the stored provider customer ID, not from free textHigh
W5WebhookIThe signing secret ends up in code or logsSecrets manager, rotation, never log the signing secretHigh
W6QueueDAn event flood or retry stormReply fast, queue the work, add a dead-letter queueMedium
W7BillingRA plan changes and nobody can say whySave the event ID with every plan changeMedium

What is different from Example 1

  • There are no user logins here. The proof of who is calling is a signature, so spoofing (S) is about the signature check.
  • The rule of thumb: do not act on an event you did not verify.
  • For SOC 2 this supports CC6 (access) and CC7 (monitoring). Failed signature checks are a good alert.
  • CASA has no webhook-specific section, so follow your provider's own webhook guide.
↑ Back to contents
06

Follow One Threat to the End

“From the model to the proof.”

A threat model is only useful if the fix is proven. Here is one row, T2 from Example 1, followed from the model to the evidence. In T2 a user changes an ID in the URL and reads another user's summary. Security people call this an IDOR (insecure direct object reference).

StepWhat you doWhat you save (evidence)
1. ThreatRow T2 in the threat model, rated HighThe threat model file, with date and owner
2. TicketCreate SEC-114 with a clear done conditionLink to the ticket
3. FixPull request with a code review and approvalLink to the merged PR and its approval
4. TestAdd an automated test that runs in CILink to the CI run that passes
5. RecordMark T2 as done in the model with the linksUpdated model and review log entry

The fix

// Before: any signed-in user can read any summary by guessing the ID
app.get('/summaries/:id', auth, async (req, res) => {
  res.json(await db.summaries.findById(req.params.id));
});

// After: the query is limited to the signed-in user's own rows
app.get('/summaries/:id', auth, async (req, res) => {
  const row = await db.summaries.findOne({
    id: req.params.id,
    ownerId: req.user.id,
  });
  if (!row) return res.status(404).end();   // same answer for "missing" and "not yours"
  res.json(row);
});

The test

test('owner can read a summary, another user cannot', async () => {
  const summary = await createSummary(userA);

  const own = await api.as(userA).get(`/summaries/${summary.id}`);
  expect(own.status).toBe(200);
  expect(own.body.id).toBe(summary.id);

  const other = await api.as(userB).get(`/summaries/${summary.id}`);
  expect(other.status).toBe(404);
});

The code returns the same 404 for "not found" and "not yours", so an attacker cannot learn which IDs exist. The test has two halves on purpose: the first proves the endpoint works for the owner, so a route that returns 404 for everyone cannot pass.

Where this one threat counts

FrameworkWhere this one threat counts
SOC 2CC3.2 (risk found and rated), CC6.3 (least privilege), CC8.1 (reviewed change)
CASAAccess control (IDOR). Your test is supporting evidence. The lab runs its own test cases, and under AL1 you submit evidence for each one
ISO 27001Access control and secure development controls
GDPRArticle 32 security, and Article 25 Privacy by Design: users cannot see other people's data

One small row gave you proof for three or four frameworks. Do this for every high-risk threat and your evidence folder fills up with real, dated records.

↑ Back to contents
The payoff

Use It for SOC 2 and CASA

Map each threat to the controls and tests that auditors and labs expect, and keep the proof.

SOC 2 · CASA · Evidence

07

Using STRIDE for SOC 2

“Show that you find and rate risks.”

SOC 2 does not ask for STRIDE. It asks whether you identify and assess risks (CC3). In a Type II report, the auditor then tests whether your controls worked over the whole period. A threat model does not replace the company-wide risk assessment, which auditors usually expect as a risk register that management reviews every year. But it is the detailed input to that register, and every STRIDE letter points to controls you already need.

STRIDESOC 2 criteria it supportsWhat an auditor may ask to see
S SpoofingCC6.1, CC6.2 (logical access)MFA settings, SSO setup, the user list
T TamperingCC6.1, CC6.7 (data in transit), CC8.1 (change management)Branch protection, code review records, TLS settings
R RepudiationCC7.2, CC7.3 (monitoring and evaluating events)Log samples, alert rules, retention policy
I Info disclosureCC6.1, CC6.7, C1.1 (if Confidentiality is in scope)Encryption settings, key management, data classes
D Denial of serviceA1.1, A1.2 (if Availability is in scope), CC6.6 (threats from outside)Rate-limit config, capacity monitoring, recovery tests
E Elevation of privilegeCC6.1, CC6.3 (roles and least privilege)Role definitions, access review records

Where the threat model itself is evidence

SOC 2 areaHow the threat model helps
CC3.2 Identify and analyze risksFeeds your company risk register. The threat models are the detailed input for your software risks.
CC3.4 Assess changes that affect riskUpdate it when the design changes, such as a new vendor or a new data type.
CC8.1 Change managementEach major change has a short threat review linked in the pull request.
CC5.1 Control activities that mitigate risksEach high risk has an owner, a fix and a date.
Criteria numbers follow the 2017 Trust Services Criteria. Only the Security criteria (the common criteria, CC) are always in scope. The A1 (Availability) and C1 (Confidentiality) rows apply only if you chose those categories. Confirm the mapping with your auditor, because each firm tests slightly different things.
↑ Back to contents
08

Using STRIDE for CASA

“Fix it before the lab finds it.”

CASA does not ask for STRIDE either, and its own v2 specification has no threat-modeling requirement. (OWASP ASVS, which CASA builds on, does ask for threat modeling at its higher levels.) The lab tests your app against the CASA specification. The best way to pass is to find and fix those problems before the lab does, and a threat model is a good way to do that.

The table maps each STRIDE letter to the CASA areas. Notice that CASA is narrower than STRIDE: it says little about audit logging or denial of service, so Repudiation and Denial of service matter more for SOC 2 than for CASA.

STRIDECASA areaWhat to test before the lab does
S SpoofingAuthentication, Session management, OAuth rulesLogin limits, cookie flags (Secure, HttpOnly), logout, OAuth redirect_uri and state, PKCE
T TamperingData validation, Access control, Token protectionInjection and XSS tests, uploads, forged or replayed tokens
R RepudiationLogging rules (no credentials in logs)Logs never contain passwords or tokens. (Audit trails are a SOC 2 matter)
I Info disclosureCommunications, Server-side secrets, No tokens in URLsTLS settings, secret storage, token encryption, no sensitive data in URLs
D Denial of serviceBrute-force resistance, Anti-automationLogin rate limits. (Wider availability is a SOC 2 matter)
E Elevation of privilegeAccess control: least privilege, IDOR, admin MFAOwner checks, role checks, IDOR tests, MFA on admin pages

How to use it for CASA

  1. Run the STRIDE session for the app, with the Google data flow on the diagram.
  2. Use the table above to turn each high-risk threat into a test.
  3. Run your own scans and tests. Fix the findings.
  4. Keep the reports. Under AL1 you hand your evidence to the lab. Under AL2 the lab tests the app itself. Keep everything for the renewal, which is at least every 12 months.
CASA is updated from time to time. Check the current spec and the assurance level Google gives your app before you plan.
↑ Back to contents
09

Turning Threats into Evidence

“If it is not written down, it did not happen.”

A threat model on a shared drive proves little. Auditors want to see the whole chain: threat, ticket, fix, test, proof.

Evidence chain: threat, ticket, fix, test, evidence1 Threatnamed in thethreat model2 Tickettracked inyour backlog3 Fixpull requestwith review4 Testautomated ormanual test5 Prooflink anddate savedrepeat for every major change
Save thisWhySOC 2CASA
The threat model document, with a date and an ownerShows you assess risks on purposeCC3Not required by CASA
Tickets for each threat, linked to the fixShows risks are followed to the endCC3, CC5Fixes before the LOA
Pull requests with review and a security noteShows change managementCC8Validation and configuration
Test results (scans, IDOR tests, pen test)Shows the fix worksCC4, CC7AL1 evidence
Config exports with timestamps (MFA, TLS, encryption). Screenshots only as a backupType II samples across the whole period, so one undated screenshot proves littleCC6Access control, communications
Review log: when you re-checked the modelShows the process repeatsCC3.4, CC4Yearly renewal

A folder layout that keeps evidence easy to find

security/
├── threat-models/
│   ├── inbox-summarizer-2026-10.md     (the model above)
│   └── diagrams/
│       └── inbox-summarizer-dfd.png
├── evidence/
│   ├── 2026-10-mfa-settings.png
│   ├── 2026-10-idor-test-report.pdf
│   └── 2026-11-casa-scan-report.pdf
└── reviews/
    └── review-log.md                   (dates of every re-check)

A template for the threat model file

# Threat model: Inbox Summarizer
Owner: <name>       Date: 2026-10-25       Next review: 2027-04-25
Scope: web app, API, database, Gmail API flow

## Diagram
(link to the data flow diagram, with trust boundaries)

## Threats
| ID | Part     | STRIDE | Threat                       | Fix                          | Risk | Ticket   | Status |
|----|----------|--------|------------------------------|------------------------------|------|----------|--------|
| T2 | Web API  | E      | User reads another's summary | Owner check on every request | High | SEC-114  | Done   |

## Accepted risks
- <risk>: <why we accept it>, approved by <name> on <date>

## Review log
- 2026-10-25: first version
↑ Back to contents

Common Pitfalls

Quick Answers

QuestionAnswer
Is STRIDE required by SOC 2 or CASA?No. Neither names it. It is one good way to meet their risk and secure-design needs.
How long does a session take?A short meeting with a developer, someone who knows security, and the product owner.
When do I run it?At design time, before big changes, and at least once a year.
Does it replace a pen test?No. The model finds design problems. A pen test and the CASA scan find implementation bugs.
Does it cover privacy?Only partly. Privacy threats need their own method, such as LINDDUN.

Takeaways

Back to Part 1: ISO 27001, SOC 2, GDPR and CASA.