SwadhyAI Notes

All System Design notes

System Design · Security

API security

A partner script, a mobile app, or a scraper hits your checkout and search endpoints all day. Unlike a tired human, an never sleeps. So rare bugs become daily events at scale.

Defense stacks identity, object-level authorization, , and audit logs so abuse shows up as metrics, not angry tweets.

Request defense journey

1

Validate schema

Reject malformed bodies early.

2

Login is not ownership.

3

Meter by route cost and tenant.

4

Observe decisions

Audit allow/deny with correlation ids.

What actually happens

Every request should pass a cost funnel: reject garbage, authenticate cheaply, authorize per object, meter expensive routes, emit decision logs. and are classic input bugs; is the business-logic cousin where IDs are guessed after login.

Browsers add and subtleties around cookies. Partners need API key hygiene and request signing for webhooks. Login magnets attract ; URL features risk into cloud metadata.

Transport security (, TLS posture, ) pairs with application integrity. At millions of users, counters and audit streams are production data systems: size them like product features.

Try it: funnel an API request through defensive gates

Each gate has a job: reject garbage, bind identity, enforce object ownership, meter cost, then log the decision. Login alone never implies access to an id in the URL.

Stage
0 / 6
Outcome
In progress
Rate tokens
5
Request type
valid
  1. 1Schema validation
  2. 2Authentication
  3. 3Object authorization
  4. 4Rate limit
  5. 5Handler
  6. 6Audit log

Input trust

400 early

OpenAPI or JSON schema plus maximum body size.

Identity + object

BOLA

Authenticated tenant must match resource ownership for the action.

Cost + evidence

429 + log

Token bucket per client and route; audit every allow and deny.

Advance a partner API call through validation, authentication, object checks, rate limiting, and audit. Malformed bodies stop early; wrong owner stops at authorization.

Early reject. Schema and size validation save authz CPU and keep error shapes safe for clients.

Object checks. Handlers must verify tenant and action on every id, not only on session creation.

How to choose API hardening moves

1. Treat every endpoint as public. Authz checks belong in handlers, not route comments.

2. Prefer positive validation. Schemas beat chasing bad inputs with regex alone.

3. Meter by cost, not vanity RPS. Login, export, and admin mutations need different buckets and over-budget responses.

Simple rule of thumb

Validate ruthlessly, authorize per resource, throttle economically, sign critical webhooks, and instrument everything: attackers script faster than humans can grep logs.

In simple terms: never trust the body, never trust the id in the URL, and make abuse expensive.

API abuse defense pipeline

Validate, authorize, throttle, and observe before business logic pays the cost

Side path from gateway

Observability

Audit stream (from auth + limits)

CallerGateServiceDetect

Validate

A request schema defines allowed types, required fields, ranges, formats, and size limits before business logic executes. Validate relationships too: an end date before a start date can be syntactically valid but meaningless. Reject or explicitly handle unknown mutation fields so a caller cannot set internal properties such as role or approved status. Continue using parameterized database queries; input validation is not a substitute for separating data from executable query structure.

Authorize

Authorize the action against the actual resource and tenant on every protected read or mutation. For GET /orders/123, a valid token proves a caller identity, but the server must still determine whether that caller may read order 123. Apply the same rule to batch endpoints, exports, nested resources, and derived caches. Replacing sequential IDs with random IDs reduces guessing but does not create authorization.

Throttle

Bucket by IP, key, user, tenant, route, and expensive operation class.

Observe

Emit allow/deny decisions, correlation IDs, and abuse reasons for response.

API threat model card

Assets
Tokens, tenant data, admin routes, export jobs, webhooks.
Actors
Valid users, partners, scrapers, bots, stolen API keys.
Trust boundaries
Edge, gateway, service handler, database, audit stream.
Attack paths
Injection, BOLA, replay, mass assignment, scraping, credential stuffing.
Controls
Schema validation, object authorization, request signing, route quotas.
Detection
Deny spikes, bulk reads, token reuse, abnormal endpoint mix.
Residual risk
Valid clients can still abuse business flows until anomaly rules and quotas catch up.

Injection & XSS defenses

Stop trusting strings from the internet

SQL injection: database commands hidden in user input

If you glue user strings into SQL text, the database cannot tell data from instructions. A crafted userId becomes extra clauses:DROP TABLE, bulk exfiltration, or bypassing login checks.

Parameterized query: placeholders ($1, ?) send values separately so the engine treats them as literals only.
ORM caveat: safe helpers exist until someone calls raw(): lint and review those paths.

Risky concatenation

query = "SELECT * FROM users WHERE id = " + userId
// userId = "1; DROP TABLE users; --"

Parameterized query

query = "SELECT * FROM users WHERE id = $1"
params = [userId]

Add defense-in-depth: least-privilege DB roles (no DDL from app users), Web Application Firewall rules for obvious probes, and centralized DB gateways so risky queries surface in one audit stream.

XSS: Cross-Site Scripting (scripts running in someone else’s browser)

Reflective XSS bounces attacker input straight back in HTML; stored XSS saves it in comments/profiles; DOM XSS mutates the page client-side. All share one goal: execute JS with the victim’s cookies/tokens in scope for your site’s origin.

  • Encode by context (HTML body vs attribute vs URL): generic “strip tags” often misses edge cases.
  • CSP tells the browser which script origins are legitimate: inline handlers become harder to abuse.
  • HttpOnly cookies keep session IDs out of document.cookie so XSS cannot trivially exfiltrate them to attacker.com (still fight XSS: HttpOnly is not a full substitute).

Security headers: what they actually do

Content-Security-Policy (CSP)
Browser allow-list for scripts/styles/images: shrinks XSS blast radius when HTML slips through.
X-Content-Type-Options: nosniff
Stops browsers from “sniffing” uploads as executable when MIME types lie.
X-Frame-Options / frame-ancestors
Reduces clickjacking: embedding your app in invisible iframes on evil sites.
Strict-Transport-Security (HSTS)
Forces HTTPS for a period: cuts sslstrip-style downgrade tricks (combine with redirects + preload carefully).

Input validation: treat the body as untrusted wire format

Validation is not “regex everything”. It is rejecting whole objects that do not match a schema: wrong types, surprise fields, absurd lengths, or mismatched Content-Type. Fail closed before business logic runs.

  • Schema-first: OpenAPI/JSON Schema/protobuf: generate validators and docs from one source.
  • Deny extras: unknown JSON keys often hide prototype pollution or mass-assignment bugs.
  • Size caps: stream large uploads or reject early: prevents memory bombs before parsing.
  • Charset / Content-Type: reject ambiguous combinations that confuse parsers.

CORS & CSRF

Origin controls + cookie/session semantics

CORS allowlists: who may read responses from the browser

Browsers send an Origin header on cross-site fetches. Your API decides whether to expose responses to that origin via Access-Control-Allow-Origin. Preflight OPTIONS requests ask permission before non-simple verbs or custom headers.

Server-side allowlist pattern

  • Echo Access-Control-Allow-Origin only for known hosts, never reflect arbitrary Origin strings from attackers.
  • Tighten Allow-Methods / Allow-Headers; cache preflight only as long as policies stay stable.
Avoid Access-Control-Allow-Origin: * when credentials: include or cookies matter: browsers reject that combo because it would let any website trigger authenticated reads.

CSRF defenses: stop forged requests that reuse cookies

Cookie-based sessions

Attacker sites cannot read your HttpOnly cookie, but they can cause the browser to POST with it: mitigate with synchronizer tokens, SameSite cookies, or custom headers that simple forms cannot forge cross-origin. Choose defenses according to how credentials are sent. A cookie is attached by the browser under its cookie rules, so a state-changing endpoint should validate the application’s CSRF protection and expected origin as appropriate. CORS controls which cross-origin scripts can read responses and make certain requests; it is not a general authentication mechanism, and simple cross-origin requests can still reach a server.

  • Synchronizer tokens in forms or X-CSRF-Token headers.
  • SameSite=Lax/Strict reduces cookie inclusion on cross-site POSTs (not a solo fix for every flow).
  • Double-submit cookie patterns when you cannot keep server session state.

Bearer tokens in memory / headers

Random evil sites cannot attach arbitrary Authorization headers to your API domain: CSRF pressure drops. Pressure shifts to XSS stealing tokens from JS-accessible storage: prefer short TTL + CSP + minimized inline scripts.

API keys & request signing

Integrity + replay resistance

API key hygiene: static secrets that must leak badly when mishandled

Keys are convenient for scripts and partners, also trivial to paste into developer platform. Assume periodic leaks; design for fast revocation, scoped permissions, and per-key observability (who rotated what, when).

  • Generate cryptographically random strings; store only hashes at rest where possible.
  • Prefix keys (sk_live_) so scanners and humans spot leaks quickly.
  • Scope + expire + rotate with overlapping validity windows.
  • Throttle per key: IPs rotate; stolen keys do not.

HMAC request signing: tamper-evident HTTP without TLS alone

Useful when proxies terminate TLS early, when replay windows must be seconds, not minutes, or when webhooks must prove they originated from trusted senders Pair signatures with clock-skew limits and idempotency keys for POST retries.

Canonical string (illustrative)

payload = HTTP_METHOD + PATH + TIMESTAMP + HASH(body)
signature = HMAC_SHA256(secret, payload)

  1. Reject timestamps outside tight skew windows: stops replay of captured requests.
  2. Recompute MAC with server-held secret; compare in constant time: timing leaks recover bytes slowly but surely.
  3. Rotate signing secrets with overlap; dual-verify during migrations.

Real systems add canonical header ordering, region, and service names: copy a reviewed request-signing profile instead of inventing one during a feature sprint. A signature protects only the bytes and context included in its verified input. Verify the received raw body using the sender’s documented canonicalization before transforming it. Then check a bounded timestamp and a durable event ID so a valid old message cannot be replayed indefinitely. A correct webhook signature proves origin and integrity; business deduplication still determines whether the event’s effect has already happened.

Application-layer encryption, beyond HTTPS on the wire

TLS hides bytes from network taps but not necessarily from compromised proxies, log pipelines, or analysts with DB access. Encrypt PII fields before they hit queues, warehouses, or third-party tools: typically with envelope encryption (DEK per record, KEK in managed key service) so you can rotate without rewriting petabytes blindly.

Rate limiting & abuse workflows

Progressive responses beat naive scale-out

Layered throttles

Cheap edges absorb brute noise; gateways enforce business fairness; databases stay for queries that already passed identity checks, never rely on a single global IP limit for IPv6-heavy mobile networks.

  • Edge / CDN buckets per ASN or IP + anomaly detection.
  • API key + user ceilings with different burst allowances.
  • Stricter buckets on auth, exports, search: anything $O(n)$ or fan-out heavy.

Standard rate-limit headers

Return a clear status and retry policy when a quota is exceeded so cooperative clients can back off. State whether a quota counts requests, concurrent work, or weighted cost, and identify the relevant scope without exposing sensitive internal details. A retry hint is not a reservation of future capacity. Clients should combine it with jitter, an end-to-end deadline, and safe retry semantics.

X-RateLimit-Limit
Max tokens per window
X-RateLimit-Remaining
Tokens left in current window
Retry-After
Seconds (or HTTP-date) to wait after 429

Adaptive tightening: dynamic quotas from risk signals

Tie limits to error rates, CAPTCHA outcomes, or bot scores, when abuse spikes, shrink quotas automatically and alert humans. Document automation so on-call engineers know whether tightening came from policy code vs incidents.

Pair with graceful degradation: serve stale reads or queues instead of burning CPU chasing attackers through expensive joins.

Credential stuffing playbook: login is the magnet for bots

  • Tight per-IP and per-account velocity; exponential backoff after failures, never identical JSON errors that distinguish valid emails (account enumeration risk).
  • Step-up MFA / email challenges when geography or device posture changes sharply.
  • Notify users of new devices; integrate breached-password datasets with care for privacy and false positives.
  • Instrument distinct metrics: failure ratio, credential pairs tried, ASNs: stuffing often clusters before password-spray rotates.
EndpointNormal RPSBurst capCost/requestLimit keyOver budget
Login2k5kPassword hash + risk lookupIP + account + deviceStep-up or slow path
Search8k12kIndex fan-outTenant + user + routeReturn 429 with backoff
Export200400Queue + storage writeTenant + job typeQueue or require approval
Webhook ingest10k20kSignature + idempotency writePartner keyRetry-After and dead-letter
Admin mutation50100Policy + auditAdmin user + tenantDeny and alert

Rate limit memory & audit volume

Scale answer: counters and logs are production data systems, not side effects

Counter memory sizing

A token bucket needs a key, token count, refill timestamp, TTL, and metadata. Budget roughly 80-160 bytes per active bucket before datastore overhead.

  • 10M active identities × 4 buckets × 128 B ≈ 5.1 GB raw; replicas, indexes, and fragmentation can push this several times higher.
  • 20M active keys × 5 counters/key × 24 B/counter × 3 windows × 2 replicas ≈ 14.4 GB before key strings, TTL metadata, and allocator overhead.
  • Separate cheap edge counters from expensive account/tenant counters so bot IP churn does not evict customer state.
  • Use approximate structures for massive low-value dimensions; keep exact counters for billing, auth, and abuse decisions.

Audit logging volume

At 50k protected requests/sec and 800 bytes per structured decision log, raw ingest is ~40 MB/sec, or ~3.5 TB/day before compression and replicas.

  • At 80k RPS, 1.2 events/request, and 900 bytes/event, audit ingest is ~86.4 MB/sec, or ~7.5 TB/day raw before compression and replicas.
  • Log every authz deny, admin action, token rotation, and sensitive data read; sample routine low-risk allows only if policy permits.
  • Keep correlation IDs, actor, tenant, route, decision, reason, and latency; avoid raw secrets or sensitive payloads.
  • Plan retention tiers: hot search for incidents, cold immutable storage for audits, deletion workflows for policy-bound data.

Abuse prevention at millions of users

Explain the abuse path as a cost funnel: reject malformed input, authenticate cheaply, authorize per object, meter by route cost, emit decision logs, and degrade non-critical work. The winning answer protects scarce resources while preserving good-user paths.

Testing and runbook panel

  • Replay object-authorization tests for every role, tenant, bulk endpoint, nested resource, and indirect object reference.
  • Load-test rate-limit counters with realistic key cardinality, hot keys, retry storms, and eviction pressure.
  • During abuse spikes, move from observe to slow path, challenge, route clamp, tenant quota clamp, then temporary block with audit reason.
  • Verify audit queries can answer: who touched this resource, from where, under which policy version, and why was the request allowed?

API risk themes & audit logging

Business-logic abuse is still abuse

OWASP API Security Top 10: map each risk to a control

  • API1 Broken Object Level Authorization (BOLA): authorize every object id: /orders/{id} must prove ownership, not only login.
  • API2 Broken Authentication: validate JWT iss/aud/exp, rotate refresh, step-up MFA on sensitive mutations.
  • API3 Broken Object Property Level Authorization: deny mass-assignment of role, price, is_admin fields.
  • API4 Unrestricted Resource Consumption: pagination caps, GraphQL cost limits, export quotas: meter expensive routes.
  • API5 Broken Function Level Authorization: hide admin routes behind role-matrix tests; never rely on obscurity.
  • API6 Unrestricted Access to Sensitive Business Flows: coupon stacking, ticket bots: domain monitors + progressive friction.
  • API7 Server Side Request Forgery: allowlist URL fetch schemes/hosts; block link-local/metadata ranges.
  • API8 Security Misconfiguration: CORS credentials + wildcard Origin, verbose errors, open admin debug.
  • API9 Improper Inventory Management: shadow APIs, old versions still live: inventory + sunset telemetry.
  • API10 Unsafe Consumption of APIs: validate third-party payloads; do not trust partner JSON more than user input.

Audit telemetry: what “good” looks like

Structured JSON logs with timestamp, actor, actor type, tenant, resource hash, action, decision, policy version, reason, request ID, source network class, client hints, latency, and risk score. Stream to immutable storage for tamper resistance.

  • Retention aligns with audit and privacy requirements: legal holds override TTL automation.
  • PII minimization: log stable pseudonyms, not raw PAN or health payloads.
  • Alert on deny spikes, impossible admin geography, or bulk exports outside business hours.

TLS posture & pinning

Mobile + service meshes

Certificate pinning: trust fewer CAs than the whole global bundle

Embed SPKI hashes of your leaf or intermediate cert in mobile binaries; on mismatch, fail closed and report telemetry (users cannot easily bypass like curl -k). Ship at least one backup pin before rotating primaries. Otherwise app stores brick until emergency releases.

Production TLS profile: baseline hygiene checklist

  • Protocols: TLS 1.2 minimum: prefer 1.3; disable legacy SSL/TLS with known breaks.
  • Ciphers: AEAD suites (AES-GCM, ChaCha20-Poly1305); prioritize ECDHE for forward secrecy.
  • Certificates: automate issuance/renewal (certificate automation); monitor expiry SLOs; enable OCSP stapling where supported.
  • Internal RPC: mesh-managed mTLS: policy binds identities to namespaces/service accounts, not just cluster IPs.

Case studies

Public breaches reinterpreted as API lessons: patching, authz, and SSRF chains

Credit bureau · 2017

Credit bureau breach: known vuln, overdue patching, massive structured-data leak

Attackers hit an internet-facing application teams had failed to patch in time, then moved sideways into databases holding structured consumer records: credit histories usable for fraud for years.

Beginners should anchor on process failure as much as “evil hacker”: without authoritative inventories and patching SLAs, even mature SIEM deployments chase ghosts post facto.

Simplified attack / failure chain

  1. Scanner identifies vulnerable framework-equivalent surface reachable from internet.
  2. Exploit establishes foothold on app subnet lacking segmentation depth.
  3. Credential harvesting yields broader DB/API credentials scoped wider than least-privilege.
  4. Bulk queries blend until downstream fraud peaks expose latency.

Advanced controls & design pressure

  • Weekly automated discovery mapping DNS ↔ workloads ↔ owners; escalate orphans weekly.
  • WAF/virtual patch lanes documented as stop-gap hours, not parity with real code fixes.
  • Columnar encryption + managed key service policies limit insider/export misuse even behind VPN.
  • Immutable audit answering “which service principal queried >1M rows?” inside analyst SLA.
  • Segment vault subnets: jump hosts + session recording for humans touching bulk tables.

Aftermath, signals & interview questions

Multi-billion-dollar remediation; disclosure timelines tightened globally.

  • Interview: “Who owns vulnerability aging for internet-facing apps?”: demand named roles.
  • Dashboard: mean patch age by severity vs EPSS scores.

Cloud SSRF · IAM roles

Cloud metadata SSRF archetype: metadata service to excessive IAM to bucket exfiltration

A misconfigured web/WAF configuration allowed attackers to coerce the server into fetching attacker-chosen URLs, including cloud metadata endpoints that mint temporary IAM credentials for attached roles.

Beginners: SSRF is “the server becomes my browser inside your VPC.” APIs that accept URLs or forward webhooks are frequent injection points: TLS does not help once your own server trusts internal IP ranges.

Simplified attack / failure chain

  1. Attacker supplies SSRF payload targeting link-local metadata URL.
  2. Server retrieves ephemeral credentials scoped to over-privileged instance profile.
  3. ListBuckets / sync tooling enumerates buckets and stages multi-GB archives.
  4. Exfiltration blends until object-level alerts fire: often late without baseline anomaly ML.

Advanced controls & design pressure

  • IMDSv2 + hop limits + deny-by-default egress; separate NAT paths per tier.
  • Narrow IAM with ABAC/resource prefixes; forbid wildcard admin on web roles.
  • URL parsers allow-list schemes and hosts; block redirects to internal ranges.
  • VPC endpoints + PrivateLink reduce metadata exposure patterns, still validate apps.
  • managed key service-backed bucket policies requiring encryption context per tenant.

Aftermath, signals & interview questions

  • Federal prosecution underscored insider-like blast radius from SSRF, not “only” XSS severity.
  • Mock interview: draw packet path from ALB → app pod → metadata hop limit.

Social API · IDOR class

partner-data misuse era: consent vs authorized data surfaces

Third-party personality quizzes rode OAuth grants that effectively exported friend-graph-scale datasets: many users understood “this app sees my quiz,” not “this app harvests my entire social neighborhood.”

Beginners internalize that scopes describe mechanics, not morality: product/legal review must gate bulk derivative datasets regardless of token validity.

Simplified attack / failure chain

  1. Bootstrap OAuth consent with narrow wording but broad backend joins.
  2. Background jobs fan out multi-hop graph pulls via poorly capped batch endpoints.
  3. Researchers/partners export aggregates into analytic warehouses lacking row audit.
  4. Public backlash triggers retroactive API restrictions: breaking legitimate researchers too.

Advanced controls & design pressure

  • Per-app QPS + cardinality budgets on graph expansions; kill-switch tokens centrally.
  • Differential privacy budgets per integration with accountant tooling.
  • Immutable audit of large pulls: correlation IDs tying analysts to datasets.
  • Sunset APIs with compile-time flags in SDKs + runtime telemetry on zombie usage.
  • Red-team “partner onboarding” flows quarterly: often softer than consumer flows.

Aftermath, signals & interview questions

privacy-law momentum; platforms tightened developer verification: interviews now expect answers on data minimization vs growth hacking tension.

Mobile/web parity · scraping

sequential-ID scraping narratives: sequential IDs + weak authz ⇒ bulk harvest

Services exposing monotonic IDs without object-level authorization enabled scrapers to iterate URLs like /posts/1..N at wire speed: often faster than product teams assumed because CDNs cached public-ish responses.

Beginners: login proves identity; authorization must prove row entitlement every call, especially for mobile APIs mirrored naïvely from web HTML assumptions. Enforce tenant scope when loading the record, not only after serializing a response or generating a download link. Background workers and service-to-service calls also need trusted authorization context. Test both allowed and denied cases, including a valid user who changes only the object ID. These tests catch a missing boundary that an authentication-only happy-path test cannot see.

Simplified attack / failure chain

  1. Attacker harvests bearer token from poorly pinned mobile binary or leaked admin creds.
  2. Parallel workers sweep ID ranges with minimal backoff: 429 absent.
  3. Dataset replayed offline for OSINT / harassment workflows.
  4. Infra bills spike; fraud teams notice odd geographic fan-out.

Advanced controls & design pressure

  • Opaque IDs + MAC’d capability URLs where enumeration matters.
  • Adaptive rate limits per tenant + progressive latency penalties (“tar pit”).
  • GraphQL cost limits, persisted queries, field-level authz in resolvers, not only gateway auth.
  • Honeypot IDs triggering SOC automation when touched.
  • Export APIs gated behind async jobs + human approvals.

Aftermath, signals & interview questions

  • Press/legal fallout dwarfs infra cost: design reviews now demand abuse personas.
  • Early signal: coefficient of variation on object-fetch latency spikes before PR crisis.

CI/CD · secrets · recurring

Build logs & artifact leaks: API keys committed once, scraped forever

Engineers accidentally publish cloud provider/developer platform/communications provider keys into CI system logs, public forks, or package artifacts: bots scan within minutes. Beginners learn APIs fail operationally when secrets double as both authentication and configuration sprinkled across repos.

Unlike interactive MFA users, API keys do not “feel” phishing, only scanners do. So prevention must be automated secret scanning + ephemeral workload credentials.

Simplified attack / failure chain

  1. Developer echoes env vars while debugging CI.
  2. Logs indexed publicly or leaked artifact tarball uploaded.
  3. Scanner chains temporary-credential identity probes → privilege enumeration.
  4. Attacker spins miners or exfiltrates buckets until cloud abuse notices.

Advanced controls & design pressure

  • OIDC federation from CI → cloud roles: no long-lived cloud provider keys in CI workflows.
  • Push protection + pre-commit secret scanners + nightly secret-scanning sweeps.
  • Central vault injecting short-lived tokens into runtime, not plaintext env in images.
  • Org-level deny policies for risky IAM actions pending tagging maturity.

Aftermath, signals & interview questions

Automated revocation outreach became common: interviews love “break-glass rotation runbook under five minutes.”

Audit deepening: OWASP API mapping

Map controls to OWASP API Security Top 10 explicitly: API1 BOLA via object-level authz tests; API5 BFLA via role-matrix tests; API7 SSRF via allowlists and blocked link-local ranges; API4 consumption via route-cost quotas; API8 misconfig via CORS/credential reviews. Scan secrets in CI, and separate gateway edge checks from service-level authorization so neither layer is assumed sufficient alone.

What must never become false

A caller who is authenticated must still fail closed when they lack object-level permission for the specific resource id in the path or body. Login ≠ ownership (OWASP API1 BOLA). Gateway auth alone does not satisfy this invariant if handlers skip the ownership check.

Failure timeline: BOLA after "we added auth"

T+0      Team ships Bearer JWT on /api/v1/orders/{id}: "auth done"
T+1d     Scraper iterates id=1..5_000_000 with a valid user token
T+1d+2h  Each call returns 200 for other tenants' orders (API1 BOLA)
T+2d     Export job mirrors harvest; SOC sees volume, not ownership denies
T+3d     Press leak; gateway rate limits would not have helped (keys were valid)
Outcome  Invariant broken: authentication without object authorization

Counterexample to "JWT means secure API": valid tokens + sequential IDs + missing ownership checks equal bulk harvest.

Exercises

  1. Map your checkout API to OWASP API1–API7. For each risk, name one automated test and one production metric that would catch a regression.
  2. At 80k RPS with 900-byte audit events and 1.2 events/request, what is raw ingest MB/sec? Which OWASP risks justify keeping deny logs at 100% sample?
  3. A partner webhook is replayed for 90 seconds. Design HMAC + timestamp skew + idempotency so API10-style unsafe consumption and replay both fail closed.

Primary references

API security primary sources: OWASP first, then transport and OAuth hardening.

Short takeaway

Validate ruthlessly, authorize per resource (OWASP API1), throttle economically, sign critical webhooks, and instrument everything: attackers script faster than humans can grep logs. Accordions on this page stay open by default so nothing hides behind forgotten clicks.

Practice and further reading

Use these exercises to connect the lesson to a design decision. State your assumptions, trace what happens to one request, and explain the rule that must remain true even during a failure. That rule is the design's correctness invariant.

Focus for this lesson: Map API assets and trust boundaries to object/function authorization, input/output control, SSRF defenses, quotas, secrets, inventory, and tests.

Explain the decision

How do you prevent BOLA?

Read the reasoning

Authorize every object access against caller, action, tenant, and current resource state; never treat an unpredictable identifier as permission.

Apply it to a production scenario

An image-import API accepts a URL. How do you prevent SSRF?

Read one approach

Allow schemes/hosts as policy permits, resolve and validate every hop, block private/link-local metadata ranges, cap redirects/size/time, and isolate egress.

Work through the numbers

A bulk endpoint allows 500 object IDs and each check costs 2 ms serially. What naive authorization latency?

Read the worked calculation

About 1 second; batch policy/data access without weakening per-object authorization and cap request size.

Reason through a failure

What must gateway-to-service identity propagation preserve?

Read the recovery reasoning

Services trust only signed or mutually authenticated context from approved gateways and cannot accept caller-forged identity headers.