On a tous vu passer un schéma de modèle de sécurité dans une présentation, avec ses couches bien rangées et ses flèches rassurantes. Le problème commence quand on ouvre l’éditeur de code et qu’on doit transformer ce schéma en règles exécutables. Secmodel, en tant qu’approche de modélisation de la sécurité, promet de structurer les contrôles d’accès et les politiques de sécurité dès la conception. Mais entre le diagramme et le code de production, le fossé est rarement documenté.
Pourquoi le modèle de sécurité casse au premier déploiement
Le scénario classique : on définit des rôles, des permissions et des flux de données sur un tableau blanc. Tout tient debout. Puis on commence à coder, et les cas limites arrivent en rafale.
Un service qui doit accéder à deux contextes de sécurité différents pour une même requête. Un utilisateur qui cumule des rôles contradictoires. Une API tierce qui ne renvoie pas les claims attendus. Le modèle théorique ne prévoit pas les états transitoires, ceux où le système est entre deux états valides.
La cause principale n’est pas un défaut de conception. C’est l’écart entre la granularité du modèle (qui raisonne en rôles et ressources) et la granularité du code (qui raisonne en requêtes, sessions et threads concurrents). On modélise des états stables, mais le code vit dans les transitions.
Secmodel appliqué au contrôle d’accès : structurer les règles dans le code
Quand on parle de passer un secmodel en production, la première brique concerne le contrôle d’accès. Deux approches dominent : RBAC (contrôle par rôles) et ABAC (contrôle par attributs). Le choix entre les deux conditionne toute l’architecture.

RBAC fonctionne bien quand les rôles sont stables et peu nombreux. On mappe un rôle à un ensemble de permissions, et le middleware vérifie l’appartenance. Le code reste lisible, les tests unitaires couvrent chaque rôle.
ABAC devient nécessaire dès que les décisions d’accès dépendent du contexte : heure de la requête, localisation, type de données demandé, relation entre l’utilisateur et la ressource. ABAC traduit fidèlement un secmodel contextuel mais complexifie les tests.
En pratique, on combine souvent les deux. Les rôles servent de filtre grossier, les attributs affinent. Le piège est de laisser cette logique se disperser dans le code applicatif. Une règle d’accès codée dans un contrôleur ici, une autre dans un middleware là, une troisième en dur dans une requête SQL. Pour que le secmodel reste vérifiable, on centralise les politiques dans un moteur de décision dédié (un policy engine).
Ce que le policy engine change concrètement
Un policy engine comme Open Policy Agent (OPA) ou un équivalent maison sépare la logique de décision du code métier. Les politiques sont écrites dans un langage déclaratif, versionnées comme du code, et testables indépendamment.
- Les développeurs n’écrivent plus de conditions d’accès dans les services, ils appellent le moteur avec un contexte (utilisateur, ressource, action) et reçoivent un booléen
- Les équipes sécurité peuvent auditer et modifier les règles sans toucher au code applicatif, ce qui réduit le risque de régression
- Les tests de conformité deviennent des tests unitaires sur les politiques elles-mêmes, pas sur l’application entière
Cette séparation est le point où le secmodel cesse d’être un document et devient du code exécutable.
Intégrer les vérifications de sécurité dans le pipeline CI/CD
Avoir un modèle de sécurité traduit en politiques ne suffit pas si personne ne vérifie que le code déployé respecte ces politiques. C’est là que le pipeline entre en jeu.
On distingue deux niveaux de vérification. Le premier est statique : avant même l’exécution, on analyse le code et les configurations pour détecter les écarts par rapport au modèle. Le second est dynamique : on exécute des tests qui simulent des scénarios d’accès non autorisé.
Analyse statique alignée sur le modèle
L’analyse statique classique (SAST) cherche des failles connues : injection SQL, XSS, secrets en clair. Mais pour valider un secmodel, on a besoin d’aller plus loin. On vérifie que chaque point d’entrée de l’application (route API, endpoint GraphQL, fonction serverless) est bien couvert par une politique du moteur de décision.
Un endpoint sans politique associée est une faille par omission. C’est le type d’erreur que le modèle théorique ne montre pas, parce qu’il ne connaît pas la liste réelle des endpoints. Un script dans le pipeline qui croise la liste des routes déclarées avec la liste des politiques actives attrape ce problème avant le déploiement.
Tests dynamiques et scénarios d’attaque
Les tests dynamiques rejouent des scénarios concrets : un utilisateur avec le rôle « lecteur » tente une écriture, un token expiré est présenté, une requête contient des attributs falsifiés. On automatise ces scénarios dans la suite de tests d’intégration.
Les retours varient sur la couverture idéale de ces tests. Couvrir chaque combinaison rôle/ressource/action devient vite irréaliste sur un système large. Prioriser les tests sur les chemins critiques (accès aux données personnelles, opérations financières, escalade de privilèges) donne un meilleur rapport effort/sécurité que viser une couverture exhaustive.

Secmodel et dette de sécurité : garder le modèle synchronisé avec le code
Le modèle de sécurité initial reflète l’architecture du jour zéro. Six mois plus tard, des services ont été ajoutés, des rôles modifiés, des intégrations tierces branchées. Si le secmodel n’évolue pas au même rythme, il devient un document historique sans valeur opérationnelle.
- Chaque ajout de service ou d’endpoint déclenche une revue de la politique associée, au même titre qu’une revue de code fonctionnel
- Les politiques du moteur de décision sont versionnées dans le même dépôt que le code applicatif, avec des revues croisées entre développeurs et équipe sécurité
- Un tableau de bord affiche en temps réel le taux de couverture des endpoints par des politiques actives, rendant la dette de sécurité visible
Traiter les politiques de sécurité comme du code de première classe (versionnement, tests, revues, déploiement automatisé) est la seule façon de maintenir l’alignement entre le modèle et la réalité du système. Un secmodel qui vit dans un wiki séparé du dépôt finit toujours par diverger. Celui qui vit dans le pipeline, à côté des tests et des configurations, reste une contrainte active que chaque commit doit satisfaire.

