Skip to Content

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, DENY ou INHERIT
    • ALLOW — accorde explicitement la permission
    • DENY — 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 :

TypeDescriptionFlux Auth
WEBApp basée sur navigateur (SPA, server-rendered)Authorization Code + PKCE
MOBILEApp native iOS / AndroidAuthorization Code + PKCE
APIResource server qui valident les tokensIntrospection token / JWKS
M2MServeur à serveur, jobs en arrière-plan, CLIGrant 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_EXPIRATION défaut 3600 s
  • Contient (mint Auris) : iss, sub, email, tenant_id (opaque), realm / tenant_slug, roles, optionnels org_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/token grant refresh_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-configuration

Login 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éclencheurQuand il s’active
pre_loginAvant la fin de l’authentification primaire
post_loginAprès l’authentification réussie, avant l’émission du token
pre_signupAvant la création d’un nouveau compte utilisateur
post_signupAprès la création d’un nouveau compte utilisateur
post_change_passwordAprès un changement de mot de passe
pre_m2m_tokenAvant 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 :

NiveauAppliqué àLimite par défaut
authLogin, inscription, réinitialisation mot de passe5 requêtes / minute
sensitive2FA, magic link, vérification téléphone3 requêtes / minute
apiAppels API authentifiés100 requêtes / minute
publicEndpoints publics non authentifiés30 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.