← All playbooks

API data exposure: the login was valid. The data access wasn’t.

36 decisions to contain API data exposure, preserve evidence, scope records and people, repair authorization and verify recovery. Visual maps, KQL/Splunk and response templates.

Incident period: Reusable response guide · reviewed October 2026Sources checked: 16 Oct 2026

30-second briefing

What this covers
A reusable API data exposure playbook with 36 decisions across triage, evidence, authorization boundaries, containment, data scope, wider impact, repair, communication and recovery. Includes object-level and field-level access, exports, caches and legacy routes.
Who should act
IT Operations · SIEM · Legal / Privacy · Third-party Risk
First action
Preserve the smallest useful evidence while restricting the affected data-returning operation; assign the API owner and incident lead, and verify that alternate routes and existing access cannot bypass containment.
Uncertainty to keep in mind
A valid login or HTTP 200 does not establish authorized disclosure. Gateway logs alone may not show which records or fields were returned; missing object-level evidence must remain an explicit scope limitation.
API data exposure: authentication can succeed while authorization to another customer's data must fail. Contain, scope, repair and verify.
THE POSTURE QUESTION

Can you show which caller was allowed to read which records and fields—and prove the same unauthorized access fails after the repair?

A successful login can still lead to a data breach

A customer signs in correctly. The API accepts the session. Then a request returns someone else's profile, a field the caller must not see, or a whole customer export. Authentication succeeded; the decision about what that caller may read failed.

This original SecOpsNomad API data exposure playbook contains 36 decisions across nine response stages. Use it for suspected unauthorized reads, excessive field disclosure, exports and related writes through REST, GraphQL, mobile, partner and internal APIs. Anonymous access and stolen credentials are also possible; the title describes one important case, not every incident. Adapt the guide to your own authorization model and telemetry.

Nine response stages: triage, evidence, mechanism, containment, scope, wider impact, repair, communication and verified recovery. Unknown answers remain assigned investigation tasks.

Original response map. Containment starts as soon as needed; evidence, scope and communication continue in parallel. The numbered stages organize the work rather than impose a waiting order.

Start here: the first hour

Time target Action Evidence of completion
0–5 minutes Open a case; name the incident lead, API owner and emergency change owner. UTC discovery time, contacts and affected operation.
5–15 minutes Preserve the smallest proof and restrict the leaking operation. Run these tasks in parallel. Restricted evidence reference, control and deployment time.
10–25 minutes Check mobile, partner, old-version and direct-origin bypasses, plus pending exports. Route inventory with tested containment outcomes.
15–35 minutes Preserve existing edge, application, identity and data-access logs before expiry. Export manifest, retention and sampling gaps.
25–45 minutes Separate credentials, object/tenant access, fields and bulk-function failures. Demonstrated mechanism and open hypotheses.
35–60 minutes Start the scope ledger; bring in Privacy and the business owner; issue the first status update. Confirmed versus potential scope, owners and next update time.

These are coordination targets, not deadlines that justify delaying urgent action. Do not download the full dataset to prove the issue, paste bearer tokens into a ticket, or test a named company's live API. Use owned synthetic accounts and records under an agreed test plan. Do not treat a quieter graph after an IP block as proof of containment.

Preparation, owners and decision rules

Before an incident, keep an inventory of operations, versions, hostnames, direct origins, owners, data stores, partner dependencies and exports. Maintain an authorization matrix and negative tests, emergency restriction/fallback procedures, and logs sufficient to join a trusted principal to a request and the objects emitted. Know which services sample or omit events.

  • Yes: perform the action and continue the other applicable checks.
  • No: record the evidence, time window and coverage that support the answer.
  • Unknown: assign an owner, a next check time and proportionate interim containment. Missing logs are not a no.
  • Not applicable: explain why and name the reviewer.

Record the case ID, operation/version, environment, UTC window, answer, evidence link, action and result, owner and review time. Store raw evidence privately. Download the 36-decision working register (CSV). Its blank columns are for case use; treat later spreadsheet input as untrusted text.

Responsibility Lead role Small-team equivalent
Coordinate, escalate and authorize reopening Incident lead Engineering lead or accountable executive
Restrict routes, jobs and caches; protect service continuity SRE / platform owner Hosting administrator or provider
Explain and repair authorization and serialization API / backend owner + AppSec Developer plus an independent security reviewer
Preserve logs, correlate requests and assess scope SOC / SIEM + data owner Administrator/MSP plus the database or business-data owner
Handle sessions, tokens and downstream secrets IAM / cloud owner Identity administrator
Assess obligations, notices and follow-on harm Privacy / Legal, Communications, Fraud Named business owner with specialist support

Roles can be combined, but the change author should not be the only person validating the fix. The page's team tags are navigation labels, not a complete response roster.

Words used in this playbook

Term Plain meaning
Authentication Establishing who or what is calling.
Authorization Deciding whether that caller may perform this action on this object and these fields.
Object / record A particular profile, invoice, file or other data item; not necessarily one person.
Tenant A customer or organization boundary in a shared service. Legitimate delegation must be represented explicitly.
Object / property / function authorization Separate checks for which item, which fields and which operation a caller may use.
Correlation ID A trusted request identifier used to join events across components.
Emitted versus received The server recorded output; it does not prove a person viewed it or kept a copy.
Exposure window The period when unauthorized access was possible; it can be longer than observed attacker activity.
Canary release A limited reopening used to validate security and business behavior before wider restoration.

OWASP distinguishes object authorization (API1), property authorization (API3) and function authorization (API5). Check all three independently. An exposed bulk business flow can also require abuse controls even when permissions work as designed; do not label every automated request an authorization flaw. OWASP API6.

0. Triage: stop the leak and establish command

Decisions P01–P04: Triage: stop the leak and establish command. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P01. Is unauthorized data access happening now? Restrict the affected operation and verify containment immediately. Check recent requests; investigate historical exposure too. Live application events, response samples, customer report. Incident lead + SRE
P02. Can the report be reproduced with controlled test data? Preserve the smallest proof and the request correlation ID. Keep the report open; request sanitized evidence. Two owned test accounts, expected access policy, build version. AppSec + API owner
P03. Are sensitive fields or multiple tenants potentially reachable? Escalate severity and involve Privacy and data owners. Document the checked datasets; revisit when scope changes. Data classification, route-to-store map, permission model. Data owner + Privacy
P04. Are the incident lead and change owner assigned? Start the timeline and set the next update time. Assign both before coordination stalls. Case ID, contacts, change authority, service dependencies. Incident lead

How to do it: step by step

  1. Open a case using UTC. Record the reporter, affected hostname, API operation, request ID and the first observed time. Keep the time of discovery separate from the earliest possible exposure.
  2. Ask the API owner which operations can return the same data and which services depend on them. Choose a narrow emergency restriction where it stops the leak; escalate broader suspension when it does not.
  3. Use two accounts and synthetic records you control to obtain the smallest proof of cross-user or cross-tenant access. Use a staging environment matching the affected build where possible. Any production check needs the service owner's authorization and a bounded test plan.
  4. Save the request shape, response field names, build and policy versions, and expected versus actual result in restricted evidence storage. Redact tokens and personal values from the ordinary ticket.

Check it worked: a named owner can show the stopped operation, its business impact and the evidence behind the initial severity. Do not delay urgent containment to finish reproducing the flaw.

1. Evidence: reconstruct the exposure window

Decisions P05–P08: Evidence: reconstruct the exposure window. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P05. Are gateway and application logs available for the whole window? Export originals with integrity hashes and retention details. Preserve what remains and record each visibility gap. UTC ranges, sampling settings, retention, export hashes. SOC + SRE
P06. Can a caller be joined to the objects returned? Join trusted principal, request ID and object audit events. Record that gateway volume cannot establish record-level scope. Validated principal ID, correlation ID, object/tenant IDs. SOC + API owner
P07. Is the first vulnerable release or configuration change known? Search from that point with a documented time margin. Expand to the earliest plausible exposure supported by evidence. Deployment history, policy changes, previous test results. Engineering + SOC
P08. Were responses cached, exported or delivered asynchronously? Preserve cache and export-job evidence; trace delivery paths. Record which alternate paths were checked. CDN configuration, job IDs, storage access and download logs. SRE + data owner

How to do it: step by step

  1. Export gateway/CDN/WAF, application, identity, database audit, deployment and configuration records before rotation or redeployment can overwrite them. Work in parallel with containment.
  2. Record each source's timezone, clock offset, collection delay, sampling, retention and missing periods. Hash the exported files, restrict access and keep a record of who collected or transferred them.
  3. Correlate an approved test request across the edge and backend. Confirm which component generates the request ID and resolves the authenticated principal; a client-supplied header is not trustworthy identity evidence.
  4. Find the deployment or policy change that introduced exposure. If it predates retention, describe the earlier period as unobservable. An alert date does not establish the start of the leak.
  5. Do not turn on unrestricted body logging. Prefer operation IDs, authorization outcomes, pseudonymous identifiers, field categories and record counts; restrict any necessary raw samples separately.

Check it worked: the case has an evidence inventory and a defensible review window, including the intervals that cannot be reconstructed.

2. Mechanism: locate the broken boundary

Decisions P09–P12: Mechanism: locate the broken boundary. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P09. Can one caller retrieve another owner's or tenant's object? Investigate object authorization and every equivalent route. Test fields, functions and bulk operations separately. Controlled accounts, object ownership, delegation rules. AppSec + backend owner
P10. Does an allowed object contain fields this caller must not see? Restrict serialization to the permitted fields. Document the field allowlist for each caller role. Response schema, field sensitivity, role-specific tests. Backend + data owner
P11. Can a normal caller invoke privileged or bulk functions? Restrict exports, search, batch and administrative operations. Check alternate methods, GraphQL resolvers and job downloads. Function policy, role matrix, operation inventory. AppSec + API owner
P12. Is credential misuse or anonymous access also involved? Run identity containment or remove anonymous access as appropriate. Keep authorization repair open despite valid authentication. Token validation, subject/issuer/audience, anonymous route policy. IAM + AppSec

How to do it: step by step

  1. Write the expected policy as principal → action → object → fields → tenant → context. Include legitimate delegated users, support access and service identities so a tenant mismatch is not automatically called malicious.
  2. Test object ownership, field visibility and privileged functions as separate controls. A correct login checks identity; it does not establish permission for every returned record.
  3. Trace enforcement through the gateway, backend and data query. The backend must enforce authorization even when a mobile app hides a button or a gateway validates a token.
  4. Inventory mobile/partner endpoints, old versions, direct origins, GraphQL nodes and resolvers, batch requests, list/search routes and asynchronous exports. Test each item's authorization, not only the first REST path reported.
  5. Review token validation and actual use if theft is suspected. A successful authentication event alone cannot distinguish a stolen account from a legitimate customer exploiting a separate flaw.

Check it worked: document demonstrated mechanisms and untested hypotheses separately. The headline is a response scenario, not a claim that every API leak requires a login.

3. Containment: close every route to the data

Decisions P13–P16: Containment: close every route to the data. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P13. Does the emergency control deny the demonstrated access? Verify at the response body and backend, then monitor. Suspend the affected function or strengthen the restriction. Controlled negative test, gateway and app evidence. SRE + AppSec
P14. Do old versions, direct origins or partner paths bypass it? Apply the restriction there or remove the alternate route. Record coverage across the complete route inventory. DNS/routing, API versions, origin access policies. SRE + API owner
P15. Can existing sessions, export jobs or links still return data? Revoke relevant access and stop or restrict pending outputs. Record session, job and link checks. Session tests, queue state, signed-link/cache behavior. IAM + application owner
P16. Could containment break critical business operations? Activate the agreed fallback and communicate the impact. Apply the control and keep rollback ownership clear. Dependency map, fallback test, change record. Business owner + incident lead

How to do it: step by step

  1. Choose the control at the layer that actually blocks access: disable an affected export, deny the vulnerable operation, enforce a server-side authorization guard, or suspend the service when narrower measures fail. Record the action time and version.
  2. Use rate limits and bot controls to reduce automated activity while fixing the underlying boundary. They do not make unauthorized reads acceptable at a slower rate; an IP block alone is also insufficient.
  3. Block bypasses at the origin and other API versions. Check pending jobs, generated files, signed download links and caches. Purge affected cache entries and correct cache key/privacy behavior; do not assume an origin fix invalidates earlier outputs.
  4. If credentials or sessions were misused, use the issuer's and application's revocation controls and verify them against the resource. A self-contained access token may remain accepted until expiry unless the resource enforces revocation or denial.
  5. Use only controlled records to repeat the proof through each relevant entry point. Save the actual body outcome, not just a 403 on the first route. Keep a rollback plan that does not silently restore the leak.

Check it worked: the same unauthorized access fails across affected paths, existing access and queued outputs, with a tested fallback for disrupted business.

4. Scope: count data, records and people separately

Decisions P17–P20: Scope: count data, records and people separately. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P17. Do logs identify objects actually emitted in suspect responses? Deduplicate those objects within confirmed unauthorized requests. Describe potential scope; do not claim a precise downloaded count. Object audit, request classification, limited response evidence. SOC + data owner
P18. Could one request return multiple records or sensitive fields? Expand list, batch and export results by record and field. Validate that one request really corresponds to one object. Pagination, export manifests, schemas, record counts. API owner + data owner
P19. Can records be mapped to unique affected people? Deduplicate securely and document the matching rules. Report record counts and the unresolved person mapping separately. Historical membership, data lineage, duplicate records. Data owner + Privacy
P20. Are passwords, secrets or high-risk personal data included? Start the specific protective actions and notification assessment. Record the field categories actually checked. Field schema at incident time, storage format, samples. Privacy + IAM + data owner

How to do it: step by step

  1. Keep four ledgers: potentially reachable, observed unauthorized responses, unique records, and unique people. Also record fields and changes/deletions. These counts have different meanings.
  2. Start from case-confirmed unauthorized requests; the same account may also have legitimate activity. Join request IDs to object emission events or export manifests, and distinguish attempted reads from content actually emitted by the server.
  3. Handle pagination, batch and GraphQL responses, duplicate retries, historical record versions and cache hits. Response bytes are not a record count. A 200 response may contain an error; HTTP success alone is not proof of disclosure.
  4. Use the schema and permissions in force during exposure, not only today's database. Map records to people through a restricted data-owner workflow; do not copy an entire customer dataset into the incident ticket.
  5. Explain limits: server emission does not prove human viewing or later misuse. Missing object logs mean uncertainty, not zero access. Preserve an estimate's method, assumptions and revision history.

Check it worked: every reported number has a unit, time window, evidence source, deduplication rule and confidence statement. No legal deadline is inferred from a raw row count.

5. Wider impact: look beyond a read-only leak

Decisions P21–P24: Wider impact: look beyond a read-only leak. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P21. Could the same weakness change or delete data? Investigate writes, permissions, refunds and account changes. Keep the read-only conclusion tied to tested methods. Mutation audit, before/after values, database history. Engineering + SOC
P22. Could exposed secrets open another system? Contain those credentials and investigate their use. Record the secret categories and integrations checked. Returned fields, key inventory, downstream audit. IAM + cloud owner
P23. Were new accounts, tokens, integrations or exports created? Preserve and remove unauthorized access or pending outputs. Check creation/change logs and their coverage. Account audit, app grants, jobs, webhook/configuration changes. IAM + API owner
P24. Are customers or partners seeing fraud or follow-on phishing? Coordinate protective action and trusted communications. Monitor for misuse without claiming it has not occurred. Support reports, fraud events, partner notices. Fraud + Communications

How to do it: step by step

  1. Review write operations and business outcomes separately: contact changes, password recovery, refunds, points transfers, newly granted roles and deleted evidence. Do not extend a read-only test to live customer mutations.
  2. If secrets or credentials appeared in responses, use the leaked cloud keys playbook. For stolen customer accounts use customer account takeover; for staff identity compromise use account compromise.
  3. Trace background exports, new service tokens, delegated applications and webhooks. Removing the original caller does not retract a generated file or a new integration.
  4. Ask Support and Fraud for correlated reports using restricted identifiers. Give customers a verified contact path and warn staff about convincing messages that reuse leaked details.

Check it worked: data integrity, downstream access and fraud each have an owner and evidence-backed status, rather than being hidden inside a single “data breach” label.

6. Repair: prove the authorization boundary

Decisions P25–P28: Repair: prove the authorization boundary. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P25. Is the root cause fixed on the server for all affected operations? Review the code/policy change and run negative tests. Keep the affected functionality restricted. Patch review, route coverage, policy diff, deployment ID. Engineering + AppSec
P26. Do independent tests deny cross-user and cross-tenant access? Save the results for the reopening gate. Block release and investigate the failed boundary. Synthetic accounts, role/tenant matrix, raw test outcomes. Independent tester + AppSec
P27. Are field, function, batch, cache and job paths also covered? Run the same allowed/denied matrix on those paths. Add missing cases before declaring repair complete. Response schemas, resolver/job tests, cache variation. QA + API owner
P28. Can the service detect the same pattern with usable evidence? Trigger a synthetic alert and verify the case evidence. Add missing telemetry and route it to a named responder. Test requests, log joins, alert delivery, response runbook. SOC + SRE

How to do it: step by step

  1. Repair authorization where data is selected and returned. Derive ownership, tenant and grants from trusted server context. Do not trust a caller-supplied tenant ID or rely on unguessable identifiers as the authorization check.
  2. Use a response field allowlist for each permitted role and operation. Cover object reads, lists, search, export creation and export download, mutations and field writes, batch operations and GraphQL resolvers.
  3. Test with a synthetic matrix: own record allowed; another customer's record denied; another tenant denied; approved delegated access allowed; ordinary user export denied; approved operator export allowed; anonymous and expired/revoked access denied where authentication is required. Check bodies, HTTP status, data changes and side effects.
  4. Repeat against old versions, direct origins and a warmed cache. Include positive tests so the fix does not merely deny everyone. Run checks in staging first; restrict any production verification to owned synthetic records.
  5. Have someone other than the author review the fix. Add regression tests and verify alerts with synthetic activity at a documented test threshold, without generating a real bulk download.

Check it worked: the tester can attach reproducible allowed/denied results to the deployed build, and the SOC can find their correlated events.

7. Communication: state what the evidence supports

Decisions P29–P32: Communication: state what the evidence supports. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P29. Do reporting, contractual or customer-notice duties apply? Have Legal assess jurisdictions, triggers and deadlines now. Document the assessment and reassess when facts change. Data categories, contracts, jurisdictions, awareness timeline. Legal / Privacy
P30. Are confirmed facts separated from estimates and unknowns? Use that separation in every status update. Reconcile the fact ledger before publishing claims. Versioned scope ledger, evidence references, review sign-off. Incident lead + Privacy
P31. Do recipients need an immediate protective action? Give specific steps through a verified channel. Explain the known impact without inventing required actions. Credential/data impact, fraud assessment, trusted support path. Communications + IAM
P32. Does a supplier hold evidence or share the affected service? Request preserved logs, scope and containment proof. Record why no supplier dependency applies. Hosting/API contracts, support case, data-flow inventory. Supplier owner + Privacy

How to do it: step by step

  1. Bring Privacy/Legal in during triage, not after a final count. Reporting and notification depend on the facts, jurisdiction and contracts; this guide sets no universal deadline. Track each applicable clock and decision owner privately.
  2. Use a versioned fact sheet: discovery time, exposure window, operations and data categories, confirmed and potential scope, containment result and remaining questions. Keep customer records and exploit details out of general updates.
  3. Explain what the organization has done and what recipients should do. A data-only disclosure does not automatically justify claiming a password reset fixes the flaw, and exposed passwords require a different protective assessment.
  4. Verify supplier contacts from existing records. Request evidence, not only “patched” or “no evidence of access.” Coordinate notices while preserving each organization's responsibilities.

Check it worked: statements use the same scoped facts, have a review owner and give a next update time. Unknowns remain visible.

8. Recovery: reopen in stages and close on evidence

Decisions P33–P36: Recovery: reopen in stages and close on evidence. Yes and no branches are reproduced in the table; unknown answers stay open.

Original decision map. Check every applicable question; this is not a path that skips the other checks.

Decision Yes No Evidence / resolve unknowns Lead owner
P33. Have containment, repair and scope gates been reviewed? Authorize a limited reopening with a rollback owner. Keep affected functionality restricted and assign remaining work. Signed gate checklist, residual risks, business approval. Incident lead + business owner
P34. Does the canary release pass both security and service checks? Expand gradually while observing relevant operations. Stop expansion and restore a safe restriction. Negative/positive tests, error rates, latency, support signals. SRE + QA
P35. Do sessions, jobs, old routes and caches obey the repaired policy? Document post-release verification for each access path. Contain the failed path and reopen the investigation. Resource tests, cache/job checks, version inventory. API owner + AppSec
P36. Are remaining unknowns, monitoring and improvement tasks owned? Record review dates and evidence-based closure criteria. Assign owners before administrative case closure. Monitoring window, risk acceptance, ticket owners, evidence retention. Incident lead

How to do it: step by step

  1. Use a release gate with four signatures or explicitly assigned roles: Engineering confirms the fix; an independent tester confirms authorization; SOC confirms visibility and containment; the business owner accepts the service plan and recorded residual risk.
  2. Reopen a small permitted cohort or restricted operation set. Repeat the synthetic negative and positive tests, watch the same abuse pattern and service-health signals, and define when to roll back to a safe restriction.
  3. Recheck existing sessions, jobs, caches, direct origins and old versions. Waiting for new logins is not a verification of already issued access.
  4. Agree a risk-based observation window and review cadence; there is no universal number of quiet hours that proves eradication. Record who handles alerts overnight and what triggers renewed containment.
  5. Close administrative response only with the fact ledger, notifications, evidence retention and remaining risk decisions recorded. Keep tracked follow-up work for the API inventory, authorization tests, data minimization and logging.

Check it worked: reopening is a documented security and business decision, with an owner able to stop it if the same exposure returns.

Hunting: bounded starting points, not disclosure verdicts

The following queries are illustrative and have not been executed against a live workspace. They use Azure Monitor Logs or mapped Splunk logs, not Defender XDR advanced hunting. Replace every placeholder, set the case window, confirm permissions and sampling, and validate on synthetic requests before operational use. Microsoft: APIM resource logs.

1. KQL: one API's request timeline

Uses documented columns in ApiManagementGatewayLogs. Resource-specific diagnostics must already be enabled. APIM UserId is its user identifier and may be empty or unrelated to your application's end user; ApimSubscriptionId is an API subscription, and the table's TenantId is the Log Analytics workspace ID, not the affected customer's tenant. Never use these as substitutes for a verified application principal. The output omits query strings and bodies but identifiers can still be sensitive. Only the latest 250 matching events are shown.

// Illustrative; not executed against a live workspace. Azure Monitor Logs, not Defender XDR.
// Resource-specific ApiManagementGatewayLogs must already be enabled; replace both identifiers.
// UserId is an APIM user identifier, not proof of the application's authenticated principal.
let Start = ago(24h);
let End = now();
let TargetResource = "REPLACE_WITH_APIM_RESOURCE_ID";
let TargetApi = "REPLACE_WITH_API_ID";
ApiManagementGatewayLogs
| where TimeGenerated between (Start .. End)
| where _ResourceId =~ TargetResource and ApiId == TargetApi
| extend Path = tostring(parse_url(Url).Path)
| project TimeGenerated, CorrelationId, OperationId, Method, Path,
          ResponseCode, ResponseSize, CallerIpAddress, UserId, ApimSubscriptionId, Cache, Region
| order by TimeGenerated desc
| take 250

2. KQL: a caller reading many single-record paths

Change the anchored /v1/customers/{id} pattern to a single-object route in your API. It does not inspect a response or establish that the caller lacked permission. dcount is approximate; 20 distinct path IDs per 15 minutes is an illustrative review threshold, not a safe universal baseline. Review approved integrations, support workflows, NAT/shared subscriptions and retries. Grouping by source can split distributed activity; compare principal-level and longer-window views too. Lists, /me, GraphQL, encoded identifiers and export jobs require application-aware logic. Only 100 candidate groups are shown.

// Illustrative; not executed against a live workspace. Azure Monitor Logs.
// Adapt this SINGLE-OBJECT route to your API. Lists, GraphQL and exports need application audit.
// dcount is approximate; thresholds identify review candidates, not proven data theft.
let Start = ago(24h);
let End = now();
let TargetResource = "REPLACE_WITH_APIM_RESOURCE_ID";
let TargetApi = "REPLACE_WITH_API_ID";
let ReviewThreshold = 20;
ApiManagementGatewayLogs
| where TimeGenerated between (Start .. End)
| where _ResourceId =~ TargetResource and ApiId == TargetApi
| where Method == "GET" and ResponseCode between (200 .. 299)
| extend ObjectId = extract(@"^/v1/customers/([^/]+)$", 1, tostring(parse_url(Url).Path))
| where isnotempty(ObjectId)
| summarize Requests = count(), ApproxObjects = dcount(ObjectId),
            FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by bin(TimeGenerated, 15m), UserId, ApimSubscriptionId, CallerIpAddress
| where ApproxObjects >= ReviewThreshold
| order by ApproxObjects desc
| take 100

3. KQL: exact observed objects for confirmed unauthorized requests

ApiObjectAccess_CL is a proposed custom table, not an Azure or Defender built-in. Implement a collection pipeline and this contract first. Emit one record per object actually included in the server's response, including each object in a batch/export where observable; do not emit only the parent list ID. For large exports, use a secured job-to-object manifest and an equivalent scoped join instead of excessive inline telemetry. Missing this instrumentation cannot be repaired retroactively by changing a query.

Custom column Type Required meaning
TimeGenerated datetime UTC time of the emission event.
ApiId string Stable application API identifier.
CorrelationId string Trusted, end-to-end request identifier.
ObjectTenantId string Stable data-owner tenant namespace; use a defined namespace for single-tenant systems.
ObjectId string Stable pseudonymous identifier within that tenant, not an access token or personal value.
ObjectEmitted bool Application recorded the object being emitted; attempts are false.
ResponseCode int Final response status associated with this object event.

Start with request IDs independently confirmed unauthorized through the access policy and investigation. Preserve that classification list privately. The query deduplicates tenant/object pairs exactly within those request IDs and the declared period; it does not estimate total incident scope or count people. Zero means no matching recorded objects under these filters. It can also mean missing logging, placeholders, ingestion delay or the wrong window.

// Illustrative; not executed against a live workspace. CUSTOM application table, not a built-in schema.
// Requires one event per object emitted; the contract is defined in the playbook.
// Include only request IDs independently confirmed unauthorized; do not classify by account alone.
let Start = ago(24h);
let End = now();
let TargetApi = "REPLACE_WITH_API_ID";
let CaseRequestIds = dynamic(["REPLACE_WITH_CONFIRMED_UNAUTHORIZED_REQUEST_ID"]);
ApiObjectAccess_CL
| where TimeGenerated between (Start .. End)
| where ApiId == TargetApi and CorrelationId in (CaseRequestIds)
| where ObjectEmitted == true and ResponseCode between (200 .. 299)
| where isnotempty(ObjectTenantId) and isnotempty(ObjectId)
| summarize FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by ObjectTenantId, ObjectId
| summarize ExactObservedObjects = count(),
            FirstSeen = min(FirstSeen), LastSeen = max(LastSeen)

4. Splunk: equivalent single-record fan-out review

This uses an explicit mapping, not an assumed universal sourcetype: api_id → API identifier; http_method → method; status → HTTP response code; uri_path → path without query string; user → validated application principal when available; src → trusted client address. Map these fields before use. Do not trust an arbitrary forwarded header. Unmapped users and sources stay visible as [unmapped], so that bucket cannot support attribution. Legitimate delegated/bulk activity needs review. Splunk stats reference.

index="REPLACE_WITH_API_LOG_INDEX" sourcetype="REPLACE_WITH_API_SOURCETYPE" earliest=-24h latest=now
api_id="REPLACE_WITH_API_ID" http_method=GET status>=200 status<300
| rex field=uri_path "^/v1/customers/(?<object_id>[^/?]+)$"
| search object_id=*
| eval user=coalesce(user,"[unmapped]"), src=coalesce(src,"[unmapped]"), event_time=_time
| bin _time span=15m
| stats count AS requests dc(object_id) AS distinct_objects min(event_time) AS first_seen max(event_time) AS last_seen BY _time user src api_id
| where distinct_objects>=20
| sort 100 - distinct_objects

Download the query files: 1. KQL · 2. KQL · 3. KQL · 4. SPL.

Post-containment check: rerun the timeline from the recorded control time and inspect application/object evidence for the previously demonstrated pattern. A failed path-ID query, an empty result or fewer requests does not prove the data boundary is fixed. Do not add the distinct-count estimates from adjacent windows; the same objects can appear in several.

Copy-paste templates

Keep customer data, token values and exploitable request samples out of these general messages. Replace brackets with verified facts; leave unknowns visible.

Internal incident update

Case: [ID] | Updated: [UTC time] | Lead: [name]
Affected API/operation/version: [details]
Discovery time: [time]; potential exposure window: [start/end or unknown]
Confirmed mechanism: [evidence-backed fact]; not yet established: [questions]
Containment: [control, time, result, alternate routes still under review]
Scope: [observed responses / unique records / unique people, each with confidence]
Visibility gaps: [sources, sampling, missing periods]
Business impact and fallback: [details]
Owners and next actions: [names/tasks]
Next update: [UTC time]

Request to the API or hosting supplier

Subject: Preserve evidence and confirm API containment – [case ID]
Please preserve the existing gateway, application, identity, object-access,
deployment, export-job and cache records for [UTC window], including retention
and sampling settings. Share evidence through [approved secure channel].
Identify affected operations, versions, origin paths and data stores.
Explain which authorization control failed and which points remain unconfirmed.
Provide containment timestamps and controlled test results for alternate paths,
existing sessions, pending exports and cached responses.
Report potentially reachable data separately from observed returned records,
including field categories, deduplication method and known logging gaps.
Confirm the incident contact, next update and independently verified repair plan.
Do not send raw tokens or customer datasets by ordinary email.

Customer notice for Privacy and Legal review

We identified [description supported by evidence] affecting [service] on [date].
The relevant period is [confirmed window / still being investigated].
The information involved is [verified categories]. We have confirmed [facts];
we are still determining [scope or other uncertainties].
We have [specific containment and repair actions that have been verified].
Recommended action for you: [case-specific action, or explain if none is needed].
Use [known official contact] for support. Be cautious about unexpected messages
that refer to this incident or ask for passwords, payments or verification codes.
We will provide our next update through [official channel] by [time/date].

Reopening and closure record

Case/build/control versions: [IDs]
Engineering review: [owner, evidence, time]
Independent allowed/denied tests: [owner, matrix, results, time]
Coverage: [versions, origins, fields, functions, jobs, sessions, caches]
Scope/notification status and unresolved limits: [facts, owners]
Canary cohort and service checks: [plan/results]
Rollback to safe restriction: [trigger, action, owner]
Monitoring and out-of-hours response: [window, alerts, contact]
Residual risk decision: [accountable owner, rationale, review date]
Reopening approval: [security and business owners, time]
Evidence retention and follow-up tickets: [locations/owners/dates]

Worked example: a valid account and a forgotten API version

Fictional training scenario, not an incident at a named company. All counts below are invented. A customer portal's current API checks ownership, but an older mobile endpoint does not. A valid trial account can retrieve another account's profile. A researcher sends a redacted sample at 08:10 UTC.

Response point What the team establishes
Triage AppSec reproduces the issue using two owned test accounts. The lead restricts the old operation and informs the business owner.
Evidence The vulnerable deployment is five days old, but usable application logs cover only two days. The earlier three days remain unknown.
Containment A direct-origin test bypasses the first edge rule. SRE restricts the backend too and removes an exposed generated export. Negative tests then pass on both routes.
Scope Twelve independently confirmed unauthorized requests emitted seven unique customer records. The data owner maps those records to six people; one person has two records. Retries are not counted twice.
Limits Other records were potentially reachable. The team does not call seven the complete incident total because the older period lacks evidence. No observed write activity is tied to the methods and window checked.
Repair Engineering applies server-side ownership and field checks to the old and current endpoints. Another tester checks delegated access, exports, cached results and negative cases, then verifies a synthetic alert.
Recovery Privacy assesses notification with the known gaps. A limited reopening passes service and security checks. The old version receives a retirement owner and date.

The useful result is a defensible scope statement and a tested boundary. Resetting every password would not, by itself, repair the missing ownership check.

Related incidents: use the guide without assuming the cause

Site analysis Why this response guide is relevant Keep this uncertainty
Lawson ID: the app's own data-returning mechanism Object and field access, bulk-read review, and record-level scoping. The analysis distinguishes possible mechanisms; it does not establish a specific authorization flaw.
SourceNext: the member-information API API activity, exposure-window reconstruction, credential fields and incident counts. API misuse does not itself identify how access was obtained or what authorization failed.
Sagawa: the parcel-tracking lookup Public lookup scope, backend reach and dependent API services. A tracking-service incident does not prove broken object authorization or a particular API exploit.

For a breached provider add supplier breach. For account theft add customer account takeover or staff account compromise. These workstreams can run alongside the API investigation.

Sources, analytical mapping and revision history

This is an original reusable workflow, not a vendor-certified runbook or a firsthand investigation of the linked incidents. OWASP's risk descriptions inform the control boundaries; the decisions, sequence, examples and graphics are SecOpsNomad's own. Current primary technical references were reviewed on 16 October 2026.

16 October 2026: initial English/Japanese guide, 36-decision registers, original visual maps, four query downloads and links to related analyses. Query columns were checked against the references; no live Azure/Splunk tenant, production API or customer data was used for execution tests. API-specific testing, telemetry deployment and case-specific legal review remain the implementing team's work.

All playbooks →日本語で読む ↗