@nodefony/security — la sécurité de bout en bout
stable@nodefony/securitymis à jour 2026-07-19
Le pare-feu applicatif de Nodefony : un modèle par zones, des authenticators enfichables, des voters de droits, et les briques qui vont avec (jetons, passkeys, 2FA, OAuth2, CSRF, CORS, en-têtes, webhooks, audit). Principe directeur : Zero Trust — sur une zone protégée, pas de preuve d’identité valide, pas d’accès. Le même firewall protège HTTP et WebSocket.
📍 Documentation › Sécurité
🧭 Par où commencer#
Quatre parcours selon ce que tu viens faire. L’ordre compte : chaque étape suppose la précédente.
Je découvre la sécurité Nodefony — comprendre le modèle avant de configurer quoi que ce soit.
- Firewall — zones, Zero Trust, la chaîne de décision. Tout part d’ici.
- Authenticators — les sept façons de prouver qui appelle.
- Autorisation — rôles, scopes, voters : ce qu’il a le droit de faire.
- Jetons — ce qui matérialise une identité prouvée, et comment on la révoque.
Je protège une API pour des machines — scripts, CI, partenaires, agents.
- Firewall — déclarer la zone et ses authenticators.
- Clés d’API — émettre, faire tourner, révoquer une clé opaque.
- Jetons — le JWT quand la vérification doit rester sans état.
- Jetons d’un émetteur TIERS — accepter Keycloak, Auth0 ou Entra sans leur céder l’application.
- Autorisation — borner chaque clé par des scopes.
J’ouvre un login à des humains — navigateur, comptes, second facteur.
- Authenticators — la session BFF, et pourquoi le login est déjà fourni.
- Page de connexion — la page servie à
/login, et comment l’habiller à ton nom. - OAuth2 — « se connecter avec GitHub/Google » et le Shadow User.
- Keycloak — brancher l’annuaire de l’entreprise, du realm au premier login.
- WebAuthn / passkeys — se connecter sans mot de passe, résistant au phishing.
- TOTP — le second facteur classique, et l’élévation de privilège (step-up).
J’audite avant une mise en production — la passe qu’on regrette de ne pas avoir faite.
- En-têtes de sécurité — CSP, HSTS, COOP/COEP : ce que le navigateur applique pour toi.
- CSRF — empêcher un site tiers d’agir au nom de ton utilisateur.
- CORS — qui a le droit de lire tes réponses.
- Journal d’audit — prouver après coup qui a fait quoi.
- Webhooks — notifier un système tiers sans se faire piéger (SSRF).
🗂️ Les briques du module#
Le tableau pour choisir en cinq secondes ; les cards en dessous pour le détail.
| Brique | Ce qu’elle résout | Tu en as besoin quand… |
|---|---|---|
| Firewall | qui passe, qui est bloqué, sur quelles routes | toujours — c’est la fondation |
| Authenticators | prouver l’identité de l’appelant | tu as autre chose que du public |
| Autorisation | rôles, scopes, voters métier | tous tes utilisateurs n’ont pas les mêmes droits |
| Jetons | émission, keystore, rotation, révocation | API sans état, ou révocation immédiate |
| Clés d’API | accès machine révocable (PAT opaque) | un script/CI/partenaire appelle ton API |
| Obtenir un jeton | émettre un porteur en ligne de commande | un agent MCP ou un script doit appeler ton app |
| CSRF | requête authentifiée forgée par un site tiers | tu sers un front avec cookie de session |
| CORS | lecture cross-origine de tes réponses | ton front est sur un autre domaine |
| En-têtes | CSP, HSTS, COOP/COEP, Referrer-Policy | tu sers du HTML à un navigateur |
| Page de connexion | la page /login servie, habillable |
des humains se connectent à ton application |
| OAuth2 | login social + provisionnement d’identité | « se connecter avec … » |
| Keycloak | connexion par l’annuaire auto-hébergé | tes comptes vivent dans un realm Keycloak |
| WebAuthn | passkeys, connexion résistante au phishing | tu veux supprimer les mots de passe |
| TOTP | second facteur temporel + step-up | 2FA, ou re-preuve avant une action sensible |
| Webhooks | notifier un tiers, signé et sans SSRF | un système externe doit réagir à tes événements |
| Journal d’audit | tracer les événements de sécurité | conformité, investigation, supervision |
🏛️ Place dans le framework#
Le module consomme @nodefony/user (jamais l’inverse) et n’importe @nodefony/http / framework
qu’en type-only, à une exception près : schemaMismatchOf (webhooks.ts), importé de
@nodefony/http pour reconnaître une base au schéma en retard avec la même règle que le cœur HTTP,
plutôt qu’avec une copie.
🧰 Surface publique#
Services Firewall, AuthFlow, TokenService, ApiKeyService, Authorization, WebAuthnService,
OAuth2Service, AuditService, TotpService, WebhookService ; briques SecuredArea,
Csrf/CsrfTokenManager, Cors, SecurityHeaders, RoleHierarchyWalker ; voters RoleVoter,
ScopeVoter ; les *Authenticator ; stores mémoire et JwtKeystore.
Les signatures exactes vivent dans le graphe généré — jq '.symbols.Firewall' .ai/symbols.json —
jamais recopiées ici (elles divergeraient).
🛠️ Gérer les comptes en exploitation#
Sur un serveur, la console d’administration suppose d’y être déjà entré — ce qui est précisément impossible quand on a perdu le mot de passe. Ces commandes sont l’autre porte, et elles s’exécutent sans ouvrir de port (profil console) :
| Commande | Ce qu’elle fait |
|---|---|
nodefony security:user:add <id> [--admin] |
crée un compte, puis dit comment s’authentifier |
nodefony security:user:list [-q <motif>] |
identifiant, rôles, état |
nodefony security:user:password <id> |
change le mot de passe — et révoque sessions et jetons |
nodefony security:user:delete <id> |
supprime, après confirmation ; refuse le dernier administrateur |
nodefony security:secrets [--write] |
engendre les clés attendues et guide leur câblage |
nodefony security:mcp:token |
émet un jeton d’accès pour la porte MCP |
nodefony security:keycloak:realm [--write|--check] |
écrit le realm Keycloak déduit de la configuration (Keycloak) |
En terminal, le mot de passe est demandé masqué et confirmé ; pour un script, --password <pwd>
l’accepte en argument — au prix de l’historique du shell, que la commande rappelle.
Deux garde-fous qui se constatent plutôt qu’ils ne se supposent : le dernier administrateur actif
ne se supprime pas (security-user-delete.ts#SecurityUserDelete.generate), et un changement de mot de passe éjecte les
accès en cours par la même cascade que la suppression (userRevocationCascade.ts#KernelListenerLike) — on change
un mot de passe parce qu’il est perdu ou compromis.
⚙️ Configuration#
Un seul point d’entrée : use("@nodefony/security", { … }) dans nodefony.config.ts, validé par Zod
au boot. Blocs : areas (zones + authenticators), cors, csrf, headers, rateLimit
(backoff NIST), puis un bloc par brique (jwt, apiKeys, totp, webhooks, audit, passkeys,
oauth2). Chaque page de brique détaille son bloc, avec une table dérivée du schéma.
📜 Normes appliquées#
| Domaine | Normes |
|---|---|
| Auth / challenge (401) | RFC 9110 §11 |
| JWT | RFC 7519, 8725 (BCP) |
| OAuth 2 | RFC 9700 (BCP), 8707, 8693, 9449 (DPoP) |
| Passkeys | W3C WebAuthn L3, CTAP2 |
| TOTP / HOTP | RFC 6238, 4226 |
| Mots de passe / 2FA | NIST SP 800-63B (throttling, timeouts) |
| Cookies | RFC 6265bis (SameSite, __Host-) |
| CSRF | Fetch Metadata (Sec-Fetch-Site) + Origin/Referer |
| En-têtes | CSP (W3C), HSTS (RFC 6797), COOP/COEP/CORP |
| Rate limit | RFC 6585 (429) |
| Général | OWASP Top 10, OWASP ASVS |
📖 Lexique#
| Sigle | Sens |
|---|---|
| WAF | Web Application Firewall : filtre applicatif des requêtes selon des règles. |
| Zero Trust | « ne rien accorder sans preuve » : aucune requête n’est de confiance par défaut. |
| JWT | JSON Web Token : jeton signé porté par le client (RFC 7519). |
| OAuth 2 | Protocole de délégation d’autorisation (RFC 9700 BCP). |
| WebAuthn | Authentification par passkey/clé (W3C WebAuthn L3). |
| TOTP/HOTP | Codes à usage unique temporels/à compteur — 2FA (RFC 6238 / 4226). |
| MFA / 2FA | Authentification à plusieurs / deux facteurs. |
| CSRF | Cross-Site Request Forgery : requête authentifiée forgée par un site tiers. |
| CORS | Cross-Origin Resource Sharing : règles d’appel cross-origine. |
| CSP | Content-Security-Policy : restreint les sources de scripts (anti-XSS). |
| HSTS | HTTP Strict Transport Security : force le TLS (RFC 6797). |
| RBAC | Role-Based Access Control : droits selon le rôle. |
| Voter | Composant qui vote « accès accordé/refusé » sur un critère (rôle, scope). |
| BFF | Backend-For-Frontend : le serveur gère la session/les jetons pour le front. |
| PAT | Personal Access Token : une clé d’API opaque, révocable côté serveur. |
📡 Observabilité — Studio#
Quatre écrans dédiés (@nodefony/studio/frontend/src/routes/) : Firewall (zones et décisions,
état runtime), ApiKeys, Audit (journal), Webhooks — plus les pages Roles, Sessions,
Login, Users. Data plane admin : SecurityAdminApi / WebhookAdminApi sous
/nodefony/security/api/*.
🧪 Tests & couverture#
Le module est le plus testé du framework. Chaque page de brique porte l’inventaire de ses tests (unitaires, intégration, E2E sur base réelle, bancs de contrat, tests d’attaque) et dit ce qui manque — un trou de couverture nommé vaut mieux qu’un chiffre flatteur. Les compteurs sont recomptés à chaque génération, jamais figés dans le texte.
🔗 Pour aller plus loin#
- ⬆️ Remonter : Toute la documentation
- 🧭 Modules voisins :
@nodefony/user(l’identité) ·@nodefony/http(transport et sessions) ·@nodefony/framework(décorateurs@IsGranted,@CurrentUser) - 🏛️ Transverse : pipeline de requête — où le firewall s’insère exactement dans le trajet d’une requête.
- 📖 Lexique général du framework.