Skip to main content

ADR-022: UAC Tenant Architecture — Flat Files over Inheritance

Decision: Un fichier UAC complet et autonome par tenant, sans inheritance ni merge.

Status: Accepted

Date: 2026-01-25

Linear: CAB-931


Contexte

STOA Platform utilise des fichiers UAC (Universal API Contract) pour définir la configuration de chaque tenant : policies de sécurité, rate limiting, quotas, accès aux APIs, observabilité, etc.

Question architecturale

Comment structurer les fichiers UAC pour supporter plusieurs tenants tout en restant maintenable, auditable et simple à debugger ?

Contraintes identifiées

ContrainteImpact
MVP 26/02/20262-3 tenants seulement pour la démo
Auditabilité RSSILe client veut voir "SON" fichier, pas un merge de 6 couches
Debug rapide"D'où vient cette valeur ?" doit avoir une réponse immédiate
CIR (Crédit Impôt Recherche)Architecture traçable et documentée

Decision

Adopter l'Option A : One UAC per Tenant (Flat) — chaque tenant possède un fichier uac.yaml complet et autonome.

Structure retenue

stoa-catalog/
├── _templates/
│ ├── starter.yaml # Template tier Starter
│ └── enterprise.yaml # Template tier Enterprise
└── tenants/
├── energy-corp/
│ └── uac.yaml # Config COMPLÈTE EnergyCorpEU
├── demo-tenant/
│ └── uac.yaml # Config COMPLÈTE demo
└── acme-corp/
└── uac.yaml # Config COMPLÈTE Acme

Diagramme


Options Considered

Option A — One UAC per Tenant (Flat) ✅ RETENUE

Un fichier uac.yaml complet par tenant, avec templates pour le bootstrap initial.

AspectÉvaluation
ComplexitéMinimale
DebugTrivial — une seule source
AuditabilitéExcellente — fichier isolé par client
DuplicationOui, mais acceptable pour 2-15 tenants
Mass-updatesVia scripts (yq, CI/CD)

Pros:

  • Explicite et prévisible
  • Chaque tenant a "son" fichier visible
  • Debug immédiat : pas de "d'où vient cette valeur ?"
  • Enterprise-friendly : le RSSI audite UN fichier
  • Zero magie, zero surprise

Cons:

  • Duplication de config entre tenants similaires
  • Mass-updates nécessitent des scripts

Option B — Global UAC unique ❌ REJETÉE

Un seul fichier UAC partagé par tous les tenants.

AspectÉvaluation
ComplexitéMinimale
IsolationNulle
Blast radiusMaximal

Pros:

  • Zero duplication
  • Une seule source de vérité

Cons:

  • Blast radius maximal : une erreur impacte TOUS les tenants
  • Versioning impossible par tenant
  • Paralysie du changement : peur de casser tout le monde
  • Incompatible avec isolation multi-tenant

Option C — Hybride Ansible-style ❌ REJETÉE

Système d'inheritance multi-couches inspiré d'Ansible.

# Merge order (du moins au plus spécifique)
defaults/base.yaml # Valeurs par défaut globales
├── tiers/starter.yaml # Override par tier
│ └── verticals/energy.yaml # Override par vertical
│ └── tenants/energy-corp/uac.yaml # Override final tenant
AspectÉvaluation
ComplexitéÉlevée
ScalabilitéExcellente (50+ tenants)
DebugComplexe

Pros:

  • Élégant et DRY
  • Scalable pour 50+ tenants
  • Modifications globales faciles

Cons:

  • Over-engineering prématuré pour 2-3 tenants
  • Debug complexe : "d'où vient cette valeur ?" nécessite de parcourir 4-6 fichiers
  • Ordre de merge à documenter et comprendre
  • YAGNI — on n'en a pas besoin maintenant

Rationale

1. MVP First

Nous visons 2-3 tenants pour la démo du 26/02/2026. L'Option C (Ansible-style) est conçue pour 50+ tenants — c'est de l'over-engineering prématuré.

2. Explicite > Magique

Le RSSI d'un client Enterprise veut voir son fichier de configuration, pas comprendre un système de merge à 6 couches. Un fichier flat par tenant = audit trivial.

3. YAGNI (You Aren't Gonna Need It)

Si nous atteignons 15+ tenants et que la duplication devient douloureuse, nous migrerons vers Ansible-style. Pas avant. Voir CAB-934.

4. Philosophie

"Ship the simplest thing that works. Refactor when it hurts."


Consequences

Positives

  • Debug instantané : une valeur = un fichier = une réponse
  • Auditabilité parfaite : chaque tenant a son fichier isolé
  • Onboarding simplifié : copier un template, modifier, terminé
  • Blast radius minimal : une erreur n'impacte qu'un tenant
  • CI/CD simple : validation par fichier, pas de résolution de merge

Négatives

  • ⚠️ Duplication : les configs similaires sont répétées
  • ⚠️ Mass-updates manuels : changement global = script sur N fichiers
  • ⚠️ Refactoring futur : migration vers Ansible-style si 15+ tenants

Trigger de réévaluation

Cette décision sera réévaluée si :

ConditionAction
15+ tenants actifsÉvaluer migration vers Ansible-style
Douleur maintenanceMass-updates trop fréquents ou erreurs de synchro
Demande clientBesoin explicite d'inheritance

Ticket de suivi : CAB-934 — Evaluate Ansible-style at 15+ tenants


Compliance — Impact CIR

Cette décision d'architecture simplifie l'audit CIR (Crédit Impôt Recherche) :

Aspect CIRBénéfice
TraçabilitéChaque tenant = un fichier versionné dans Git
ReproductibilitéConfiguration explicite, pas de magie
DocumentationCet ADR documente le raisonnement technique
État de l'artComparaison avec 3 alternatives justifie le choix

Liens