Authentification et clés API
Jetons de session contre clés API, comment frapper une clé, et ce qu’une clé ne pourra jamais faire.
Deux identifiants atteignent l’API, et ils ne sont pas interchangeables.
| JWT de session | Clé API | |
|---|---|---|
| Comment l’obtenir | POST /api/auth/login | Paramètres → Clés API dans le tableau de bord |
| Durée de vie | 15 minutes ; le cookie de refresh la prolonge | Jusqu’à 365 jours, ou jusqu’à révocation |
| Portée | Tout endpoint accessible à votre compte | Uniquement les endpoints explicitement ouverts aux clés, et seulement dans les scopes de la clé |
| Second facteur | Oui, si vous l’avez activé | Non — d’où une clé limitée en portée et dans le temps |
Les deux voyagent dans le même en-tête :
curl -H "Authorization: Bearer $DOCKBOARD_API_KEY" \
https://panel.example.com/api/applicationsUne clé se reconnaît à son préfixe dbk_, et l’API route dessus — aucun en-tête ni endpoint supplémentaire à apprendre.
Frapper une clé
Paramètres → Clés API → Nouvelle clé. Ou via l’API, avec une session — voir pourquoi la gestion des clés est réservée aux sessions :
curl -X POST https://panel.example.com/api/api-keys \
-H "Authorization: Bearer $SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "GitHub Actions — staging deploys",
"scopes": ["project:apps:deploy", "project:deployments:view"],
"projectIds": ["prj_staging"],
"allowedIps": ["203.0.113.0/24"],
"expiresAt": "2027-01-01T00:00:00.000Z"
}'{
"key": {
"id": "…",
"prefix": "dbk_AbC12345",
"scopes": ["project:apps:deploy", "project:deployments:view"]
},
"secret": "dbk_…"
}Les champs
| Champ | Requis | Notes |
|---|---|---|
name | oui | 100 caractères max. Affiché dans la liste des clés et dans chaque ligne d’audit. |
scopes | oui | Voir scopes. Un scope inconnu est écarté ; si rien de valide ne subsiste, la frappe est refusée plutôt que de produire une clé plus faible que demandé. |
projectIds | non | Restreint la clé à ces projets. Omettez pour « tout projet accessible au propriétaire ». Une liste vide est refusée — elle se lit « rien » et se comporterait en « tout ». |
allowedIps | non | IP ou CIDR, v4 et v6. Une clé présentée hors de sa liste blanche est refusée exactement comme une clé inconnue. |
expiresAt | non | ISO-8601, dans le futur, sous 365 jours. Omettez pour aucune expiration. |
kind | non | PERSONAL (défaut) ou MACHINE. SUPERADMIN uniquement pour MACHINE. |
ownerId | non | Frapper une clé agissant au nom d’un autre utilisateur. SUPERADMIN uniquement. |
PERSONAL contre MACHINE : une clé personnelle agit en votre nom et vous appartient. Une clé MACHINE est une automatisation appartenant à l’organisation, qui survit à son créateur — d’où la réserve aux SUPERADMIN, et pourquoi en frapper une pour autrui relève du même privilège.
Les autres appels
GET /api/api-keys # your keys; secrets are never returned
GET /api/api-keys/scopes # every grantable scope, for a picker
POST /api/api-keys/:id/revoke # stops it working, keeps the row for the audit trail
DELETE /api/api-keys/:id # drops the row too — revoke is usually what you wantUn compte peut détenir 50 clés actives simultanément. Les clés révoquées et expirées ne comptent pas : la rotation ne vous met jamais au plafond, seule l’accumulation le fait.
Ce qu’une clé ne pourra jamais faire
Certaines capacités sont totalement absentes du catalogue de scopes : aucune clé ne peut les détenir, quels que soient les droits de son propriétaire :
- Supprimer un projet, en transférer la propriété, gérer ses membres ou ses rôles.
- Gérer les clés API — voir ci-dessous.
Elles restent accessibles depuis le tableau de bord, où une session humaine et la 2FA font barrage.
Pourquoi la gestion des clés est réservée aux sessions
/api/api-keys/* ne porte aucune déclaration de scope : une clé API y est refusée même si elle détient tout le catalogue. Une clé capable de frapper des clés est une clé capable d’échapper à ses propres scopes et de survivre à sa propre révocation. Frapper exige une session.
Arrêter une clé qui n’est pas la vôtre
Les appels ci-dessus sont limités à l’appelant, ce qui laisse un cas sans réponse : une clé MACHINE appartient à l’organisation, et quelqu’un peut partir avec dans sa poche. Les administrateurs de la plateforme disposent donc d’une surface distincte, réservée aux sessions :
GET /api/admin/api-keys # every key on the install
GET /api/admin/api-keys?userId=… # narrowed to one owner
POST /api/admin/api-keys/:id/revoke
DELETE /api/admin/api-keys/:idLister requiert users:view ; révoquer et supprimer requièrent `users:manage` — la même permission que suspendre le compte, car détruire l’identifiant de quelqu’un relève de la même classe d’acte. Les deux écrivent une ligne d’audit nommant la clé *et son propriétaire*, puisqu’après suppression il n’y a plus rien à interroger.