Aller au contenu

Restreindre l'accès aux distributions & aux machines

Par défaut, tout utilisateur authentifié dont le rôle global autorise une action peut accéder à toutes les distributions et à toutes les machines de l'inventaire. Ce guide montre comment restreindre cet accès à des rôles ou des groupes spécifiques — pour l'arborescence de paquets d'une distribution (distribution_access) et/ou un ensemble de machines de l'inventaire (machine_access). Pour savoir comment ces deux couches s'articulent avec le système de rôles global, voir Le modèle RBAC ; cette page ne couvre que les étapes de configuration.


1. Prérequis

  • Vous devez être connecté en tant qu'admin — les endpoints de gestion de distribution_access et machine_access sont réservés à l'admin, et seul l'admin contourne les restrictions une fois créées.
  • Un rôle personnalisé ou un groupe déjà créé, à utiliser comme principal_id. Listez les rôles et groupes existants avec :
    curl -s http://repod.example.com:8000/api/v1/roles \
      -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .
    
    curl -s http://repod.example.com:8000/api/v1/groups \
      -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .
    
    Notez l'id du rôle ou du groupe auquel vous voulez accorder l'accès — cette valeur est le principal_id dans toutes les requêtes ci-dessous.

Ceci est opt-in et irréversible par omission

Une distribution ou une machine sans aucune règle d'accès reste totalement ouverte. Dès que vous ajoutez la première règle pour un codename ou une machine/tag donné, celle-ci devient restreinte aux seuls principals listés dans les règles associées. Assurez-vous que les comptes admin (qui contournent toujours les restrictions) ou le rôle/groupe de l'équipe visée sont bien couverts avant d'ajouter la première règle — il n'existe pas d'entrée « autorisation par défaut » distincte sur laquelle se replier.


2. Restreindre une distribution

2.1 Vérifier l'état actuel

curl -s http://repod.example.com:8000/api/v1/distributions/jammy/access \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .

Un tableau access vide signifie que la distribution est actuellement ouverte à tous.

2.2 Ajouter une règle d'accès

curl -s -X POST http://repod.example.com:8000/api/v1/distributions/jammy/access \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "principal_type": "group",
    "principal_id": "grp_a1b2c3d4"
  }' | jq .
Champ Valeurs Signification
principal_type role | group Indique si principal_id désigne un rôle personnalisé ou un groupe
principal_id chaîne custom_roles.id ou groups.id — l'id récupéré à l'étape 1

Réponse (201) :

{
  "access": {
    "id": "...",
    "codename": "jammy",
    "principal_type": "group",
    "principal_id": "grp_a1b2c3d4",
    "created_by": "admin",
    "created_at": "..."
  }
}

Exemple complet — donner au groupe security-team l'accès en écriture à jammy uniquement :

  1. Récupérer l'id du groupe : GET /api/v1/groups → trouver security-team, noter son id.
  2. Ajouter une règle pour jammy avec ce principal_id (comme ci-dessus). Aucune autre distribution n'est affectée — les règles distribution_access sont par codename, donc noble et almalinux9 restent ouvertes tant que vous n'ajoutez pas de règles pour elles aussi.
  3. Tout utilisateur qui n'est pas dans security-team (et n'est pas admin) obtient désormais 404 Not Found sur GET /distributions/jammy/packages, POST /upload/ ciblant jammy, et les opérations de promotion/migration touchant jammy en source ou en destination.

Plusieurs règles pour le même codename se combinent en union — une seule règle correspondante (rôle ou groupe) suffit. Il n'existe pas de mode intersection.

2.3 Supprimer une règle d'accès

curl -s -X DELETE http://repod.example.com:8000/api/v1/distributions/jammy/access/<entry_id> \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx"

Renvoie 204 en cas de succès, 404 si l'entrée n'existe pas. Supprimer la dernière règle d'un codename le rouvre à tout le monde.


3. Restreindre une machine ou un tag de machines

L'accès au niveau machine utilise une table distincte avec deux axes indépendants : qui obtient l'accès (user_principal_type/user_principal_id, même vocabulaire role/group que pour les distributions) et à quelle(s) machine(s) la règle s'applique (machine_principal_type/machine_principal_id, soit tag soit client).

3.1 Vérifier l'état actuel

curl -s "http://repod.example.com:8000/api/v1/inventory/machine-access" \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .

Filtrer par principal de machine avec des paramètres de requête :

curl -s "http://repod.example.com:8000/api/v1/inventory/machine-access?machine_principal_type=tag&machine_principal_id=prod" \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" | jq .

3.2 Ajouter une règle d'accès machine

curl -s -X POST http://repod.example.com:8000/api/v1/inventory/machine-access \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "user_principal_type": "group",
    "user_principal_id": "grp_a1b2c3d4",
    "machine_principal_type": "tag",
    "machine_principal_id": "prod"
  }' | jq .
Champ Valeurs Signification
user_principal_type role | group À qui la règle accorde l'accès
user_principal_id chaîne custom_roles.id ou groups.id
machine_principal_type tag | client Indique si la règle cible toutes les machines portant un tag, ou une machine spécifique
machine_principal_id chaîne Le nom du tag (ex. prod), ou l'id du client

Exemple complet — donner au groupe ops-team l'accès à toutes les machines taguées prod :

curl -s -X POST http://repod.example.com:8000/api/v1/inventory/machine-access \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "user_principal_type": "group",
    "user_principal_id": "<id du groupe ops-team>",
    "machine_principal_type": "tag",
    "machine_principal_id": "prod"
  }' | jq .

Une fois cette règle créée, toute machine taguée prod est restreinte aux membres d'ops-team (plus admin). Les machines sans le tag prod restent ouvertes, sauf si elles portent un autre tag qui possède également une règle.

Une règle client remplace les règles de tag, elle ne fusionne jamais avec elles

Si vous ajoutez une règle machine_principal_type: "client" pour une machine spécifique, cet ensemble de règles devient l'intégralité de l'ensemble de règles effectif pour cette machine — ses règles issues des tags sont totalement ignorées, jamais combinées avec la règle client. En l'absence de règle client, toutes les règles de chaque tag porté par la machine se combinent en union (une seule règle correspondante suffit). Voir Le modèle RBAC pour le raisonnement complet derrière ce choix.

3.3 Supprimer une règle d'accès machine

curl -s -X DELETE http://repod.example.com:8000/api/v1/inventory/machine-access/<entry_id> \
  -H "Authorization: Bearer repod_xxxxxxxxxxxxxxxx"

Renvoie 204 en cas de succès, 404 si l'entrée n'existe pas.


4. Vérifier que ça a fonctionné

En tant qu'utilisateur qui n'est ni dans le rôle/groupe autorisé ni admin :

# Restriction de distribution — attendu : 404, pas 403
curl -s -o /dev/null -w "%{http_code}\n" \
  http://repod.example.com:8000/api/v1/distributions/jammy/packages \
  -H "Authorization: Bearer <token d'un utilisateur non autorisé>"
# → 404

# Restriction de machine — attendu : le client filtré de la liste, pas une erreur
curl -s http://repod.example.com:8000/api/v1/inventory/clients \
  -H "Authorization: Bearer <token d'un utilisateur non autorisé>" | jq '.items[] | select(.id=="<id du client restreint>")'
# → aucune sortie — le client est omis silencieusement, pas renvoyé avec une erreur

En tant qu'utilisateur qui est dans le rôle/groupe autorisé :

curl -s -o /dev/null -w "%{http_code}\n" \
  http://repod.example.com:8000/api/v1/distributions/jammy/packages \
  -H "Authorization: Bearer <token d'un utilisateur autorisé>"
# → 200

Un 404 sur une ressource restreinte est délibéré et identique à la réponse pour une ressource qui n'existe réellement pas — c'est la conception « anti-fuite » décrite dans Le modèle RBAC. N'interprétez pas un 404 ici comme le signe d'une faute de frappe dans un codename ou un id de client ; vérifiez d'abord GET /distributions/{codename}/access ou GET /inventory/machine-access pour confirmer si une restriction est réellement en place.