Authz : Backend d'autorisations utilisant ABAC et RBAC

Authz

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)

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)

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 ?

RBAC

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 :

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/

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: ""},
    },
})

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: ""},
    },
})

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.