Scopes et restrictions de projet
Les deux catalogues de scopes, les jokers, et pourquoi une clé est bornée par ses scopes ET son propriétaire.
Un scope est une permission que le panneau possède déjà, préfixée du catalogue dont elle vient :
project:apps:deploy a project permission, checked per project
platform:projects:view a platform permission, checked globallyLe préfixe n’est pas décoratif. quotas:view existe dans les deux catalogues et n’y signifie pas la même chose — le budget d’un projet contre celui de tous les utilisateurs. Sans le préfixe, une même chaîne autoriserait silencieusement le plus large des deux.
Jokers
Les jokers d’action sont autorisés : project:apps:* couvre toute action sur les applications, y compris celles ajoutées dans une version ultérieure. Les jokers de ressource ne le sont pas : project:* signifierait « tout », or c’est précisément l’octroi qu’un relecteur doit voir écrit noir sur blanc.
project:ghost:* — est également refusé. Il figurerait dans la liste des scopes en ayant l’air d’un octroi tout en ne conférant rien.Les scopes que vous utiliserez vraiment
GET /api/api-keys/scopes sur votre instance fait foi — la liste est générée depuis les catalogues de permissions en vigueur, elle ne dérive donc jamais. Quelques scopes récurrents :
| Scope | Portée |
|---|---|
project:apps:view apps:create apps:delete | Lister et lire, créer et modifier, supprimer des applications. |
project:apps:deploy | POST /deployments, redéploiement, rollback. |
project:apps:restart | Démarrer, arrêter, redémarrer. |
project:apps:logs | Logs de conteneur. |
project:apps:env | Lire et écrire les variables d’environnement. |
project:deployments:view | Liste et détail des déploiements. |
project:databases:view databases:create databases:manage databases:delete | La surface bases de données — manage couvre démarrage/arrêt, identifiants, export et import. |
project:domains:view domains:manage domains:delete | Domaines, vérification, synchronisation DNS. |
project:backups:view backups:create backups:restore backups:delete | Planifications, exécutions et restaurations de sauvegardes. |
platform:projects:view platform:projects:manage | La liste des projets elle-même, et la création ou modification de projets. |
Deux plafonds, pas un
Les droits effectifs d’une clé valent `propriétaire ∩ scopes`.
Le contrôle de scope est un filtre supplémentaire par-dessus les permissions du compte, jamais un remplacement. Chaque contrôle en aval — rôle, permission de plateforme, appartenance au projet — s’exécute contre la ligne utilisateur vivante derrière la clé, exactement comme pour la session de cette personne. Conséquences à connaître :
- Accorder
project:apps:deleteà une clé dont le propriétaire n’a qu’un accès en lecture sur un projet n’accorde rien du tout. - Rétrogradez ou bannissez le propriétaire, et ses clés cessent de fonctionner dès la requête suivante — la ligne utilisateur est relue à chaque requête, jamais mise en cache depuis la frappe.
- Une restriction
projectIdsresserre la clé *en deçà* de son propriétaire. Elle ne peut jamais l’élargir.
Comment la restriction de projet est appliquée
Partout où une requête nomme un projet — la route (/projects/:id, :projectId), la query string (?projectId=) ou le corps — et, à défaut des trois, sur le projet propriétaire de la ressource.
POST /api/applications/:id/restart nomme une application, pas un projet ; le garde résout le projet de cette application avant de trancher. Idem pour bases, domaines, sauvegardes, instances et déploiements — qui se résolvent via leur application. Une clé épinglée au projet A ne peut pas redémarrer une application du projet B en passant par l’identifiant de l’application.
Quand une requête ne nomme aucun projet — GET /api/deployments répond « tout ce que je vois » — la restriction s’applique aux lignes : tout ce qui est hors des projets de la clé est retiré de la réponse.
Ce qu’une clé peut atteindre, tout court
Un endpoint n’est appelable par clé que s’il a été explicitement ouvert. Pas d’« autorisé sauf interdit » : tout endpoint écrit à l’avenir est réservé aux sessions tant que quelqu’un ne l’ouvre pas délibérément — c’est ce qui empêche un jeton de CI de devenir insensiblement un compte complet au fil des versions.
Actuellement ouverts :
| Domaine | Chemin de base et couverture |
|---|---|
| Applications | /api/applications — créer, lister, lire, modifier, supprimer, logs, env, démarrer/arrêter/redémarrer, redéployer, rollback |
| Déploiements | /api/deployments — déclencher, lister, lire |
| Projets | /api/projects — créer, lister, lire, modifier, membres, usage, mesh, catalogue RBAC |
| Bases de données | /api/databases — créer, lister, lire, cycle de vie, identifiants, export/import, supprimer |
| Domaines | /api/domains — ajouter, lister, lire, modifier, vérifier, santé, enregistrements, sync DNS, supprimer |
| Sauvegardes | /api/backups — planifications, exécutions, manifestes, restauration, vérification, export, config de stockage par projet, suppression |
Les handlers hors de cette liste — exec dans un conteneur, déplacer une application entre serveurs, transférer un projet, modifier les rôles, tout ce qui est sous /api/admin — répondent à une clé :
{
"statusCode": 403,
"message": "This endpoint is not available to API keys. Use a session, or open it with @RequireApiScope."
}