Data-exposure controls
The four controls that stop any API key from bulk-extracting the wine or offer tables.
Data-exposure controls
Threat. A partner holding a valid entity-scoped key can, without any exploit, walk every paginated list endpoint until it holds the complete
wineandoffertables. A rate limit slows this; it does not stop it.
Wine2You answers with four controls, enforced server-side on every read.
C1 — Read-path row/field filter (primary defence)
A row is returned only if all hold:
| Gate | Rule |
|---|---|
network_shareable |
true, or the caller is the owning entity |
permissions |
caller satisfies allowed_countries / named_sellers / default |
| channel/tenant scope | the caller's channel ↔ location links admit the row |
Filtered rows are omitted, not redacted — no empty placeholders that leak existence.
C2 — Bounded pagination
Cursor pagination, page_size default 50 / max 200, single-use cursors, no total-count field. The
whole-network read (GET /v1/inventory/network-snapshot) requires the read:network scope, which ordinary
partner keys do not carry.
C3 — Per-key record quota
Each key has a records-returned budget per period, in addition to its request rate limit. Exhausted → 429
Retry-After, without revealing whether more rows exist. Counters are per entity.
C4 — Audit & anomaly
Every read logs key_id, entity_id, endpoint, rows_returned, cursor_span. A key pulling far above its
trailing average raises an ops alert.
What this means for you as an integrator
- You receive exactly the rows your entity may see — no more, by construction.
- Page-walking to reconstruct a table is bounded by C3 and terminated by C2.
- A
404may mean "not found" or "filtered" — treat both as absent.
Next steps
- Errors & rate limits
- Normative spec (full detail): Data-Exposure Controls Spec