Il Control Plane espone un’unica API versionata sotto /api/v1. Tre confini di fiducia, tre credenziali diverse — mai mescolarle.
Canale edge — Bearer <edge api_key> + tenant_id
Usato dai nodi edge. L’API key viene emessa al claim del bootstrap e ruotata a ogni re-claim; il Control Plane conserva solo il suo hash SHA-256. Ogni chiamata autenticata aggiorna anche l’heartbeat di flotta (last_poll_at).
| Metodo | Path | Scopo |
|---|---|---|
POST |
/api/v1/sync/ingest |
Drain dell’outbox CDC: eventi batch, idempotente su id evento |
GET |
/api/v1/sync/manifest |
Manifest attivo + firma Ed25519 |
GET |
/api/v1/sync/licenses |
Licenze plugin + licenza contrattuale del tenant (firmate) |
Gli errori usano codici stabili (LICENSE_SUSPENDED, EDGE_CAP_EXCEEDED, DRAINING…). Un 503 con code: DRAINING indica spegnimento in corso — ritenta più tardi, non allarmarti.
Endpoint pubblici — nessuna credenziale
| Metodo | Path | Scopo |
|---|---|---|
POST |
/api/v1/bootstrap/claim |
Scambia un token bt_* monouso per tenant_id + API key. Rate-limited, atomico, ruota la chiave del tenant |
POST |
/api/v1/waitlist |
Iscrizione waitlist pubblica (CORS via WAITLIST_ALLOWED_ORIGIN) |
POST |
/api/v1/webhooks/stripe |
Eventi Stripe — firma verificata byte-per-byte, dedup su event.id |
GET |
/api/v1/live /ready /health |
Probe di liveness / readiness |
GET |
/metrics |
Esposizione Prometheus |
Admin — Bearer <admin-session>
Le sessioni vengono da POST /api/v1/admin/login (rate-limited, password bcrypt, scadenza enforced). Ogni chiamata admin mutante è registrata in cp_admin_audit.
| Metodo | Path | Scopo |
|---|---|---|
POST |
/api/v1/admin/login /logout |
Ciclo di vita della sessione |
GET |
/api/v1/admin/fleet |
Tutti i tenant + salute edge, stato contratto, heartbeat |
POST |
/api/v1/admin/tenants |
Crea un tenant |
GET POST |
/api/v1/admin/tenants/:id/bootstrap-tokens |
Emette token di provisioning monouso |
GET POST |
/api/v1/admin/tenants/:id/manifests |
Manifest attivo / pubblica una nuova versione firmata |
GET POST DELETE |
/api/v1/admin/tenants/:id/licenses |
Gestione licenze plugin (firmate Ed25519) |
GET PATCH |
/api/v1/admin/tenants/:id/subscription |
Stato contratto, cap, metering vs piano |
GET |
/api/v1/admin/tenants/:id/events /aggregates |
Ispezione dei dati sincronizzati |
GET POST |
/api/v1/admin/notifications /…/:id/retry |
Ispezione outbox email + retry dead-letter |
GET |
/api/v1/admin/waitlist |
Lead della waitlist |
GET POST DELETE |
/api/v1/admin/users |
Gestione admin multi-utente + cambio password |
GET |
/api/v1/admin/audit |
Registro append-only delle azioni admin |
Webhook Stripe — Stripe-Signature verificata
Eventi gestiti: checkout.session.completed (provisioning self-service del tenant + token bootstrap + welcome email), customer.subscription.* (state machine del contratto), invoice.paid / invoice.payment_failed (riattivazione / dunning + grace). Endpoint non firmato → 503 se STRIPE_WEBHOOK_SECRET non è configurato — fail-closed.
Convenzioni
requestIdsu ogni risposta per correlazione edge ↔ cloud; includilo nelle segnalazioni di supporto.- Idempotenza: l’ingest deduplica su
idevento; ogni chiamata di sync è sicura da ritentare. - Rate limit: tetto globale più bucket per rotta sugli endpoint pubblici — un
429significa rallenta, non tempesta di retry.