Authz : Backend d'autorisations utilisant ABAC et RBAC
La gestion des autorisations dans les applications doit être simple et centralisée.
J'ai donc, avec Authz, nouveau projet open-source, voulu simplifier ceci.
Un principal
souhaite effectuer une action
sur une ressource
. Cela lui est possible en fonction de policies
et/ou de roles
définis dans le backend Authz.
Pour cela, il existe plusieurs façons possibles dont principalement : par attribution de rôle (RBAC) ou par règles définies permettant de mettre en relation un principal avec une ressource par rapport à des attributs (ABAC).
Commençons par voir les différents termes que nous allons utiliser.
Description des différents objets
- Principal : Ce terme générique permet de regrouper quelque-chose qui cherche à effectuer une action sur une ressource. Il peut s'agir d'un utilisateur, d'un compte de service ou encore d'un groupe d'utilisateurs,
- Resource : Il s'agit d'un objet sur lequel on peut effectuer une action : par exemple, un article sur un CMS. Cette ressource contient un type (appelé "kind" dans Authz : article) ainsi qu'un identifiant,
- Action : Une action est quelque-chose qui peut être effectué sur une ressource, par exemple, sur nos article, nous pouvons les créer, éditer, supprimer. Ces trois éléments sont des actions.
- Policy : Une policy est une règle permettant de définir quelles actions peuvent être appliquées sur quelles ressources,
- Role : Un rôle regroupe un ensemble de policy et permet donc de définir un ensemble d'actions réalisables un plusieurs ressources. Il est attribué à un principal.
Authz permet de gérer à la fois des autorisations ABAC ou RBAC et même d'utiliser les deux en même temps. Voyons ça plus en détail.
Autorisations de type Attribute-Based Access Control (ABAC)
Ce modèle, plus flexible que par l'attribution par rôle, permet de décrire des règles d'autorisations en fonction des attributs positionnés sur les principals
et ressources
.
Imaginons par exemple un attribut owner_id: 123
sur un article de notre CMS car il a été écrit par l'utilisateur ayant pour identifiant 123
.
Lors de la déclaration de notre principal
(utilisateur), nous allons donc lui positionner un attribut id: 123
.
Maintenant, nous pouvons ajouter une policy
permettant d'effectuer les actions edit
et delete
sur les ressources article.*
(tous les articles).
Nous y ajoutons également la règle suivante : resource.owner_id == principal.id
.
Une policy peut également disposer de plusieurs règles.
Une fois cette policy en place, notre utilisateur dont l'identifiant est 123
aura donc la permission d'éditer et supprimer les articles dont il est le propriétaire.
Autorisations de type Role-Based Access Control (RBAC)
Côté attribution de rôles, cela est plus simple.
Il suffit en effet de créer une policy
permettant d'effectuer les actions edit
et delete
sur les ressources article.*
(tous les articles) sans spécifier de règles d'attribut.
Cette policy
peut ensuite être ajoutée dans un role
, qui peut contenir plusieurs policies.
Le role
sera ensuite attribué à des principal
, ce qui les autorisera donc à pouvoir éditer et supprimer tous les articles.
Architecture
Comment fonctionne donc Authz ?
Il s'agit d'un backend centralisé qui pourra être utilisé par vos applications à l'aide d'appels API HTTP ou gRPC.
Pour cela, vous pourrez créer un compte de service qui vous donnera un client_id
et client_secret
à utiliser pour l'authentification.
Vous pouvez également utiliser l'un des SDK disponible, pour le moment dans les langages suivants :
- SDK Go : https://github.com/eko/authz/tree/master/sdk,
- SDK PHP : https://github.com/eko/authz-php-sdk,
- SDK Python : https://github.com/eko/authz-python-sdk,
- d'autres à venir bientôt !
Vos applications pourront ainsi :
- Déclarer et modifier / supprimer des principals,
- Déclarer et modifier / supprimer des ressources,
- Vérifier si un principal dispose d'une autorisation.
Le backend s'occupe de mettre à plat les policies qui permettent de donner des accès aux principals.
Utilisation des SDKs
Ici, je vais démontrer uniquement le SDK Go mais la documentation est disponible sur l'ensemble des repositories pour les autres SDKs.
Première étape, installer le SDK dans votre application :
$ go get github.com/eko/authz/sdk@latest
Ensuite, il vous faut connecter et identifier votre application au backend :
authzClient, err := sdk.NewClient(&sdk.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
GrpcAddr: "localhost:8081",
})
Vous pouvez à présent déclarer un principal :
response, err := authzClient.PrincipalCreate(ctx, &authz.PrincipalCreateRequest{
Id: "user-123",
Attributes: []*authz.Attribute{
{Key: "email", Value: "johndoe@acme.tld"},
},
})
Déclarer une ressource :
response, err := authzClient.ResourceCreate(ctx, &authz.ResourceCreateRequest{
Id: "post.456",
Kind: "post",
Value: "456",
Attributes: []*authz.Attribute{
{Key: "owner_email", Value: "johndoe@acme.tld"},
},
})
Vous pouvez apercevoir que nous avons ici déclarés des attributs sur nos ressources. Nous utilisons donc le modèle ABAC.
Déclarons maintenant une policy avec la règle permettant de matcher ces attributs :
import (
"github.com/eko/authz/backend/sdk/rule"
)
response, err := authzClient.PolicyCreate(ctx, &authz.PolicyCreateRequest{
Id: "post-owners",
Resources: []string{"post.*"},
Actions: []string{"edit", "delete"},
AttributeRules: []string{
rule.AttributeEqual(
rule.PrincipalResourceAttribute{
PrincipalAttribute: "email",
ResourceAttribute: "owner_email",
},
),
},
})
Enfin, vous pouvez vérifier si votre principal dispose de l'accès nécessaire pour éditer l'article :
isAllowed, err := authzClient.IsAllowed(&authz.Check{
Principal: "user-123",
ResourceKind: "post",
ResourceValue: "456",
Action: "edit",
})
if err != nil {
// Log error
}
if isAllowed {
// Do something
}
Conclusion
Vous savez maintenant comment fonctionne Authz et êtes prêts à commencer !
Le projet est open-source sous license MIT, vous êtes donc les bienvenus si vous souhaitez contribuer ou échanger sur des fonctionnalités. Je serai ravi d'échanger avec vous !
Rendez-vous sur https://github.com/eko/authz.