Permissions et scopes
Opfield utilise des scopes explicites. Un scope comporte une base de capacité et peut inclure un suffixe de ressource.
docker:containers:viewdocker:containers:view:<node-id>/<resource-id>databases:view:<database-id>nodes:details:<node-id>La base de capacité décrit l’action autorisée. Un suffixe de ressource restreint cette action à l’identité d’un nœud ou d’une ressource. Opfield évalue l’identité authentifiée, les droits effectifs de groupe et directs, la propriété de la ressource, l’état actuel du produit et les droits du plan à la frontière de l’opération côté serveur. La visibilité dans la navigation et les contrôles désactivés aident les utilisateurs à comprendre leurs accès, mais ce ne sont pas des autorisations.
Les permissions répondent à deux questions distinctes : quelle action est autorisée, et quelle ressource est concernée. Un utilisateur peut être en mesure de consulter un Container sans voir les détails sensibles de l’hôte, ou de gérer une Route sans gérer toutes les Routes de son nœud Ingress. Préférez le plus petit droit qui permet le processus réel plutôt que d’accorder un accès étendu pour éviter un écran manquant.
Règles de conception
Section intitulée « Règles de conception »- Accordez les accès normaux via des groupes ; réservez les ajouts directs à un utilisateur aux exceptions.
- Préférez les droits limités à une ressource à ceux couvrant un nœud entier ou une zone entière du produit.
- Séparez la consultation de la modification, de l’affichage des secrets, de l’export, des montages et des actions destructives.
- Traitez les jetons d’API et les autorisations OAuth comme une autorité déléguée, et non comme des administrateurs de rechange.
- Testez le parcours utilisateur obtenu, y compris la visibilité dans la navigation et le refus direct par l’API.
Partez de la tâche que l’identité doit accomplir. Listez les actions de lecture nécessaires pour découvrir et vérifier la cible, les actions de modification nécessaires pour la changer, et toute donnée protégée séparément ou action destructive. Limitez ensuite chaque droit à la ressource, au nœud ou au dossier exacts où se situe le travail. L’appartenance à un groupe est normalement plus facile à examiner et à révoquer que de nombreux droits directs par utilisateur.
N’accordez pas un scope de gestion global simplement parce que le processus traverse plusieurs types de ressources. Un processus de publication peut nécessiter un accès limité à un projet Pages, un domaine, un certificat, une Route et l’état d’un Build Worker, sans pour autant avoir besoin de l’administration générale des nœuds ni de l’export des clés privées. Testez le processus complet avec l’identité non administratrice prévue avant toute utilisation en production.
Niveaux de scope et visibilité
Section intitulée « Niveaux de scope et visibilité »Les scopes globaux s’appliquent à toute la zone de produit autorisée. Les droits limités à un nœud restreignent les opérations aux ressources d’un nœud géré précis lorsque le contrat de la ressource prend en charge ce niveau. Les droits limités à une ressource désignent une ressource Opfield durable. Les dossiers peuvent regrouper les ressources prises en charge et intervenir dans la conception des accès, mais déplacer une ressource dans un dossier ne change ni sa propriété d’exécution ni son chemin réseau.
Tout scope d’action implique la consultation des mêmes ressources : proxy:edit:<route-id> affiche cette Route, et docker:containers:manage:<node-id> affiche les conteneurs de ce nœud. Les scopes de création font exception : ils n’impliquent aucune consultation, qu’ils soient larges ou restreints à un dossier ou à un nœud. Voir Consultation implicite.
Les Apps sont visibles avec apps:view sur l’app ou sur l’un de ses environnements. Sans ce scope, un utilisateur voit malgré tout une app lorsqu’il peut consulter l’un de ses membres — un conteneur, un Deployment, un projet Compose, une base de données, un stockage, une Route ou un site Pages — grâce à ses propres droits sur la ressource, sur le dossier de l’environnement ou sur le dossier de l’app. Il ne voit alors que les environnements qui contiennent ces membres, et uniquement ces membres ; la vue d’ensemble, l’activité et les incidents se limitent à eux. Les variables, les nœuds autorisés, la maintenance, la promotion et chaque action sur l’app nécessitent toujours leurs scopes d’app.
La visibilité des ressources et celle des hôtes sont intentionnellement distinctes. Un utilisateur peut exploiter une charge de travail qui lui est attribuée sans découvrir l’inventaire d’hôtes sans rapport. La recherche, la navigation, REST, la découverte MCP, les abonnements en temps réel et les requêtes directes sur les ressources doivent tous appliquer les mêmes règles d’accès effectives. Un élément de navigation masqué ne prouve pas un refus ; vérifiez aussi une requête directe.
Restreindre l’accès à un dossier
Section intitulée « Restreindre l’accès à un dossier »Un droit sur un dossier limite un utilisateur, un groupe, un jeton d’API ou une autorisation OAuth aux ressources de ce dossier et de ses sous-dossiers. Il convient à une équipe projet qui ne doit voir et exploiter que ses propres ressources, par exemple tout ce qui appartient à MyProject.
- Créez un dossier MyProject dans chaque zone qu’utilise l’équipe, par exemple Routes, conteneurs Docker et Databases. Chaque type de ressource a sa propre arborescence de dossiers : un dossier de Routes ne couvre donc pas les conteneurs. Voir Prise en charge des dossiers par type de ressource.
- Déplacez les ressources existantes du projet dans ces dossiers. Le déplacement d’une ressource nécessite le scope de gestion des dossiers de la zone et un droit de modification sur la ressource.
- Dans l’éditeur de groupe ou dans les permissions supplémentaires de l’utilisateur, sélectionnez les scopes dont l’équipe a besoin, ouvrez la restriction de chaque scope et choisissez le dossier MyProject. Le droit enregistré a la forme
<scope>:folder/<folder-id>.
| Objectif | Scopes restreints au dossier |
|---|---|
| Voir et exploiter les conteneurs et Deployments du projet | docker:containers:view, docker:containers:manage ; ajoutez docker:containers:environment, docker:containers:secrets ou docker:containers:console seulement si nécessaire |
| Créer de nouveaux conteneurs et Deployments dans le dossier, y compris récupérer leurs images | docker:containers:create |
| Gérer les Routes du projet | proxy:view, proxy:edit, proxy:create |
| Interroger les bases de données du projet | databases:view, databases:query:read |
Ce que voit l’utilisateur :
- Chaque ressource du dossier et de ses sous-dossiers, y compris celles qui y sont créées ou déplacées plus tard. Opfield résout les droits sur les dossiers à chaque requête, et les pages ouvertes prennent en compte les ressources nouvellement visibles sans nouvelle connexion.
- Rien d’autre : les listes n’affichent que les ressources accordées, un dossier accordé encore vide affiche une liste vide, et les requêtes directes sur d’autres ressources sont refusées. Une ressource sortie du dossier cesse d’être visible, sauf si l’utilisateur dispose d’un droit distinct sur elle.
- Les boîtes de dialogue de création ne proposent que les dossiers dans lesquels l’utilisateur peut créer. No folder est masqué lorsque l’utilisateur ne peut pas créer à la racine, et le seul dossier autorisé est présélectionné. Via l’API ou MCP, passez le dossier dans
folderId; créer ailleurs renvoie403. Lorsqu’une ressource s’exécute sur un nœud, la boîte de dialogue ne liste que les nœuds sur lesquels l’utilisateur peut déployer, sans lui accorder l’administration des nœuds. - Un scope de création seul affiche le dossier comme destination, mais aucun de ses contenus. Accordez aussi un scope de consultation sur le dossier lorsque l’équipe doit voir ce qui s’y trouve déjà.
- Les conteneurs et Deployments créés à partir d’une source Git sont placés dans le dossier choisi, y compris lorsque le premier build les crée plus tard. Tant qu’il attend son premier build, l’élément est listé dans ce dossier et peut être déplacé avec Move to folder… ou par glisser-déposer ; le premier build le crée ensuite dans le dossier où il se trouve à ce moment-là. Voir Placement des charges de travail construites dans les dossiers.
- Une création refusée indique les dossiers et nœuds dans lesquels l’utilisateur peut créer à la place, par exemple
Missing docker:containers:create at the root (no folder). Your docker:containers:create access is limited to folder 'MyProject' (<id>): pass folderId for one of them.Les créations Docker renvoient ce message dans la Console et l’API REST ; pour les autres types de ressources, les erreurs d’outils MCP et AI Workspace ajoutent la même liste de dossiers et de nœuds.
Settings > Authentication > Identity provisioning > Auto-assign permissions for created resources est activé par défaut. Ce paramètre ajoute, pour chaque nouvelle ressource, des droits dans les permissions supplémentaires de son créateur : toujours la consultation de la nouvelle ressource, et les autres scopes par ressource uniquement si le créateur les détient déjà de façon large ou sur le dossier ou le nœud de destination. Un utilisateur qui ne dispose que d’un scope de création voit donc exactement les ressources qu’il a créées. Un créateur limité à un dossier conserve ainsi le même accès si la ressource est ensuite sortie du dossier, mais n’obtient rien de nouveau : la consultation et la création sur un dossier ne se transforment pas en accès à la console ou aux secrets. Désactiver ce paramètre n’affecte que les nouvelles ressources ; les droits existants restent et peuvent être modifiés dans Assign permissions.
Les jetons d’API et les autorisations OAuth acceptent les mêmes restrictions par dossier. Leurs dossiers sont résolus d’abord, puis le résultat est limité par les accès propres du propriétaire ; un jeton ne voit donc jamais plus que son propriétaire ; voir Restreindre les jetons et les autorisations OAuth.
Voir ce qu’une identité peut atteindre
Section intitulée « Voir ce qu’une identité peut atteindre »GET /api/auth/me/access renvoie les accès de l’appelant regroupés par zone de produit : s’ils sont larges ou limités, les dossiers accordés avec leurs chemins, les nœuds, comptes et ressources individuelles avec les actions autorisées sur chacun, et les endroits où l’appelant peut créer (create.atRoot, create.folders, create.nodes). Cela fonctionne avec une session, un jeton d’API ou un jeton OAuth, et indique qu’un jeton ou une autorisation OAuth est borné par les accès actuels de son propriétaire. L’identifiant, le nom, l’adresse e-mail et le groupe de l’utilisateur ne sont inclus que pour une session de navigateur et pour AI Workspace, jamais pour un jeton. Les clients MCP et AI Workspace obtiennent le même résumé avec l’outil get_my_access, et MCP le sert aussi sous forme de ressource opfield://access ; voir Savoir à quoi l’appelant a accès.
Un accès limité à des dossiers est normal pour les agents et l’automatisation. Une liste ne renvoie que ce que l’appelant peut voir ; une liste vide à la racine n’est donc pas un refus. Lorsque vous testez une identité limitée à des dossiers, lisez d’abord son résumé d’accès, puis créez dans l’un des dossiers listés avec folderId.
Restreindre l’accès Git à des dépôts
Section intitulée « Restreindre l’accès Git à des dépôts »Les scopes d’intégration Git peuvent être limités à un compte connecté et, en dessous, à des groupes et projets GitLab ou à des propriétaires et dépôts GitHub. Un droit sur un groupe GitLab couvre ses sous-groupes et tous les projets qu’ils contiennent ; un droit sur un propriétaire GitHub couvre tous les dépôts de cette organisation ou de cet utilisateur. Dans l’éditeur de groupe, les permissions supplémentaires d’un utilisateur, le formulaire de jeton d’API et le consentement OAuth et MCP, cochez un connecteur pour couvrir tous ses dépôts, ou ouvrez Add groups or projects… (GitLab) ou Add owners or repositories… (GitHub) sous le connecteur et recherchez des cibles plus précises. Les droits stockent des identifiants stables du fournisseur ; renommer ou déplacer un groupe ou un dépôt ne les modifie donc pas.
Pour permettre à une équipe de construire à partir d’un projet, accordez integrations:gitlab:use sur ce projet en plus des permissions propres à la charge de travail : use sur le projet suffit pour configurer une source de build Docker ou Pages. Conservez ce droit : les builds manuels le vérifient à nouveau, et les builds automatiques d’une source enregistrée dans cette version sont suspendus lorsque le compte qui l’a enregistrée perd use. Les jetons d’API et les autorisations OAuth portent les mêmes restrictions et n’atteignent jamais un dépôt que leur propriétaire ne peut pas atteindre à ce moment-là. Voir Restrictions de l’intégration Git pour le format des qualificatifs et Restreindre l’accès aux dépôts pour ce que vérifie chaque opération.
Exploiter des charges de travail sans les adopter
Section intitulée « Exploiter des charges de travail sans les adopter »Les permissions Docker limitées à une ressource fonctionnent sur les conteneurs qu’Opfield a découverts sans les avoir créés. Vous pouvez permettre à une équipe de redémarrer un service et de lire ses journaux sans confier à Opfield tout l’hôte, ni la configuration de l’application.
| Objectif | Droit | Remarques |
|---|---|---|
| Lire les journaux, statistiques et processus d’un conteneur autonome | docker:containers:view:<node-id>/<resource-id> |
Il n’existe pas de scope distinct pour les journaux ; view les couvre |
| Démarrer, arrêter, redémarrer ou tuer un conteneur autonome et lire ses journaux | docker:containers:manage:<node-id>/<resource-id> |
manage implique view sur le même conteneur. Il autorise aussi kill et la recréation ; il n’existe pas de scope limité au redémarrage |
| Ouvrir un shell dans ce conteneur | ajoutez docker:containers:console:<node-id>/<resource-id> |
L’accès à la console est toujours un droit distinct |
| Lire les journaux agrégés et la supervision d’un projet Compose externe | docker:compose:view:<node-id>/<project-id> |
Fonctionne avant l’adoption et avec tous les plans |
| Démarrer, arrêter ou redémarrer un projet Compose | docker:compose:manage:<node-id>/<project-id> une fois le projet adopté |
Les projets externes sont en lecture seule jusqu’à l’adoption ; les actions de cycle de vie s’appliquent à tout le projet, et non aux conteneurs Compose individuels |
| Appliquer les mêmes accès à un groupe de ressources | les mêmes scopes avec folder/<folder-id> |
Couvre les ressources prises en charge du dossier Docker et de ses sous-dossiers |
Un conteneur autonome est tout conteneur sans labels de projet Docker Compose, y compris un conteneur lancé avec docker run. Opfield lui attribue une identité de ressource stable qui survit aux opérations de recréation et de mise à jour effectuées via Opfield. Si le conteneur est supprimé puis relancé hors d’Opfield, Opfield enregistre une nouvelle ressource et révoque les droits sur l’ancienne identité. Voir Conteneurs qu’Opfield n’a pas créés.
Un projet Compose externe conserve son identité tant qu’Opfield l’observe. Si le projet disparaît du nœud, par exemple après docker compose down, Opfield le retire de l’inventaire, sauf s’il est placé dans un dossier Docker ; lorsqu’il réapparaît, il reçoit une nouvelle identité, et les droits sur l’ancienne identité du projet ne correspondent plus. Placez dans un dossier Docker les projets externes qui portent des droits limités au projet, ou accordez l’accès via le dossier.
Séparations importantes
Section intitulée « Séparations importantes »- La modification d’un conteneur n’implique pas la modification des montages.
- L’accès à une base de données n’implique pas l’affichage des identifiants.
- L’utilisation d’Inference n’implique pas l’accès à AI Workspace.
- La consultation d’une ressource n’implique pas la consultation des détails de son nœud hôte.
- La modification d’une Route n’implique pas l’export de la clé privée du certificat.
Les autres opérations sensibles suivent le même principe. L’accès à la console ou aux fichiers est distinct de la consultation ordinaire d’une charge de travail. L’export d’archives est distinct de la consultation des fichiers ou de la configuration d’une ressource. La modification d’un secret n’implique pas son affichage, et les valeurs en écriture seule sont remplacées plutôt que récupérées. Le consentement OAuth et la découverte des outils MCP n’ajoutent pas de scopes que l’utilisateur propriétaire ne possède pas.
AI Workspace et le MCP distant restent soumis à l’autorisation normale d’Opfield. L’accès à AI Workspace et l’utilisation d’Opfield Inference sont des capacités distinctes. Le MCP distant nécessite sa propre ressource OAuth et mcp:use ; les sessions de navigateur, les jetons d’API gw_ ordinaires, les jetons de journalisation, les jetons d’inférence ou les jetons OAuth émis pour une autre ressource ne sont pas des identifiants MCP interchangeables.
Identités programmatiques
Section intitulée « Identités programmatiques »Utilisez des identifiants distincts pour l’administration interactive, la CI, la supervision et les outils tiers. Un jeton d’API agit avec l’autorité déléguée par son utilisateur Opfield. Un client OAuth ajoute un cycle de vie explicite de redirection et de consentement. Le MCP distant utilise OAuth et n’expose que les outils compatibles avec l’identité actuelle et l’état du produit. Un jeton gwi_ dédié appartient au plan de données Opfield Inference et ne peut pas servir d’identifiant d’API Opfield normal.
Créez les identifiants d’automatisation avec un propriétaire, un objectif, une rotation prévue et un système dépendant connu. Stockez les secrets une seule fois dans un gestionnaire de secrets, jamais dans des URL de dépôts, l’historique des commandes, des captures d’écran ou des journaux. Testez une action autorisée et une action refusée. Si un jeton est perdu, créez-en un de remplacement et révoquez l’ancienne valeur ; les secrets masqués ne peuvent pas être récupérés depuis l’interface.
Révocation
Section intitulée « Révocation »Les opérations de session, d’API, de MCP et de WebSocket protégés revalident les accès. La révocation d’un groupe, d’un jeton ou d’un droit sur une ressource doit arrêter les nouvelles actions privilégiées et mettre fin aux flux protégés lorsque c’est nécessaire. Une page chargée auparavant ou un outil déjà découvert ne conserve pas d’autorité après la révocation.
Lorsque les responsabilités d’un utilisateur changent, examinez ensemble l’appartenance aux groupes, les droits directs, les sessions actives, les jetons d’API, les autorisations OAuth et les dépendances d’automatisation. Bloquer un utilisateur arrête toute nouvelle utilisation sans effacer l’attribution. Supprimer un utilisateur préserve les enregistrements d’audit historiques, et restaurer un enregistrement supprimé ne le réactive pas silencieusement. La suppression du dernier administrateur est refusée.
La suppression d’une ressource — nœud, Route, domaine, certificat, CA, Access List, modèle, groupe, dossier, connecteur, projet Pages, base de données, stockage, environnement de journalisation, Deployment, projet Compose, app ou toute autre ressource — retire chaque permission qui la désigne des utilisateurs, des groupes, des jetons d’API et des autorisations OAuth et MCP ; une ressource ultérieure portant le même nom n’en hérite donc jamais. Les permissions restantes sur des ressources supprimées avant 2.11 sont retirées au démarrage et toutes les heures.
Pour la rotation d’un identifiant, créez le remplaçant, mettez à jour le système dépendant, vérifiez qu’il est utilisé avec succès, puis révoquez l’ancien identifiant. En cas de divulgation suspectée, révoquez d’abord lorsque c’est sûr sur le plan opérationnel, examinez l’activité d’audit et les identifiants de requêtes, invalidez séparément les sessions liées et effectuez la rotation de tout secret en aval susceptible d’avoir été exposé.
Vérification et diagnostic des échecs
Section intitulée « Vérification et diagnostic des échecs »Testez les permissions depuis l’identité qui les utilisera, et non depuis un compte administrateur. Confirmez la visibilité attendue dans la navigation et la recherche, lisez la ressource cible, effectuez une opération autorisée et tentez une opération clairement hors périmètre. Pour l’automatisation, testez aussi un échec de validation et le suivi d’une tâche asynchrone.
Interprétez précisément les échecs courants : 401 indique une authentification absente ou invalide ; 403 signifie généralement un scope ou un droit de plan manquant ; 404 peut refléter la visibilité de la ressource autant que son absence ; 409 indique un conflit de cycle de vie, de quota ou d’état actuel ; et 422 indique une entrée invalide. Ne résolvez pas un conflit de droit de plan ou de cycle de vie en élargissant les permissions.
Voir Scopes, jetons et OAuth pour les processus de mise en œuvre.