Introduction

J’ai découvert récemment ArangoDB dans un projet opensource. Il s’avère qu’ArangoDB est parfaitement adapté aux données en graphe et inclut de base:

  • Une interface Web

  • Un outil de visualisation de graph

  • Un langage de requêtage : ArangoQL

Et pour rien enlever à tout ça, une simple image docker est nécessaire !

J’ai aussi profiter du travail de Darren Robinson qui a développé un module PowerShell pour SailPoint IdentityNow.

Extraire et formater la donnée

Il ne s’agit pas ici d’avoir une visualisation en temps réel mais bien d’avoir une analyse "à froid". Comme dit juste au-dessus, je vais utiliser le module IdentityNow pour extraire les données et utiliser les capacités de PowerShell pour formater et générer des fichiers JSON.

Je vous présenterai un rapide retour d’expérience sur PowerShell.

Bien démarrer avec le module PowerShell IdentityNow

Le README explique déjà comme configurer le module.

Ne souhaitant utiliser que le PAT (Personal Access Token), j’ai donc limité les commandes à :

$orgName = "customername-sb"
Set-IdentityNowOrg -orgName $orgName

# IdentityNow Personal Access Token as generated through the IdentityNow Portal and your personal identity profile preferences
$patClientID = 'yourClientID'
$patClientSecret = 'yourClientSecret'
$patCreds = [pscredential]::new("$($patClientID)", ($patClientSecret | ConvertTo-SecureString -AsPlainText -Force))

Set-IdentityNowCredential -PersonalAccessToken $patCreds
Save-IdentityNowConfiguration

Ceci a des effets de bord malheureusement mais qui ont pu être facilement fixé.

PowerShell 5 ou PowerShell Core 7 ?

J’aime PowerShell (5) car il est présent sur tous les postes de travail. Les prérequis sont minimes et l’on n’a même pas besoin d’être admin pour installer des modules. La version de base sur Windows 10 (même en dernier build) est la version 5. C’est une version vieillissante, bourrée de bug, et qui manque cruellement de cmdlets. Il est même probable que les performances soient moindre que PowerShell Core.

Les problèmes décrits ci-après sont inexistant sur PowerShell Core 7.

Module SailPointIdentityNow

Le module SailPointIdentityNow se veut compatible avec toutes les versions. Il fait un usage intensif de la cmdlet Invoke-RestMethod. Sur la version 5, Invoke-RestMethod n’utilise pas correctement les entêtes de la réponse et n’encode par correctement le retour d’IdentityNow. Du coup, on se retrouve avec les mêmes problèmes d’encodage d’il y a 10 ans…​

Encodage des fichiers

Par défaut, lorsqu’on utilise un encodage "UTF8", PowerShell ajoute un BOM que n’accepte pas du tout ArangoDB. L’astuce trouvée sur SO permet de forcer un encodage UTF8 sans BOM

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($targetFile, $content, $Utf8NoBomEncoding)

Formater la données

Pour ArangoDB, nous allons créer 2 jeux de données :

  • L’ensemble des sommets ou nœuds (vertices ou nodes en anglais)

  • L’ensemble des arêtes (edges en anglais)

ArangoDB support un tableau JSON ou des lignes JSON (une structure JSON par ligne). Dans la mesure où PowerShell permet de facilement générer des tableaux valides en JSON, j’ai choisi la première option.

Pour les sommets, un attribut _key doit être défini. Les autres attributs seront plus des métadonnées.

Pour les arêtes, il est nécessaire de définir les liaisons en utilisant les attributs _to et _from.

Par le biais des pipelines, PowerShell a des fonctionnalités très performantes pour formater la donnée. Ainsi, la cmdlet Select-Object permet de restreindre les champs, renommer des colonnes ou calculer des colonnes. Cela est beaucoup plus rapide qu’une boucle foreach et la création de PSCustomObject. La cmdlet Where-Object permet de très facilement filtrer la donnée. Finalement, ConvertTo-Json permet de convertir le tout en JSON.

ConvertTo-Json restreint la profondeur de la conversion. On voit donc souvent ConvertTo-Json -Depth 100 pour se prémunir de cette limitation.
$vertices += $sources | Select-Object name, description, sourceConnected, sourceConnectorName, ` (1)
        @{Name = 'color'; Expression = { $SOURCE_COLOR } }, ` (2)
        @{Name = '_key'; Expression = { $_.id } }, ` (3)
        @{Name = 'type'; Expression = { "source" } }
1 Limite la donnée aux propriétés name, description, sourceConnected et sourceConnectorName
2 Ajout d’une constante
3 La propriété _key prend la valeur de la propriété _id

Afficher le graphe

Démarrer ArangoDB

Comme évoqué, nous allons utiliser l’image docker. Pour démarrer l’image, on peut utiliser la commande suivante :

docker run -p 8529:8529 -e ARANGO_ROOT_PASSWORD=openSesame arangodb/arangodb:3.8.0

Il suffit alors de se connecter à http://localhost:8529/ avec le login/mot de passe root/openSesame.

Utiliser la base _SYSTEM proposée par défaut.

Importer les données

Il faut créer 2 collections, au travers de l’interface Web, dans le menu "Collections" :

  • Une collection pour les sommets (idnVertices)

  • Une collection pour les arrêtes (idnEdges)

L’interface permet de transférer le fichier JSON pour chacune des collections.

Visualiser la donnée.

Il est possible de créer un graphe mettant en relation les sommets et les arêtes :

Graph

On peut alors configurer l’attribut utilisé pour l’affichage, l’attribut pour la couleur, etc. :

Graph
L’attribut utilisé pour la couleur ne permet pas de définir le code couleur mais s’assure que 2 sommets ayant la même valeur auront la même couleur.

Et voilà!

Graph

Requêter la donnée

On peut utiliser le langage AQL pour interroger la base et les relations. L’interface Web permet d’exécuter les requêtes et de visualiser les résultats.

Graph
En appuyant sur Ctrl+Enter, la requête est exécutée.

Pour connaître les profils d’accès associés à un rôle :

FOR c IN idnVertices
    FILTER c.name == "Receivable Accountant"
    FOR v IN 1..2 OUTBOUND c idnEdges
        RETURN DISTINCT v

Pour connaître les profils d’accès et les sources associés à un rôle :

FOR c IN idnVertices
    FILTER c.name == "Receivable Accountant"
    FOR v IN 1..2 OUTBOUND c idnEdges
        RETURN DISTINCT v

Pour connaître uniquement les sources associés à un rôle :

FOR c IN idnVertices
    FILTER c.name == "Receivable Accountant"
    FOR v IN 2 OUTBOUND c idnEdges
        RETURN DISTINCT v

Inversement, il est possible de connaître les profils d’accès associés à une source :

FOR c IN idnVertices
    FILTER c.name == "Microsoft 365"
    FOR v IN 1 INBOUND c idnEdges
        RETURN  v

Il est possible de connaître les rôles associés (en exluant les applications) à une source :

FOR c IN idnVertices
    FILTER c.name == "Microsoft 365"
    FOR v IN 2 INBOUND c idnEdges
        FILTER v.`type` != 'application'
        RETURN  v

Pour retourner les applications et les rôles associés à une source :

FOR c IN idnVertices
    FILTER c.name == "Microsoft 365"
    FOR v IN 2 INBOUND c idnEdges
        RETURN  {name:v.name,type:v.type}

Conclusion

Le code complet a été déposé sur GitHub.

ArangoDB est souvent vu comme une base versatile à la fois orientée graph et document. Ceci est un premier essai qui a montré la simplicité d’utilisation de la base, grâce à un outillage et un packaging très adapté à ce projet.

Il s’agira certainement de "charger" un peu la base avec plus de relation, plus d’objets et voir comment se comporte le système.

L’utilisation combinée de PowerShell pour l’extraction et le formatage de la donnée et d’ArangoDB pour le stockage, le requêtage et la visualisation ouvre de belles perspectives.