[:fr]

 Si vous cherchez pour vos maquettes un service d’identité SCIM complet et protégé par OAuth 2.0 vous pouvez embarquer Sparrow.

 

Refonder LDAP sur un service d’identité :

LDAP est un héritage du 20ème siècle et des grandes normes ISO X400 et X500. C’est donc une vieille dame dont il est question. Bien que révisée au 21ème siècle dans sa version v3, nous sommes encore sur des principes d’informatique distribuée reposant sur du client / serveur.

Il était temps de refonder ce service d’annuaire.

Le travail de Kiran Ayyagari avec Sparrow est une complète réécriture du service en Go. Mais il ne garde de LDAP que la notion de session (bind, unbind), recherche d’objet utilisateur et changement de mot de passe.

De fait il ne supporte pas tout un tas de fonction comme le Referral, l’Update … Pour la gestion des objets, il met à disposition une API basée sur SCIM. Cette refondation sur un service d’identité pur est la principale innovation de ce projet.

Sparrow gère trois type d’entité :

  • Des utilisateurs
  • Des groupes
  • Des objets

Toute la logique de schéma repose sur des fichiers JSON, par exemple un enregistrement d’identité avec ses attributs :

 

{
    "schemas":[
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "userName":"bjensen",
    "externalId":"bjensen",
    "name":{
        "formatted":"Ms. Barbara J Jensen III",
        "familyName":"Jensen",
        "givenName":"Barbara"
    }
}

Sparrow est donc fondamentalement un serveur SCIM exposant quelques fonctions en mode LDAP pour des utilisateurs et des groupes.

Ce serveur est multi domaines, ce qui permet de gérer plusieurs natures de populations disjointes.

 

Identifier vs Autoriser :

Dans les concepts d’OpenId Connect il est assez difficile de faire la part de ce qui revient au serveur d’autorisation et au fournisseur d’identité.

OpenID Connect implements authentication as an extension to the OAuth 2.0 authorization process. Use of this extension is requested by Clients by including the openid scope value in the Authorization Request.

Donc j’obtiens des informations d’identification au travers d’une autorisation sur un objet qui me demande une authentification. Il faut suivre 😉

Au moins avec Sparrow c’est plus simple c’est un serveur d’autorisation OAuth 2.0 qui permet l’enregistrement dynamique des clients et supporte l’Authorization code flow. De fait c’est même trop simple de devenir Client du serveur, il suffit d’un compte sur l’annuaire.

Toute demande sur une ressource SCIM passe par un client qui aura obtenu une autorisation sur les données. Sparrow dispose d’un modèle de rôle RBAC basique (pas de hiérarchie) qui est associée à la session et permet de contrôler les droits de modification, création et suppression. Dans le code ci- dessous, on notera que seul un administrateur ou le propriétaire de la données peut modifier cette dernière.

//http.go func createResource(hc *httpContext)
// Cet appel au fournisseur de données (Provider) peut retourner une erreur
 createCtx := base.CreateContext{InRes: rs, OpContext: hc.OpContext}
 insertedRs, err := hc.pr.CreateResource(&createCtx)
 if err != nil {
  writeError(hc.w, err)
 return
}

//Provider.go
//Cette fonction évalue l’autorisation Rbac de l’utilisateur
func (prv *Provider) CreateResource(crCtx *base.CreateContext) (res *base.Resource, err error) {
 if !crCtx.Session.IsAllowCreate() {
 return nil, base.NewForbiddenError("Insufficent privileges to create a resource")
 }
 return prv.sl.Insert(crCtx.InRes)
}
//fonction de modification des données limitée à l'administrateur ou le propriétaire
func (prv *Provider) Replace(replaceCtx *base.ReplaceContext) (res *base.Resource, err error) {
 // allow an admin always, but normal user when the resource belongs to self
  if !replaceCtx.Session.IsAllowUpdate() && (replaceCtx.Rid != replaceCtx.Session.Sub) {
   return nil, base.NewForbiddenError("Insufficent privileges to replace the resource")
  }
  return prv.sl.Replace(replaceCtx.InRes, replaceCtx.IfNoneMatch)
}

 

Les « dessous de la mariée » :

La force d’un annuaire repose sur sa capacité à gérer des données. Pour cela Kiran à fait le choix de github.com/coreos/bbolt un fork de bolt, lui-même hérité de LMDB. En gros un dictionnaire de données dans un seul fichier avec un index de type B+tree. Cela assure de bonnes performances en lecture, un peu moins en écriture.

Pour classer les données, on utilise la bonne vieille méthode: “une table (bucket) par objet et et chaque attribut sa table (bucket)”. Le système n’est pas relationnel et c’est à l’application de faire les boucles de recherche pour trouver l’ensemble des informations. Chaque domaine de données dispose de sa base (ou silo dans la conception de Sparrow) et de sa persistance des jetons OAuth.

Sparrow ne propose pas encore de système de réplication comme pour un annuaire LDAP standard. De plus une base bbolt ne supporte pas plusieurs accès en écriture, ni plusieurs ouverture en mode écriture. Cela rend donc problématique le partage de fichier entre plusieurs instance de Sparrow. C’est clairement une limitation de la version actuelle. Kiran a prévu de développer cette réplication Multi-Maître.

Personnellement je pense qu’il aurait pu tirer parti de fonction système comme HDFS ou des bases qui fonctionnent déjà en cluster comme etcd par exemple. Si cette option vous tente, il faut simplement modifier la “classe” silo et mettre en place une nouvelle gestion de données.

3 captures d’écran fait avec boltdbweb:

  • Les tables (bucket) contenant des attributs (ici les objets)
  • La table des attributs mail (une seule clé pas de valeur)
  • La table des membres de groupe (le premier est l’administrateur)

 

Sparrow est un petit projet, mais avec une vision claire de ce que doit être un service d’identité au 21ème siècle.[:en]

 If you are looking for a complete SCIM identity service protected by OAuth 2.0 for your models, you can ship with Sparrow.

Rebuild LDAP on an identity service:

LDAP is a legacy of the 20th century and the great ISO X400 and X500 standards. So it’s an old lady that’s being talked about. Although revised in the 21st century in its version v3, we are still on principles of distributed computing based on the client / server.

It was time to rebuild this directory service.

Kiran Ayyagari’s work with Sparrow is a complete rewrite of the service in Go. But he keeps only LDAP the notion of session (bind, unbind), search for user object and change password.

In fact it does not support a lot of functions like Referral, Update … For the management of objects, it provides a SCIM-based API. This refoundation on a pure identity service is the main innovation of this project.

Sparrow manages three types of entities:

  • Users
  • Groups
  • Objects (devices)

All schema logic relies on JSON files, such as an identity record with its attributes.

Sparrow is basically a SCIM server exposing some functions in LDAP mode for users and groups.

This server is multi domains, which allows to manage several natures of disjointed populations.

Identify vs. Allow:

In the concepts of OpenId Connect it is quite difficult to distinguish between what is the authorization server and the identity provider.

OpenID Connect implements authentication as an extension to the OAuth 2.0 authorization process. Use of this extension is requested by Clients in the scope of the application in the Authorization Request.

So I get credentials through an authorization on an object that requires me to authenticate. You must follow 😉

At least with Sparrow it’s simplier, the embedded OAuth 2.0 Authorization Server allows the dynamic registration of clients and supports the Authorization code flow. In fact it’s even too simple to become a server client, all you need is an account on the directory.

Any request on a SCIM resource goes through a client that has obtained authorization on the data. Sparrow has a basic RBAC role model (no hierarchy) that is associated with the session and controls the rights to edit, create, and delete. In the code below, it should be noted that only an administrator or the owner of the data can modify the latter.

look behind the curtain

The strength of a directory is its ability to manage data. For that Kiran made the choice of github.com/coreos/bbolt a fork of bolt, himself inherited from LMDB. Basically a data dictionary in a single file with an index of type B + tree. This ensures good reading performance, a little less writing.

To classify the data, one uses the good old method: « a table (bucket) by object and and each attribute its table (bucket) ». The system is not relational and it is up to the application to do the search loops to find all the information. Each data domain has its base (or silo in Sparrow’s design) and its persistence of OAuth tokens.

Sparrow does not yet offer a replication system as for a standard LDAP directory. Moreover, a bbolt base does not support several write accesses, nor several opening in write mode. This makes file sharing between several Sparrow instances problematic. This is clearly a limitation of the current version. Kiran has planned to develop this Multi-Master replication.

Sparrow is a small project, but with a clear vision of what an identity service should be in the 21st century.[:]

Stéphane POPOFF

Architecte Sécurité