Qu'est-ce que l'ABAC ? Contrôle d'accès basé sur les attributs avec exemples
Qu'est-ce que l'ABAC ?
Le contrôle d'accès basé sur les attributs (ABAC) accorde ou refuse une requête en évaluant des attributs contre des règles, au lieu de rechercher qui est l'utilisateur ou quel rôle il détient. Le NIST, qui a publié la définition de référence dans SP 800-162, regroupe les entrées en quatre types :
| Attributs de | Exemples |
|---|---|
| Le sujet (utilisateur ou service) | département, niveau d'habilitation, type de contrat, âge |
| L'objet (ressource) | propriétaire, département, classification, statut |
| L'action | lire, modifier, approuver, supprimer |
| L'environnement | heure de la journée, adresse IP ou réseau, appareil, emplacement |
Une règle est une condition portant sur ces attributs, par exemple « un utilisateur peut lire un document s'il appartient au même département que le document, pendant les heures ouvrables ». Comme la règle fait référence aux attributs plutôt qu'à des utilisateurs ou rôles nommés, les nouveaux utilisateurs et les nouveaux documents sont couverts sans ajouter aucune règle.
Casbin maintient ABAC simple : vous passez des structures ou des objets dans Enforce() et référencez leurs champs dans le matcher. Des applications complètes sont disponibles dans les tutoriels ABAC pour Go, Node.js avec Express et Python avec Flask.
ABAC vs RBAC
RBAC décide en fonction des rôles de l'utilisateur : « les éditeurs peuvent modifier les documents ». ABAC décide en fonction des attributs : « le propriétaire peut modifier le document ». Les rôles sont faciles à auditer, car vous pouvez lister ce qu'un rôle autorise et qui le détient ; les attributs expriment des règles concernant des enregistrements spécifiques et le contexte, tels que la propriété, le département ou l'heure, que les rôles seuls ne peuvent pas exprimer sans créer un rôle par enregistrement. La plupart des applications les combinent : les rôles décident quelles fonctionnalités un utilisateur peut atteindre, et les conditions basées sur les attributs restreignent cela aux enregistrements qu'il peut toucher. Choisir un modèle de contrôle d'accès compare ACL, RBAC, ABAC et ReBAC sur un exemple unique et montre comment combiner RBAC et ABAC dans un seul modèle Casbin.
Points forts et faiblesses
- Bon pour : la propriété (« uniquement les leurs »), le contexte (heures ouvrables, réseau du bureau) et les données portant leurs propres étiquettes (département, région, sensibilité). Une seule règle peut remplacer de nombreuses concessions de rôles.
- Faible pour : l'audit. « Qui peut lire ce document ? » n'a pas de réponse directe ; vous devez évaluer la règle contre chaque utilisateur. Les règles ont également besoin des attributs à portée de main, donc l'application charge généralement l'enregistrement avant le contrôle.
Exemple minimal :
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == r.obj.Owner
Ainsi, r.obj doit être un objet possédant un champ Owner ; Casbin y accède via réflexion. En Go, vous pourriez définir :
type testResource struct {
Name string
Owner string
}
Vous pouvez également passer des chaînes JSON ; activez la gestion JSON et Casbin les analysera :
e, _ := NewEnforcer("examples/abac_model.conf")
e.EnableAcceptJsonRequest(true)
data1Json := `{ "Name": "data1", "Owner": "bob"}`
ok, err := e.Enforce("alice", data1Json, "read")
if err != nil {
// Handle JSON parsing errors
fmt.Printf("Enforcement failed: %v\n", err)
return
}
Lorsque activé, tout paramètre commençant par { ou [ est analysé comme du JSON. Un JSON invalide produit une erreur claire ; les autres chaînes restent telles quelles.
// Valid JSON - automatically parsed
validJSON := `{"Name": "alice", "Age": 25}`
ok, err := e.Enforce(validJSON, "data1", "read") // Works correctly
// Invalid JSON - returns descriptive error
invalidJSON := `{"Name": "alice",}` // Trailing comma is invalid in JSON
ok, err := e.Enforce(invalidJSON, "data1", "read")
// Returns: "failed to parse JSON parameter at index 0: ..."
// Plain string - no parsing attempted
plainString := "alice"
ok, err := e.Enforce(plainString, "data1", "read") // Treated as plain string
L'activation de la prise en charge des paramètres JSON introduit une surcharge de performance d'environ 1,1 à 1,5x.
Attributs d'environnement
La requête peut transporter plus que sub, obj et act. Ajoutez un champ pour l'environnement et passez-le à Enforce() comme tout autre objet. Ce modèle permet au propriétaire de modifier son document à tout moment, et permet aux personnes du même département de le lire entre 9h00 et 18h00 :
[request_definition]
r = sub, obj, act, env
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub.Name == r.obj.Owner || (r.act == "read" && r.sub.Department == r.obj.Department && r.env.Hour >= 9 && r.env.Hour < 18)
type User struct{ Name, Department string }
type Doc struct{ Name, Owner, Department string }
type Env struct{ Hour int }
doc := Doc{Name: "design.md", Owner: "alice", Department: "design"}
bob := User{Name: "bob", Department: "design"}
ok, _ := e.Enforce(bob, doc, "read", Env{Hour: 10}) // true
ok, _ = e.Enforce(bob, doc, "read", Env{Hour: 22}) // false: outside business hours
ok, _ = e.Enforce(bob, doc, "edit", Env{Hour: 10}) // false: bob is not the owner
Utilisation d'ABAC
- Référencez les attributs dans le matcher (par ex.
r.sub.Role,r.obj.Owner). - Passez des instances de structure ou de classe (ou du JSON) dans
Enforce().
L'accès aux attributs ABAC fonctionne uniquement pour les éléments de requête (r.sub, r.obj, r.act). Les éléments de politique comme p.sub ne peuvent pas utiliser ABAC car les politiques ne peuvent pas stocker de définitions de structures ou de classes.
Les matchers peuvent référencer plusieurs attributs simultanément. Exemple : m = r.sub.Domain == r.obj.Domain.
Lorsque les politiques nécessitent des virgules qui entreraient en conflit avec l'analyse CSV, enveloppez l'expression entre guillemets. Exemple : "keyMatch("bob", r.sub.Role)" empêche les séparations indésirables.
Règles complexes avec eval()
Pour des conditions plus complexes, placez les expressions dans la politique et évaluez-les avec eval() afin que le modèle reste petit et que les politiques restent flexibles.
Configuration du modèle avec eval() :
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub_rule, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = eval(p.sub_rule) && r.obj == p.obj && r.act == p.act
p.sub_rule est une expression portant sur les attributs de la requête, évaluée au moment de l'application. Exemple de politique :
p, r.sub.Age > 18, /data1, read
p, r.sub.Age < 60, /data2, write
FAQ
ABAC est-il meilleur que RBAC ? Aucun n'est globalement meilleur. ABAC exprime des règles plus fines ; RBAC est plus facile à examiner. Commencez par les rôles et ajoutez des conditions basées sur les attributs là où les rôles cessent de convenir, comme la propriété ou les fenêtres temporelles.
Quelle est la différence entre ABAC et PBAC ? ABAC indique sur quoi se basent les décisions (attributs). PBAC indique comment les règles sont gérées : comme des données de politique évaluées à l'exécution. Le motif eval() ci-dessus est les deux : des conditions basées sur les attributs stockées comme politique.
ABAC est-il identique à XACML ? Non. XACML est un langage standard OASIS pour écrire des politiques ABAC. Casbin n'utilise pas XACML ; les règles sont écrites dans le matcher du modèle ou stockées sous forme de lignes de politique.
Puis-je essayer ABAC sans écrire de code ? Oui. Choisissez un exemple ABAC dans l'éditeur en ligne et modifiez le matcher et la requête.
Comments are powered by giscus and GitHub Discussions. They load from giscus.app and GitHub only after you click the button below.