Architecture
Cette page décrit comment Auris est structuré en interne et comment ses composants interagissent. Comprendre l’architecture est utile pour déboguer les problèmes d’intégration, planifier les frontières de sécurité ou évaluer Auris pour un déploiement enterprise.
Auth planes (AURIS-MSP-SOV-3 / Auth constraint #1): Public Architecture does not
list Keycloak as credential store, session manager, IdP federation broker, or token
issuer for Auris tenants. Native Auris issuer mints and locally verifies JWTs with
opaque tenant_id. IdP Admin sync/read seams are gone (fail-closed if
AURIS_KEYCLOAK_IDP_ADMIN_SYNC / AURIS_KEYCLOAK_IDP_ADMIN_READ set ON). Admin user CRUD / password-reset native (seam-removal 2;
AURIS_KEYCLOAK_ADMIN_USER_CRUD ON hard-fails). OP logout KC path gone (seam-removal 3;
AURIS_KEYCLOAK_OP_LOGOUT ON hard-fails). This is not a Keycloak-zero /
Auth #1 / constraint #9 claim — English page is canonical; see
docs/operations/keycloak-introspection-fail-closed.md.
Vue d’ensemble de Haut Niveau
Auris est une plateforme en couches. Ton application communique avec les API et les SDK Auris. La couche API fournit l’émetteur de tokens natif et les plans auth, et ajoute l’autorisation, la sécurité et les services pour développeurs au-dessus.
Auth planes (native Auris issuer + residual seams): token issuer (Auris-minted opaque
tenant_id JWTs), session/logout (Auris authoritative; IdP end_session from DB; no
/broker/ logout), IdP federation (native SP + TenantIdentityProvider / SsoConnection
SoT; KC Admin sync/read gone), credential-store posture (IdP secrets in Auris DB).
Hard isolation = opaque Tenant.id. Routing slug in iss /realms/<slug> is not an authz
key. Not Keycloak-zero.
Modèle Tenant
Chaque déploiement Auris supporte plusieurs tenants. Un tenant est un environnement complètement isolé avec :
- Comptes utilisateurs et identifiants
- Applications (clients OAuth 2.0 enregistrés)
- Rôles, permissions et politiques d’autorisation
- Configuration de sécurité (rate limit, politiques MFA, règles IP, CAPTCHA)
- Modèles d’e-mail, branding et domaines personnalisés
- Journaux d’audit et endpoints webhook
En interne, chaque tenant correspond directement à un tenant Auris (Tenant.id opaco). Cela signifie que l’isolation du tenant est appliquée au niveau du référentiel d’identité — les utilisateurs du tenant A ne peuvent pas s’authentifier sur les applications du tenant B et leurs données ne sont jamais mélangées.
L’en-tête x-tenant est utilisé sur la plupart des appels API Auris pour identifier le contexte du tenant actif. Les SDK gèrent cela automatiquement en fonction du domain (ou identifiant du tenant) que tu configures à l’initialisation.
La chaîne 'default' est un fallback au niveau SDK uniquement pour le développement local non scopé.
Les déploiements de production doivent toujours passer le vrai Tenant ID. Utiliser 'default' comme
tenant en dur peut désactiver silencieusement des fonctions de sécurité comme la protection contre
les attaques et l’application du MFA.
Autorisation à Trois Niveaux
Auris implémente l’autorisation en trois niveaux, chacun plus granulaire que le précédent :
Niveau 1 — Authentification (JWTs émis par Auris)
Les access tokens sont émis et vérifiés par Auris (issuer natif). Signature HS256 (JWT_SECRET) par défaut, ou RS256 si configuré. tenant_id opaque toujours présent sur les tokens scoped au tenant. Les tokens bruts d’IdP externes ne sont pas acceptés pour l’authz API (introspection Keycloak fail-closed).
Les claims incluent iss (issuer Auris + /realms/<slug> pour le routage), sub, email, tenant_id, roles. Ne pas supposer realm_access.roles.
Niveau 2 — Prisma RBAC (Rôles Fine-Grained avec Permissions Tri-State)
Auris maintient son propre store de rôles et permissions dans PostgreSQL (via Prisma). Ce niveau fournit :
- Rôles avec un ensemble nommé de permissions
- Permissions au format
action:ressource(ex.manage:users,view:invoices,approve:expenses) - Valeurs de permission tri-state :
ALLOW,DENYouINHERITALLOW— accorde explicitement la permissionDENY— révoque explicitement, même si un autre rôle l’accorde (DENY gagne)INHERIT— se replie sur le rôle parent ou le défaut du tenant
- Overrides de permissions par utilisateur qui peuvent accorder ou révoquer des permissions spécifiques indépendamment du rôle
- Permissions avec scope applicatif — le même utilisateur peut avoir des permissions différentes dans différentes applications enregistrées
Les vérifications de permissions se font côté serveur via POST /api/roles/check. Le tableau de bord applique les permissions sur chaque route API en utilisant requirePermission(req, 'action:resource').
Niveau 3 — FGA (Fine-Grained Authorization / Zanzibar-style ReBAC)
La couche FGA implémente le contrôle d’accès basé sur les relations au niveau de l’objet, inspiré du document Zanzibar de Google. Elle répond à des questions comme « l’utilisateur Alice peut-il lire le document 42 ? » ou « l’utilisateur Bob est-il membre de l’organisation X ? ».
Le modèle FGA consiste en :
- Modèle d’Autorisation — un schéma (écrit en DSL OpenFGA) qui définit les types d’objets et les relations entre eux
- Tuples de Relation — des faits stockés dans la base de données (ex.
document:42#viewer@user:alice) - Moteur de vérification — un algorithme Zanzibar récursif qui évalue si un sujet a une relation avec un objet, en suivant les réécritures computedUserset et tuple-to-userset jusqu’à une profondeur configurable (défaut : 25)
FGA supporte six types de règles de réécriture : this, computedUserset, tupleToUserset, union, intersection et exclusion. Il supporte également expand (liste tous les sujets pour une relation) et listObjects (liste tous les objets auxquels un sujet a accès via recherche inverse).
Quand FGA_ENGINE_ENABLED=true, les vérifications d’accès aux ressources sont routées vers le moteur FGA.
Types d’Application
Auris supporte quatre types d’applications, correspondant aux profils client OAuth 2.0 standard :
| Type | Description | Flux Auth |
|---|---|---|
WEB | App basée sur navigateur (SPA, server-rendered) | Authorization Code + PKCE |
MOBILE | App native iOS / Android | Authorization Code + PKCE |
API | Resource server qui valident les tokens | Introspection token / JWKS |
M2M | Serveur à serveur, jobs en arrière-plan, CLI | Grant Client Credentials |
Chaque application reçoit un Client ID (public) et optionnellement un Client Secret (pour les clients confidentiels). Les URI de redirection sont enregistrés par application et appliqués exactement — pas de correspondance avec des wildcards.
Flux des Tokens
Auris émet trois types de tokens selon les spécifications OpenID Connect :
Access Token
- Format : JWT, défaut code
JWT_ALGORITHM=HS256(RS256 seulement si configuré) - Durée :
JWT_EXPIRATIONdéfaut 3600 s - Contient (mint Auris) :
iss,sub,email,tenant_id(opaque),realm/tenant_slug,roles, optionnelsorg_id,tenants - Utilisation :
Authorization: Bearer <token> - Vérification : HS256/RS256 local uniquement (
verifyJWT). Pas d’introspection Keycloak. JWKS uniquement sur le chemin RS256
Refresh Token
- Format : JWT avec
type: 'refresh'(pas une chaîne opaque) - Durée : 30 jours dans
createTokens - Utilisation :
POST /api/auth/tokengrantrefresh_token - Sécurité : rotation à usage unique avec détection de réutilisation
ID Token
- Format : JWT, signé avec RS256
- Contient : Claims d’identité utilisateur (
name,email,picture,phone_number,locale, attributs personnalisés) - Utilisation : Utilisé par l’application client pour afficher les informations utilisateur — non envoyé aux API
- Vérification : Même endpoint JWKS que l’access token
OIDC Discovery
Auris publie un document OIDC Discovery standard sur :
GET /.well-known/openid-configurationLogin Hébergé
Auris fournit des pages de login hébergées servies depuis le domaine Auris (ou ton domaine personnalisé). Ces pages gèrent le flux OAuth 2.0 Authorization Code + PKCE de bout en bout.
Toutes les couches de sécurité (CAPTCHA, rate limiting, protection force brute, détection de connexions suspectes, MFA adaptatif) sont appliquées pendant le flux de login hébergé.
Moteur Actions
Les Actions sont des fonctions JavaScript personnalisées qui s’exécutent pendant les flux d’authentification dans un environnement sandbox. Les Actions peuvent être déclenchées en six points :
| Déclencheur | Quand il s’active |
|---|---|
pre_login | Avant la fin de l’authentification primaire |
post_login | Après l’authentification réussie, avant l’émission du token |
pre_signup | Avant la création d’un nouveau compte utilisateur |
post_signup | Après la création d’un nouveau compte utilisateur |
post_change_password | Après un changement de mot de passe |
pre_m2m_token | Avant l’émission d’un token machine-to-machine |
Architecture de Sécurité
La sécurité est appliquée en couches, du réseau à l’application :
Rate Limiting
Quatre niveaux de rate limit avec des compteurs à fenêtre glissante :
| Niveau | Appliqué à | Limite par défaut |
|---|---|---|
auth | Login, inscription, réinitialisation mot de passe | 5 requêtes / minute |
sensitive | 2FA, magic link, vérification téléphone | 3 requêtes / minute |
api | Appels API authentifiés | 100 requêtes / minute |
public | Endpoints publics non authentifiés | 30 requêtes / minute |
Protection Force Brute
Les tentatives de login échouées sont suivies par compte. Après un seuil configurable (défaut : 5 échecs en 15 minutes), le compte est temporairement verrouillé.
CAPTCHA
Trois fournisseurs supportés : Cloudflare Turnstile, hCaptcha et Google reCAPTCHA v3.
Règles IP
Chaque tenant peut définir des règles d’autorisation et de blocage basées sur CIDR.
Détection de Connexions Suspectes
Après chaque authentification réussie, Auris évalue cinq signaux de risque : nouvel appareil, nouvelle IP, nouveau pays, voyage impossible et IP VPN/proxy/datacenter.
DPoP Token Binding
Pour les applications nécessitant le niveau maximum de sécurité des tokens, Auris supporte Demonstrating Proof of Possession (DPoP, RFC 9449).
Résumé du Modèle de Données
Les entités principales dans Auris et leurs relations :
Toutes les modifications aux modèles Prisma (nouveaux champs ou tables) nécessitent npx prisma generate et
npx prisma db push pour prendre effet.