v

Authentication

Entity-scoped API keys, scopes, and the request flow through the Cloudflare edge and Unkey.

Authentication

Wine2You uses entity-scoped API keys. One key belongs to exactly one entity, and the API never trusts a key beyond the entity it is bound to.

The request flow

your system
   │  Authorization: Bearer <key>
   ▼
api.wine2you.shop          ← Cloudflare edge; Access service token for machine-to-machine
   ▼
Wine2You API
   ├─ Unkey verifies the key → resolves entity_id + scopes + rate/quota bucket
   ├─ OpenFGA authorises the action (can_read_offers, can_write_listings, …)
   └─ read-path filter applies C1–C4 before any row is serialised
   ▼
scoped result  (only rows your entity may see)

Keys

Property Value
Issuer Partner portal → POST /api/keys (gated by OpenFGA can_mint_key)
Plaintext shown once at creation; never retrievable again
Binding one key ↔ one entity_id
Scopes e.g. read:offers, write:offers, read:orders, read:network
Limits per-key request rate and per-key record quota (C3)

Scopes

Scope Grants
read:wines, read:offers, read:listings read the corresponding resource within your entity's filter
write:offers, write:listings create/update your own offers and listings
read:orders read orders your entity participates in
read:network the whole-network snapshot — not issued to ordinary partner keys

Two-layer authorisation

  1. Who you are — Unkey + OpenFGA resolve entity_id and permitted actions.
  2. What you may see — the read-path filter (C1–C4) scopes every read.

Both are required. A valid key with a generous rate limit still cannot walk the wine or offer tables, because the filter removes rows before serialisation and a record quota terminates page-walking.

Next steps

Edit this page on GitHub ↗