Import, export et format JSON
Sur cette page
Un graphe d’authentification est un document JSON. La console l’enregistre pour vous, mais le format compte dès qu’il faut copier des graphes d’un environnement à l’autre, les versionner dans Git ou les générer par script. Cette page décrit l’export et l’import dans la console, puis le format lui-même.
Exporter des graphes#
Dans la liste Graphes d’authentification, le bouton Exporter (raccourci E) ouvre la liste des graphes du royaume, tous cochés par défaut.
L’option Inclure les sous-graphes référencés, cochée par défaut, ajoute au fichier chaque sous-graphe appelé par un SubGraphNode des graphes choisis, et ceux qu’il appelle à son tour : le fichier se suffit à lui-même. Le fichier téléchargé s’appelle tosiam-authgraphs-<royaume>-<date>.json, par exemple tosiam-authgraphs-royaume-racine-2026-10-02.json.
Importer des graphes#
Le bouton Importer (raccourci I) accepte un ou plusieurs fichiers JSON. La console lit trois formes :
- un fichier d’export (enveloppe décrite plus bas) ;
- un graphe seul,
{"startNodeId": …, "steps": …}, nommé d’après le fichier (connexion.jsondonneconnexion) ; - un objet
{"nom": graphe, …}qui associe des noms à des graphes.
Avant d’enregistrer, la fenêtre liste ce qui va être importé, dans quel royaume, et signale les noms qui existent déjà.
| Choix pour un nom existant | Effet |
|---|---|
| Ignorer (par défaut) | Le graphe du royaume est conservé, celui du fichier n’est pas importé. |
| Remplacer | Le graphe du royaume est écrasé par celui du fichier. |
| Copier | Le graphe du fichier est créé sous un nouveau nom : <nom>-imported, puis <nom>-imported-2… |
Un graphe est importé comme sous-graphe s’il figure dans la liste subGraphs de l’enveloppe, s’il déclare des parameters ou s’il contient un SubGraphExitNode. Les sous-graphes sont enregistrés en premier, avant les graphes qui les appellent.
La fenêtre signale aussi :
- les fichiers ignorés, qui ne sont pas du JSON ou ne contiennent aucun graphe ;
- un même nom défini dans plusieurs fichiers : la première lecture est conservée ;
- les sous-graphes référencés manquants, appelés par un graphe mais absents du fichier et du royaume : les graphes qui les appellent ne fonctionneront pas tant qu’ils n’existent pas.
La console ne vérifie pas la structure des graphes : c’est le serveur qui la contrôle à l’enregistrement. Si un graphe est refusé, le rapport Import : ce qui n’a pas pu être enregistré donne la raison renvoyée par le serveur, par exemple une étape qui pointe vers un nœud inexistant.
Le fichier d’export#
{
"tosiam": "authgraph-export",
"version": 1,
"exportedAt": "2026-10-02T06:01:49.630Z",
"graphs": {
"doc-collecteurs": { "startNodeId": "userData", "steps": { … } },
"google-social-login": { "startNodeId": "google-social-login", "steps": { … } },
"google-social-auth": { "startNodeId": "google-redirect", "steps": { … }, "parameters": [ … ] }
},
"subGraphs": ["google-social-auth"]
}| Champ | Contenu |
|---|---|
tosiam, version | Marque du format : authgraph-export, version 1. |
exportedAt | Date de l’export (UTC). |
graphs | Les graphes et les sous-graphes, indexés par leur nom. |
subGraphs | Les noms, parmi graphs, à enregistrer comme sous-graphes. Absent s’il n’y en a pas. |
Le fichier ne mentionne pas le royaume d’origine : on peut l’importer dans n’importe quel royaume.
Format d’un graphe#
Un graphe contient deux champs : startNodeId, l’identifiant de la première étape, et steps, les étapes indexées par leur identifiant. Les autres champs à la racine sont ignorés.
{
"startNodeId": "userData",
"steps": {
"userData": {
"type": "PageNode",
"nodes": [
{ "type": "UsernameCollectorNode", "layout": { "name": "Saisie de l'identifiant" } },
{ "type": "PasswordCollectorNode", "layout": { "name": "Saisie du mot de passe" } }
],
"outcomes": { "outcome": "authenticate" },
"layout": { "x": 40, "y": 140, "name": "Page" }
},
"authenticate": {
"type": "DataStoreNode",
"config": { "authLevel": 0 },
"outcomes": { "true": "success", "false": "failure" },
"layout": { "x": 400, "y": 150, "name": "Décision datastore" }
},
"success": { "type": "SuccessNode", "layout": { "x": 1060, "y": 60, "name": "Succès" } },
"failure": { "type": "FailureNode", "layout": { "x": 1060, "y": 480, "name": "Échec" } }
}
}C’est le graphe doc-collecteurs de la page Nœuds : collecteurs, tel que le serveur le renvoie.
| Champ d’une étape | Rôle |
|---|---|
type | Type du nœud (obligatoire), par exemple DataStoreNode. Les types et leurs réglages sont décrits dans les pages de nœuds. |
config | Réglages du nœud. Les valeurs sont des chaînes, des nombres, des booléens ou des objets. |
outcomes | Pour chaque sortie du nœud, l’identifiant de l’étape suivante. Une sortie absente n’est reliée à rien. |
nodes | Nœuds enfants d’une page (PageNode), voir plus bas. |
layout | Position et libellé dans l’éditeur : x, y, name. Ignoré à l’exécution ; sans layout, l’éditeur place les nœuds lui-même. |
stage | Nom de l’étape, renseigné par la console ; facultatif. |
Le serveur refuse le graphe, avec le message correspondant, si :
startNodeIdmanque, ou ne désigne aucune étape ;stepsest vide, ou compte plus de 50 étapes ;- une étape n’a pas de
type; - une sortie pointe vers une étape inexistante.
Il ne détecte pas les sorties non reliées ni les étapes inaccessibles : ces contrôles, avec quelques autres, sont faits par l’éditeur (voir Validation). Ouvrez un graphe écrit à la main dans l’éditeur pour les voir.
Une page, plusieurs nœuds#
Un PageNode affiche sur un seul écran les champs de plusieurs nœuds, par exemple l’identifiant et le mot de passe. Ses nœuds enfants se déclarent dans le tableau nodes, dans l’ordre d’affichage. Chaque enfant n’a que type, config et layout : pas d’identifiant ni de sorties.
À l’exécution, la page exécute ses enfants dans l’ordre et regroupe leurs champs dans une seule réponse. Si un enfant échoue, la page échoue. Sinon la page sort par son unique sortie, outcome : les sorties propres aux enfants ne sont pas prises en compte. Une page n’a donc de sens qu’avec des nœuds qui collectent une saisie.
Dans l’éditeur, le nœud s’appelle Page (catégorie Session & utilitaires). On y ajoute des enfants en déposant un nœud de la palette sur sa carte, ou avec Ajouter un nœud ; chaque enfant se range avec Monter, Descendre et Retirer de la page. L’éditeur refuse comme enfant les nœuds terminaux, les nœuds de sous-graphe, une autre page et le nœud de décision scriptée.
Sous-graphes paramétrés#
Un sous-graphe a le même format qu’un graphe, avec un tableau parameters facultatif à la racine. Il ne se termine pas par SuccessNode ou FailureNode (le serveur le refuse à l’exécution), mais par des SubGraphExitNode, dont chaque exitName devient une sortie du SubGraphNode qui l’appelle.
Sous-graphe verif-otp-courriel :
{
"startNodeId": "envoi",
"parameters": [
{ "name": "longueur", "description": "Nombre de chiffres du code", "default": "6" }
],
"steps": {
"envoi": { "type": "EmailOtpSendNode", "config": { "otpLength": "${longueur}" }, "outcomes": { "outcome": "controle" } },
"controle": { "type": "EmailOtpVerifyNode", "outcomes": { "true": "ok", "false": "ko" } },
"ok": { "type": "SubGraphExitNode", "config": { "exitName": "valide" } },
"ko": { "type": "SubGraphExitNode", "config": { "exitName": "refuse" } }
}
}Appel depuis un graphe :
"verif": {
"type": "SubGraphNode",
"config": { "subGraphName": "verif-otp-courriel", "parameters": { "longueur": "8" } },
"outcomes": { "valide": "success", "refuse": "failure" }
}| Champ d’un paramètre | Rôle |
|---|---|
name | Nom, utilisé sous la forme ${name} dans les réglages du sous-graphe. |
description | Aide affichée dans la console. |
default | Valeur par défaut. Un paramètre sans valeur par défaut est obligatoire : si l’appelant ne le fournit pas, l’exécution échoue. |
secret | true pour une valeur sensible (secret client, clé). La valeur reste en clair dans le graphe appelant et dans les exports. |
Le remplacement de ${name} a des limites :
- il ne s’applique qu’aux réglages de premier niveau de type chaîne : pas aux valeurs imbriquées dans un objet (comme
propertiesdeSetSessionPropertiesNode), ni aux enfants d’une page ; - un sous-graphe ne doit pas s’appeler lui-même, directement ou non : rien ne limite la profondeur d’appel.
Par l’API REST#
La console utilise l’API REST d’administration, servie sous /tosiam/api. Le royaume racine s’écrit root dans le chemin.
| Méthode et chemin | Action |
|---|---|
GET /realms/{realm}/authgraphs | Lister les graphes |
POST /realms/{realm}/authgraphs | Créer un graphe ; son nom est le champ _id du corps |
GET /realms/{realm}/authgraphs/{nom} | Lire un graphe |
PUT /realms/{realm}/authgraphs/{nom} | Remplacer un graphe, ou le créer s’il n’existe pas |
DELETE /realms/{realm}/authgraphs/{nom} | Supprimer un graphe |
Les sous-graphes ont les mêmes opérations sous /realms/{realm}/subgraphs. GET /authgraph-node-types liste les types de nœuds et leurs réglages.
Trois points diffèrent des API /json :
- la session administrateur se passe en cookie (
iPlanetDirectoryPro), pas en en-tête ; - les écritures (
POST,PUT,DELETE) exigent le jeton anti-CSRF : le serveur le renvoie dans l’en-têteX-XSRF-TOKENde toute réponse, et il doit revenir à la fois en cookieXSRF-TOKENet en en-têteX-XSRF-TOKEN; - le corps est de type
application/vnd.tosiam+json;application/jsonest refusé (415).
SERVEUR=https://<serveur>/tosiam
SSO=<jeton de session administrateur> # obtenu par /json/authenticate
# 1. Une lecture renvoie le jeton anti-CSRF
XSRF=$(curl -s -D - -o /dev/null -b "iPlanetDirectoryPro=$SSO" \
"$SERVEUR/api/realms/root/authgraphs" \
| awk 'tolower($1)=="x-xsrf-token:" {print $2}' | tr -d '\r')
# 2. Création ou remplacement du graphe « connexion »
curl -X PUT "$SERVEUR/api/realms/root/authgraphs/connexion" \
-b "iPlanetDirectoryPro=$SSO; XSRF-TOKEN=$XSRF" \
-H "X-XSRF-TOKEN: $XSRF" \
-H "Content-Type: application/vnd.tosiam+json" \
-d @connexion.json| Réponse | Cas |
|---|---|
201 | POST : graphe créé |
200 | PUT : graphe remplacé ou créé ; DELETE : {"_id": …, "deleted": true} |
400 | Graphe mal formé, avec le message du serveur, par exemple Invalid graph definition: Step 'x' outcome 'a' references unknown step 'nope' |
401 | Session absente ou expirée |
403 | Jeton anti-CSRF absent ou invalide, ou compte qui n’administre pas le royaume |
404 | Graphe inconnu |
409 | POST : un graphe porte déjà ce nom |
Par ssoadm#
ssoadm create-auth-graph --realm / --name connexion --datafile connexion.json
ssoadm update-auth-graph --realm / --name connexion --datafile connexion.json
ssoadm create-sub-graph --realm / --name verif-otp-courriel --datafile verif-otp-courriel.jsonLe fichier doit contenir un seul graphe, sans enveloppe d’export. ssoadm enregistre son contenu sans le vérifier : une erreur de format n’apparaît qu’à la connexion. Pour un fichier d’export, utilisez l’import de la console, ou extrayez chaque graphe :
jq '.graphs["doc-collecteurs"]' tosiam-authgraphs-royaume-racine-2026-10-02.json > doc-collecteurs.jsonLes autres commandes (list-, show-, delete-auth-graph, et leurs équivalents -sub-graph) sont dans la référence des commandes.
Mis à jour le