Docs
TOSIAM est une plateforme complète de gestion des identités et des accès (IAM) conçue pour les architectures modernes. Qu’est-ce que TOSIAM ? TOSIAM fournit un ensemble complet de services pour gérer les identités numériques, l’authentification, l’autorisation et la fédération d’identités. Il est conçu pour être extensible, performant et facile à intégrer. Fonctionnalités principales Gestion des identités — Création, modification et suppression des identités utilisateurs Authentification — Support multi-facteurs, OAuth2, OIDC, SAML Autorisation — Politiques d’accès fine granularité (RBAC, ABAC) Fédération — Single Sign-On entre applications et domaines Architecture TOSIAM suit une architecture modulaire basée sur des services découplés :
Cette page vous guide pour démarrer rapidement avec TOSIAM. Prérequis Installer un java JDK 11, 17 ou 21 (La variable d’environnement JAVA_HOME doit être définie.) Installation Télécharger la distribution Quick Start de TOSIAM. Extraire l’archive dans un répertoire <ROOT>. Un répertoire tosiam-quickstart-3.35.0 est créé. C’est la racine de la distribution (répertoire <INSTALL>) Démarrage set TOSIAM_HOME=%cd% cd bin tosiam.bat up export TOSIAM_HOME=$(pwd) cd bin ./tosiam.sh up Un serveur TOSIAM basé sur un serveur Tomcat 11 est lancé puis configuré automatiquement.
Un realm est un espace de gestion isolé dans TOSIAM. Chaque realm possède ses propres utilisateurs, groupes, rôles, politiques, modules d’authentification et configuration de services — sans interférence avec les autres realms. Pourquoi des realms ? Les realms permettent le multi-tenancy : une seule instance TOSIAM peut servir plusieurs organisations, départements ou applications tout en maintenant une séparation stricte des données et des politiques. Cas d’usage typiques : Séparer les utilisateurs internes (employés) des utilisateurs externes (clients) Héberger plusieurs clients sur la même infrastructure Créer des environnements de test isolés du realm de production Hiérarchie Les realms forment une arborescence.
TOSIAM gère deux types de sessions : les sessions stateful (stockées dans le Core Token Store) et les tokens stateless (JWT autonomes). La compréhension de ces mécanismes est essentielle pour dimensionner et sécuriser un déploiement. Sessions stateful Après une authentification réussie, TOSIAM crée une session et retourne un tokenId (cookie iPlanetDirectoryPro par défaut). Ce token est une référence opaque vers la session stockée côté serveur dans le Core Token Store (CTS).
TOSIAM repose sur un modèle d’identité hérité du User Management Service (UMS) d’iPlanet/OpenAM, enrichi par une couche REST moderne. Les identités sont stockées dans un datastore LDAP configurable par realm. Types d’identité Type Description Utilisateur (User) Compte d’une personne physique ou d’un service Groupe statique (StaticGroup) Liste figée de membres Groupe dynamique (DynamicGroup) Membres calculés par filtre LDAP Groupe dynamique assignable (AssignableDynamicGroup) Filtre LDAP + membres manuels Rôle géré (ManagedRole) Rôle assigné explicitement à des utilisateurs Rôle filtré (FilteredRole) Rôle calculé par filtre (tous les utilisateurs répondant à un critère) Datastores Chaque realm peut configurer un ou plusieurs datastores.
Les graphes d’authentification sont l’architecture d’authentification moderne de TOSIAM, implémentée dans le module tosiam-graph. Ils remplacent les chaînes de modules statiques par un modèle flexible de nœuds connectés, permettant de concevoir visuellement des parcours d’authentification complexes. Concept Un graphe est un graphe orienté où chaque nœud (GraphNode) reçoit un contexte mutable (GraphContext) et retourne un résultat qui détermine la transition suivante : Résultat Signification REQUEST_INPUT Afficher des callbacks à l’utilisateur (formulaire) GO_TO Transitionner vers un autre nœud selon un outcome SUCCESS Authentification réussie (nœud terminal) FAILURE Authentification échouée (nœud terminal) SUB_GRAPH_EXIT Sortir d’un sous-graphe par une sortie nommée Le moteur (GraphEngine) itère jusqu’à 100 transitions consécutives avant de forcer un échec.
Nœuds qui demandent une information à l’utilisateur via des callbacks, dans le cadre d’un graphe d’authentification. UsernameCollectorNode — demande le nom d’utilisateur via un NameCallback, écrit la valeur dans le shared state. Aucune propriété configurable. Outcome : outcome. PasswordCollectorNode — demande le mot de passe via un PasswordCallback, le place en transient state (jamais persisté en clair dans le shared state). Aucune propriété configurable. Outcome : outcome. PhoneCollectorNode — demande un numéro de téléphone et le normalise en E.
Nœuds qui évaluent une condition et branchent le graphe d’authentification en conséquence. Beaucoup ne se limitent pas à true/false : ils renvoient des sorties métier explicites, à connecter individuellement. Exemple : une boucle de nouvelle tentative avec RetryLimitNode Le graphe le plus simple qui illustre un mécanisme non trivial : une boucle qui redemande le mot de passe en cas d’échec, jusqu’à une limite de tentatives. UsernameCollectorNode ──outcome──▶ PasswordCollectorNode ──outcome──▶ DataStoreNode ▲ │ │ true (sous la limite) │ false │ ▼ RetryLimitNode ◀───────────── (échec credentials) │ │ false (limite atteinte) ▼ FailureNode DataStoreNode ──true──▶ SuccessNode { "startNodeId": "username", "steps": { "username": { "type": "UsernameCollectorNode", "config": {}, "outcomes": { "outcome": "password" } }, "password": { "type": "PasswordCollectorNode", "config": {}, "outcomes": { "outcome": "check" } }, "check": { "type": "DataStoreNode", "config": { "authLevel": 0 }, "outcomes": { "true": "success", "false": "retry" } }, "retry": { "type": "RetryLimitNode", "config": { "retryLimit": 3 }, "outcomes": { "true": "password", "false": "failure" } }, "success": { "type": "SuccessNode", "config": {}, "outcomes": {} }, "failure": { "type": "FailureNode", "config": {}, "outcomes": {} } } } RetryLimitNode ne connaît que sa propre propriété retryLimit : il compte les passages en échec dans le transient state (perdu si le navigateur ferme l’onglet), et bascule sur false une fois la limite atteinte — c’est le nœud qui coupe la boucle password → check → retry → password et évite un bruteforce illimité.
Enrôlement et vérification TOTP (RFC 6238), plus les nœuds transverses de choix/politique MFA, dans le cadre d’un graphe d’authentification. TotpVerifierNode — vérifie un code TOTP avec tolérance de dérive d’horloge. Propriété Type Défaut secretSource string ldap secretStateKey string clé du TotpSecretGeneratorNode secretAttributeName string (obligatoire) oathDeviceProfiles digits int 6 period int 30 stepsInWindow int 1 algorithm string HmacSHA1 retryLimit int 3 Outcomes : true / false / exceeded. TotpSecretGeneratorNode — génère le secret TOTP et l’URI otpauth:// (première étape de l’enrôlement).
Envoi et vérification de codes à usage unique par SMS ou email, dans le cadre d’un graphe d’authentification. SmsOtpSendNode — génère un OTP numérique et l’envoie par SMS. Propriété Type Défaut otpLength int 6 ttlSeconds int 300 phoneAttribute string telephoneNumber phoneSharedStateKey string SS_PHONE smsBodyTemplate string Your verification code is: {otp} (valid for {ttl}s) Outcomes : sent / error. SmsOtpVerifyNode — vérifie l’OTP soumis contre celui envoyé par SmsOtpSendNode. Propriété Type Défaut maxAttempts int 5 Outcomes : true / false / expired.
Authentification sans mot de passe par lien à usage unique envoyé par email, dans le cadre d’un graphe d’authentification. MagicLinkSendNode — envoie un lien à usage unique par email. Propriété Type Défaut ttlSeconds int 900 linkBaseUrl string (obligatoire) — tokenQueryParam string token emailAttribute string mail emailSharedStateKey string email emailSubject string Your sign-in link emailBodyTemplate string gabarit avec {link}/{ttl} Outcomes : sent / error. MagicLinkVerifyNode — valide le token à usage unique (comparaison en temps constant) et l’invalide après usage.
Enrôlement et authentification par passkeys (FIDO2/WebAuthn), dans le cadre d’un graphe d’authentification. PasskeyEnrollmentCheckNode — vérifie si l’utilisateur a au moins une passkey enregistrée. Aucune propriété configurable (interface Config vide). Outcomes : enrolled / notEnrolled. PasskeyRegistrationNode — enrôle une nouvelle passkey (protocole WebAuthn en deux passes : challenge puis validation de l’attestation). Propriété Type Défaut rpId string (obligatoire) — rpName string TOSIAM origin string (obligatoire) — Outcomes : registered / error.
Protections anti-bot, dans le cadre d’un graphe d’authentification. Les quatre nœuds ci-dessous partagent la même forme de configuration (siteKey public, secretKey marqué secret donc masqué dans les logs/exports, et une verificationUrl par défaut vers le service concerné) — seule la sémantique du score/seuil diffère. RecaptchaV2Node / RecaptchaV2InvisibleNode — Google reCAPTCHA v2, respectivement en case à cocher et en mode invisible (grecaptcha.execute()). Même classe de configuration pour les deux. Propriété Type Défaut siteKey string (obligatoire) — secretKey string, secret (obligatoire) — verificationUrl string https://www.
Signaux contextuels (appareil, géolocalisation, score composite) pour de l’authentification adaptative, dans le cadre d’un graphe d’authentification. DeviceFingerprintNode — compare l’empreinte de l’appareil (en-tête X-Device-Fingerprint ou shared state) aux appareils déjà connus de l’utilisateur. Propriété Type Défaut autoRegister boolean false Outcomes : recognized / new / unknown. GeoLocationDecisionNode — décide selon la géolocalisation IP, avec une option de détection de vélocité (déplacements rapprochés dans le temps). Propriété Type Défaut allowedCountries string "" blockedCountries string "" geoApiEndpoint string endpoint par défaut du service de géolocalisation blockUnknownGeo boolean false velocityCheckEnabled boolean false velocityWindowMinutes int 60 Outcomes : allowed / blocked / suspicious.
Authentification par certificat client X.509, dans le cadre d’un graphe d’authentification. CertificateCollectorNode — lit un certificat client X.509 (PEM) déposé dans un en-tête HTTP par un reverse proxy qui termine le mTLS. Propriété Type Défaut headerName string "" (utilise SSL_CLIENT_CERT) Outcomes : present / absent. CertificateValidationNode — valide la chaîne PKIX contre le truststore JVM, puis résout l’identité (par défaut via le SAN e-mail) vers un uid LDAP. Propriété Type Défaut checkCrl boolean false checkOcsp boolean false requiredSanType string RFC822_NAME sanExpectedValue string "" userIdMapper string EMAIL_ADDRESS Outcomes : valid / invalid / revoked.
SSO fédéré SAML2 côté SP, dans le cadre d’un graphe d’authentification. SamlRedirectNode — construit et envoie l’AuthnRequest SP-initiated (binding HTTP-Redirect, Deflate + Base64). Propriété Type Défaut spEntityId string (obligatoire) — idpSsoUrl string (obligatoire) — acsUrl string (obligatoire) — nameIdFormat string urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified forceAuthn boolean false isPassive boolean false returnUrl string "" Outcome : outcome. SamlCallbackNode — valide la SAMLResponse reçue et détecte si l’IdP signale un besoin de MFA complémentaire. Propriété Type Défaut providerName string saml-idp acsUrl string "" mfaRequiredAttribute string requiresMfa mfaRequiredContextClassRef string "" Outcomes : success / failure / mfaRequired.
Connexion via un provider social OAuth2/OIDC, dans le cadre d’un graphe d’authentification. SelectSocialProviderNode — affiche le choix du provider social. Propriété Type Défaut providers string (obligatoire) — prompt string Select identity provider Outcome : outcome. OidcRedirectNode — démarre un Authorization Code Flow avec PKCE (S256). Propriété Type Défaut clientId string (obligatoire) — authorizationEndpoint string (obligatoire) — redirectUri string (obligatoire) — scopes string openid profile email Outcome : outcome. OidcCallbackNode — échange le code contre des tokens et décode l’id_token.
Cookie « se souvenir de moi » persistant, adossé à un stockage LDAP, dans le cadre d’un graphe d’authentification. Notes PersistentSsoNode et SetPersistentSsoNode vivent dans un module Maven séparé, tosiam-auth-graph (et non tosiam-graph comme les autres nœuds du catalogue), probablement pour isoler leur dépendance directe au DAO LDAP PersistentAuthDao. Le package Java et le mode d’utilisation dans un graphe restent identiques. PersistentSsoNode — valide le cookie « se souvenir de moi » contre un token stocké en LDAP, et gère son renouvellement.
Consentement, CGU, politique de mot de passe et complétude de profil, dans le cadre d’un graphe d’authentification. ConsentNode — demande le consentement RGPD sur un périmètre donné. Propriété Type Défaut consentText string (obligatoire) texte français par défaut consentScope string (obligatoire) profile:read attributeName string sunAMUserConsentScopes Outcomes : granted / denied. TermsAndConditionsNode — demande l’acceptation des CGU, versionnées. Propriété Type Défaut termsVersion string (obligatoire) 1.0 termsText string (obligatoire) texte français par défaut attributeName string sunAMUserTCAcceptedVersion Outcomes : accepted / declined.
Nœuds transverses de composition de graphe et de gestion de session, dans le cadre d’un graphe d’authentification. SetSessionPropertiesNode — écrit des paires clé/valeur statiques dans le shared state, propagées à la session finale. Propriété Type Défaut properties map clé/valeur {} Outcome : outcome. PageNode — agrège les callbacks de plusieurs nœuds collecteurs enfants en une seule requête d’input (un seul écran pour username + password, par exemple) ; échoue immédiatement si un enfant échoue.
TOSIAM supporte huit grant types OAuth 2.0. Chaque grant type correspond à un scénario d’utilisation précis. Authorization Code (+ PKCE) Le flux standard pour les applications web et mobiles. Le client redirige l’utilisateur vers TOSIAM, reçoit un code d’autorisation, puis l’échange contre un access token. 1. GET /oauth2/{realm}/authorize ?response_type=code &client_id=mon-client &redirect_uri=https://app.example.com/callback &scope=openid email &code_challenge=... ← PKCE (recommandé) &code_challenge_method=S256 2. POST /oauth2/{realm}/access_token grant_type=authorization_code &code=AUTH_CODE &redirect_uri=https://app.example.com/callback &code_verifier=... ← PKCE PKCE (RFC 7636) est recommandé pour tous les clients, obligatoire pour les clients publics (SPA, mobile).
TOSIAM supporte deux modèles de tokens OAuth2 : stateful (stockés en CTS) et stateless (JWT autonomes). Le choix impacte la scalabilité, la révocation et la latence de validation. Tokens stateful (CTS) Par défaut, les access tokens sont des références opaques stockées dans le Core Token Store (CTS). La validation d’un token stateful nécessite une requête au CTS. Avantages : révocation immédiate, pas de risque de fuite de données dans le token.
Une installation TOSIAM se décompose fonctionnellement en deux couches : la couche IAM (les instances TOSIAM elles-mêmes, qui portent la logique d’authentification, d’autorisation et de fédération) et la couche de données, elle-même divisée en trois bases distinctes. Vue d’ensemble ┌───────────────────────┐ │ Load Balancer │ └───────────┬────────────┘ │ ┌──────────────┬─────────┴────────┬──────────────┐ │ │ │ │ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │ TOSIAM │ │ TOSIAM │ │ TOSIAM │ │ TOSIAM │ │ node 1 │ │ node 2 │ .
Faire évoluer une installation TOSIAM vers un déploiement de production consiste à traiter séparément les deux couches décrites dans Composants et couches : la couche IAM se scale horizontalement en dupliquant des nœuds identiques et sans état, la couche de données se scale par réplication — et pour le Core Token Store, par sharding, seule technique qui permette d’absorber une charge d’écriture qui croît linéairement avec le nombre d’utilisateurs actifs.
TosDJ est le serveur d’annuaire (fork d’OpenDJ) qui porte les trois bases décrites dans Composants et couches : Config Store, Core Token Store (CTS) et User Store interne. Une même distribution TosDJ sert à préparer n’importe laquelle de ces trois bases — c’est le profil choisi au moment du setup qui détermine le schéma LDAP et les données initiales chargées. Cet article installe un serveur TosDJ directement sur un hôte Linux, sans conteneur, en mode silencieux (non interactif), pour pouvoir scripter le déploiement.
TOSIAM est une application web Java (WAR), sans état applicatif propre (voir Composants et couches), déployée sur Tomcat ou JBoss/Wildfly. Elle ne fait rien tant qu’elle n’a pas été configurée pour se connecter à un Config Store TosDJ. Cet article suppose qu’un Config Store TosDJ est déjà installé et démarré (voir Installer un serveur TosDJ pas à pas) et détaille l’installation, sans conteneur, du nœud TOSIAM lui-même : déploiement du WAR, configuration silencieuse, puis mise en place des outils d’administration (ssoadm).