Gestion des tenants
Les endpoints de gestion des tenants sont protégés par l’en-tête
X-Admin-Key — la clé opérateur qui protège le registre des tenants. Ils ne
sont jamais accessibles avec une signature HMAC de tenant, et la clé admin
ne doit jamais être livrée à un navigateur ou à un appareil.
Pour le modèle conceptuel transverse (états, secret affiché une fois, rotation), voir aussi Cycle de vie d’un tenant.
Convention de paramètres : body ou query
Section intitulée « Convention de paramètres : body ou query »| Méthode | Chemin | Tenant via | Corps |
|---|---|---|---|
| POST | /provision/tenant | corps | complet |
| POST | /update/tenant | ?tenant_id= | partiel |
| POST | /rotate/tenant-secret | ?tenant_id= | — |
| POST | /suspend/tenant | ?tenant_id= | — |
| POST | /reactivate/tenant | ?tenant_id= | — |
| GET | /fetch/tenant | ?tenant_id= | — |
| GET | /fetch/tenants | — (pagination) | — |
Provisionner un tenant
Section intitulée « Provisionner un tenant »Crée un tenant et renvoie son tenant_id et son tenant_secret. Seul
tenant_name est requis ; les champs de configuration peuvent être posés plus
tard.
curl $BASE_URL/api/v1/provision/tenant \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "tenant_name": "example_backend", "rate_limit_per_min": 120, "qr_login_allowed_origins": ["https://example.com"], "callback_url_base": "https://api.example.com", "branding_display_name": "Example", "branding_logo_url": "https://example.com/logo.png", "webauthn_rp_id": "example.com", "webauthn_origins": ["https://example.com"], "passkeys_enabled": true }'Les champs de configuration et ce qu’ils pilotent :
| Champ | Utilisé par |
|---|---|
rate_limit_per_min | Plafond de débit des appels relais (défaut 60, max 10 000). |
qr_login_allowed_origins | Connexion par QR : origines web autorisées. Liste vide = QR-login désactivé. |
callback_url_base | Callbacks relais → tenant. Le relais y ajoute /relay-callbacks/<flow>. |
branding_display_name | Écran de consentement mobile : « Se connecter à … ? ». À défaut, tenant_name. |
branding_logo_url | Logo (carré, HTTPS) de l’écran de consentement mobile. |
webauthn_rp_id | Relying Party ID WebAuthn (eTLD+1). Requis pour les passkeys. |
webauthn_origins | Allowlist d’origines pour les cérémonies passkey. Liste vide = passkeys désactivées. |
passkeys_enabled | Drapeau de déploiement progressif des passkeys (null/true/false). |
La réponse — tenant_secret affiché une seule fois :
{ "success": true, "status_code": 201, "message": "Tenant provisioned. Save tenant_secret now — it will not be shown again.", "data": { "tenant_id": "tnt_...", "tenant_secret": "sk_...", "tenant_name": "example_backend", "rate_limit_per_min": 120, "created_at": "2026-06-21T..." }}Mettre à jour la configuration
Section intitulée « Mettre à jour la configuration »Mise à jour partielle : seuls les champs présents dans le corps sont écrits. Le secret n’est jamais modifié ici (utilisez la rotation) et les changements d’état passent par suspend / reactivate.
curl "$BASE_URL/api/v1/update/tenant?tenant_id=tnt_..." \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{ "qr_login_allowed_origins": ["https://example.com", "https://preview.example.com"], "branding_display_name": "Example (Preview)" }'{ "success": true, "status_code": 200, "message": "Tenant updated", "data": { "tenant_id": "tnt_...", "tenant_name": "example_backend", "status": "active", "rate_limit_per_min": 120, "qr_login_allowed_origins": ["https://example.com", "https://preview.example.com"], "branding_display_name": "Example (Preview)", "abuse_strikes": 0, "created_at": "2026-06-21T...", "updated_at": "2026-06-21T..." }}Rotation du secret
Section intitulée « Rotation du secret »Génère un nouveau tenant_secret. L’ancien secret devient invalide
immédiatement — déployez le nouveau avant tout appel signé suivant. Le nouveau
secret est affiché une seule fois.
curl "$BASE_URL/api/v1/rotate/tenant-secret?tenant_id=tnt_..." \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "success": true, "status_code": 200, "message": "Secret rotated. Save the new tenant_secret — old secret is now invalid.", "data": { "tenant_id": "tnt_...", "tenant_secret": "sk_...", "rotated_at": "2026-06-21T..." }}Suspendre et réactiver
Section intitulée « Suspendre et réactiver »Suspendre bloque tous les appels relais du tenant : une requête /relay/*
signée par un tenant suspendu est rejetée avec 403. La réactivation annule la
suspension.
curl "$BASE_URL/api/v1/suspend/tenant?tenant_id=tnt_..." \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "success": true, "status_code": 200, "message": "Tenant suspended", "data": null }curl "$BASE_URL/api/v1/reactivate/tenant?tenant_id=tnt_..." \ -X POST \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "success": true, "status_code": 200, "message": "Tenant reactivated", "data": null }Lire les tenants
Section intitulée « Lire les tenants »GET /fetch/tenant renvoie la configuration et l’état d’un tenant (jamais le
secret). GET /fetch/tenants renvoie une liste paginée.
curl "$BASE_URL/api/v1/fetch/tenant?tenant_id=tnt_..." \ -H "X-Admin-Key: YOUR_ADMIN_KEY"{ "success": true, "status_code": 200, "message": "OK", "data": { "tenant_id": "tnt_...", "tenant_name": "example_backend", "status": "active", "rate_limit_per_min": 120, "abuse_strikes": 0, "created_at": "2026-06-21T...", "updated_at": null }}curl "$BASE_URL/api/v1/fetch/tenants?limit=100&offset=0" \ -H "X-Admin-Key: YOUR_ADMIN_KEY"limit va de 1 à 500 (défaut 100) et offset est ≥ 0 (défaut 0). La réponse
est un tableau d’objets data au même format que /fetch/tenant.