@nodefony/security 10.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +544 -0
- package/README.md +182 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.148.0/helpers/esm/decorateMetadata.js +6 -0
- package/dist/index.js +151 -0
- package/dist/nodefony/command/security-secrets.js +158 -0
- package/dist/nodefony/command/security-token.js +335 -0
- package/dist/nodefony/command/security-user-add.js +131 -0
- package/dist/nodefony/command/security-user-delete.js +102 -0
- package/dist/nodefony/command/security-user-list.js +77 -0
- package/dist/nodefony/config/config.js +366 -0
- package/dist/nodefony/config/defineModuleConfig.js +35 -0
- package/dist/nodefony/contracts/IAccessVoter.js +13 -0
- package/dist/nodefony/contracts/IApiKey.js +1 -0
- package/dist/nodefony/contracts/IAuditEvent.js +1 -0
- package/dist/nodefony/contracts/IAuditStore.js +1 -0
- package/dist/nodefony/contracts/IAuthenticator.js +1 -0
- package/dist/nodefony/contracts/IAuthorizationService.js +1 -0
- package/dist/nodefony/contracts/IFirewall.js +1 -0
- package/dist/nodefony/contracts/IFirewallDescription.js +1 -0
- package/dist/nodefony/contracts/IJwtKeystore.js +1 -0
- package/dist/nodefony/contracts/IOAuthProvider.js +1 -0
- package/dist/nodefony/contracts/ISecuredArea.js +1 -0
- package/dist/nodefony/contracts/IToken.js +1 -0
- package/dist/nodefony/contracts/ITokenStore.js +1 -0
- package/dist/nodefony/contracts/ITotpSecret.js +1 -0
- package/dist/nodefony/contracts/ITotpSecretStore.js +1 -0
- package/dist/nodefony/contracts/IWebAuthnCredential.js +1 -0
- package/dist/nodefony/contracts/IWebAuthnCredentialStore.js +1 -0
- package/dist/nodefony/contracts/IWebhookEndpoint.js +1 -0
- package/dist/nodefony/contracts/IWebhookStore.js +1 -0
- package/dist/nodefony/contracts/index.js +2 -0
- package/dist/nodefony/errors/AccessDeniedError.js +14 -0
- package/dist/nodefony/errors/ApiKeyError.js +21 -0
- package/dist/nodefony/errors/AuthenticationError.js +14 -0
- package/dist/nodefony/errors/CsrfError.js +23 -0
- package/dist/nodefony/errors/InvalidTargetError.js +39 -0
- package/dist/nodefony/errors/SsrfError.js +17 -0
- package/dist/nodefony/errors/ThrottledError.js +21 -0
- package/dist/nodefony/errors/UnverifiableTokenError.js +42 -0
- package/dist/nodefony/errors/WebAuthnError.js +21 -0
- package/dist/nodefony/errors/index.js +9 -0
- package/dist/nodefony/service/accessTokenVerifier.js +77 -0
- package/dist/nodefony/service/apiKeys.js +310 -0
- package/dist/nodefony/service/auditService.js +145 -0
- package/dist/nodefony/service/authFlow.js +332 -0
- package/dist/nodefony/service/authorization.js +95 -0
- package/dist/nodefony/service/cors.js +81 -0
- package/dist/nodefony/service/csrf.js +97 -0
- package/dist/nodefony/service/firewall.js +699 -0
- package/dist/nodefony/service/oauth2.js +153 -0
- package/dist/nodefony/service/securityHeaders.js +80 -0
- package/dist/nodefony/service/tokenService.js +486 -0
- package/dist/nodefony/service/totp.js +209 -0
- package/dist/nodefony/service/webAuthn.js +343 -0
- package/dist/nodefony/service/webhooks.js +539 -0
- package/dist/nodefony/src/RoleHierarchyWalker.js +77 -0
- package/dist/nodefony/src/SecuredArea.js +51 -0
- package/dist/nodefony/src/admin/SecurityAdminApi.js +495 -0
- package/dist/nodefony/src/admin/WebhookAdminApi.js +378 -0
- package/dist/nodefony/src/admin/adminAudit.js +37 -0
- package/dist/nodefony/src/admin/userRevocationCascade.js +40 -0
- package/dist/nodefony/src/apikey/apiKeyFormat.js +107 -0
- package/dist/nodefony/src/audit/MemoryAuditStore.js +121 -0
- package/dist/nodefony/src/audit/auditBridge.js +82 -0
- package/dist/nodefony/src/audit/auditFilters.js +60 -0
- package/dist/nodefony/src/audit/auditStoreRegistry.js +25 -0
- package/dist/nodefony/src/audit/readAuditContext.js +24 -0
- package/dist/nodefony/src/audit/recordAudit.js +16 -0
- package/dist/nodefony/src/authenticator/AnonymousAuthenticator.js +36 -0
- package/dist/nodefony/src/authenticator/ApiKeyAuthenticator.js +164 -0
- package/dist/nodefony/src/authenticator/ExternalJwtAuthenticator.js +224 -0
- package/dist/nodefony/src/authenticator/FirewallRealtimeAuthenticator.js +174 -0
- package/dist/nodefony/src/authenticator/JwtAuthenticator.js +176 -0
- package/dist/nodefony/src/authenticator/SessionAuthenticator.js +92 -0
- package/dist/nodefony/src/authenticator/UserPasswordAuthenticator.js +95 -0
- package/dist/nodefony/src/authenticator/authenticatorRegistry.js +63 -0
- package/dist/nodefony/src/authenticator/bearer.js +2 -0
- package/dist/nodefony/src/authenticator/externalSubject.js +36 -0
- package/dist/nodefony/src/authenticator/peekIssuer.js +56 -0
- package/dist/nodefony/src/crypto/secretCipher.js +79 -0
- package/dist/nodefony/src/csp.js +54 -0
- package/dist/nodefony/src/csrfToken.js +65 -0
- package/dist/nodefony/src/net/ssrfGuard.js +130 -0
- package/dist/nodefony/src/oauth/oauthProviderRegistry.js +37 -0
- package/dist/nodefony/src/oauth/providers/github.js +65 -0
- package/dist/nodefony/src/oauth/providers/oidc.js +48 -0
- package/dist/nodefony/src/realtime/UserRealtimeToken.js +94 -0
- package/dist/nodefony/src/realtime/frameAuthorizer.js +279 -0
- package/dist/nodefony/src/realtime/realtimeContracts.js +1 -0
- package/dist/nodefony/src/sessionIdentity.js +35 -0
- package/dist/nodefony/src/throttle/LoginThrottler.js +97 -0
- package/dist/nodefony/src/token/AnonymousToken.js +40 -0
- package/dist/nodefony/src/token/JwtKeystore.js +160 -0
- package/dist/nodefony/src/token/MemoryTokenStore.js +236 -0
- package/dist/nodefony/src/token/RemoteJwtVerifier.js +231 -0
- package/dist/nodefony/src/token/UserToken.js +67 -0
- package/dist/nodefony/src/token/jwtRuntime.js +19 -0
- package/dist/nodefony/src/token/secretFile.js +134 -0
- package/dist/nodefony/src/token/tokenCriteria.js +35 -0
- package/dist/nodefony/src/token/tokenFilters.js +72 -0
- package/dist/nodefony/src/token/tokenSort.js +40 -0
- package/dist/nodefony/src/token/tokenStatus.js +35 -0
- package/dist/nodefony/src/token/tokenStoreRegistry.js +25 -0
- package/dist/nodefony/src/totp/MemoryTotpSecretStore.js +97 -0
- package/dist/nodefony/src/totp/totpCipher.js +30 -0
- package/dist/nodefony/src/totp/totpCrypto.js +226 -0
- package/dist/nodefony/src/totp/totpOperations.js +129 -0
- package/dist/nodefony/src/totp/totpSecretStoreRegistry.js +18 -0
- package/dist/nodefony/src/voter/RoleVoter.js +32 -0
- package/dist/nodefony/src/voter/ScopeVoter.js +52 -0
- package/dist/nodefony/src/voter/voterRegistry.js +20 -0
- package/dist/nodefony/src/webauthn/MemoryWebAuthnCredentialStore.js +121 -0
- package/dist/nodefony/src/webauthn/webAuthnCredentialStoreRegistry.js +18 -0
- package/dist/nodefony/src/webhook/MemoryWebhookStore.js +87 -0
- package/dist/nodefony/src/webhook/WebhookDispatcher.js +208 -0
- package/dist/nodefony/src/webhook/webhookCipher.js +27 -0
- package/dist/nodefony/src/webhook/webhookDelivery.js +102 -0
- package/dist/nodefony/src/webhook/webhookFilters.js +56 -0
- package/dist/nodefony/src/webhook/webhookSignature.js +51 -0
- package/dist/nodefony/src/webhook/webhookSort.js +48 -0
- package/dist/nodefony/src/webhook/webhookStoreRegistry.js +18 -0
- package/dist/types/index.d.ts +157 -0
- package/dist/types/nodefony/command/security-secrets.d.ts +24 -0
- package/dist/types/nodefony/command/security-token.d.ts +44 -0
- package/dist/types/nodefony/command/security-user-add.d.ts +28 -0
- package/dist/types/nodefony/command/security-user-delete.d.ts +25 -0
- package/dist/types/nodefony/command/security-user-list.d.ts +28 -0
- package/dist/types/nodefony/config/config.d.ts +295 -0
- package/dist/types/nodefony/config/defineModuleConfig.d.ts +27 -0
- package/dist/types/nodefony/contracts/IAccessVoter.d.ts +23 -0
- package/dist/types/nodefony/contracts/IApiKey.d.ts +75 -0
- package/dist/types/nodefony/contracts/IAuditEvent.d.ts +94 -0
- package/dist/types/nodefony/contracts/IAuditStore.d.ts +80 -0
- package/dist/types/nodefony/contracts/IAuthenticator.d.ts +66 -0
- package/dist/types/nodefony/contracts/IAuthorizationService.d.ts +28 -0
- package/dist/types/nodefony/contracts/IFirewall.d.ts +64 -0
- package/dist/types/nodefony/contracts/IFirewallDescription.d.ts +120 -0
- package/dist/types/nodefony/contracts/IJwtKeystore.d.ts +40 -0
- package/dist/types/nodefony/contracts/IOAuthProvider.d.ts +51 -0
- package/dist/types/nodefony/contracts/ISecuredArea.d.ts +57 -0
- package/dist/types/nodefony/contracts/IToken.d.ts +41 -0
- package/dist/types/nodefony/contracts/ITokenStore.d.ts +240 -0
- package/dist/types/nodefony/contracts/ITotpSecret.d.ts +41 -0
- package/dist/types/nodefony/contracts/ITotpSecretStore.d.ts +88 -0
- package/dist/types/nodefony/contracts/IWebAuthnCredential.d.ts +56 -0
- package/dist/types/nodefony/contracts/IWebAuthnCredentialStore.d.ts +118 -0
- package/dist/types/nodefony/contracts/IWebhookEndpoint.d.ts +82 -0
- package/dist/types/nodefony/contracts/IWebhookStore.d.ts +85 -0
- package/dist/types/nodefony/contracts/index.d.ts +9 -0
- package/dist/types/nodefony/errors/AccessDeniedError.d.ts +10 -0
- package/dist/types/nodefony/errors/ApiKeyError.d.ts +17 -0
- package/dist/types/nodefony/errors/AuthenticationError.d.ts +10 -0
- package/dist/types/nodefony/errors/CsrfError.d.ts +19 -0
- package/dist/types/nodefony/errors/InvalidTargetError.d.ts +34 -0
- package/dist/types/nodefony/errors/SsrfError.d.ts +13 -0
- package/dist/types/nodefony/errors/ThrottledError.d.ts +16 -0
- package/dist/types/nodefony/errors/UnverifiableTokenError.d.ts +37 -0
- package/dist/types/nodefony/errors/WebAuthnError.d.ts +17 -0
- package/dist/types/nodefony/errors/index.d.ts +8 -0
- package/dist/types/nodefony/service/accessTokenVerifier.d.ts +29 -0
- package/dist/types/nodefony/service/apiKeys.d.ts +103 -0
- package/dist/types/nodefony/service/auditService.d.ts +30 -0
- package/dist/types/nodefony/service/authFlow.d.ts +123 -0
- package/dist/types/nodefony/service/authorization.d.ts +33 -0
- package/dist/types/nodefony/service/cors.d.ts +48 -0
- package/dist/types/nodefony/service/csrf.d.ts +57 -0
- package/dist/types/nodefony/service/firewall.d.ts +148 -0
- package/dist/types/nodefony/service/oauth2.d.ts +66 -0
- package/dist/types/nodefony/service/securityHeaders.d.ts +66 -0
- package/dist/types/nodefony/service/tokenService.d.ts +103 -0
- package/dist/types/nodefony/service/totp.d.ts +58 -0
- package/dist/types/nodefony/service/webAuthn.d.ts +123 -0
- package/dist/types/nodefony/service/webhooks.d.ts +160 -0
- package/dist/types/nodefony/src/RoleHierarchyWalker.d.ts +21 -0
- package/dist/types/nodefony/src/SecuredArea.d.ts +31 -0
- package/dist/types/nodefony/src/admin/SecurityAdminApi.d.ts +82 -0
- package/dist/types/nodefony/src/admin/WebhookAdminApi.d.ts +30 -0
- package/dist/types/nodefony/src/admin/adminAudit.d.ts +27 -0
- package/dist/types/nodefony/src/admin/userRevocationCascade.d.ts +31 -0
- package/dist/types/nodefony/src/apikey/apiKeyFormat.d.ts +43 -0
- package/dist/types/nodefony/src/audit/MemoryAuditStore.d.ts +33 -0
- package/dist/types/nodefony/src/audit/auditBridge.d.ts +49 -0
- package/dist/types/nodefony/src/audit/auditFilters.d.ts +56 -0
- package/dist/types/nodefony/src/audit/auditStoreRegistry.d.ts +37 -0
- package/dist/types/nodefony/src/audit/readAuditContext.d.ts +17 -0
- package/dist/types/nodefony/src/audit/recordAudit.d.ts +13 -0
- package/dist/types/nodefony/src/authenticator/AnonymousAuthenticator.d.ts +26 -0
- package/dist/types/nodefony/src/authenticator/ApiKeyAuthenticator.d.ts +74 -0
- package/dist/types/nodefony/src/authenticator/ExternalJwtAuthenticator.d.ts +132 -0
- package/dist/types/nodefony/src/authenticator/FirewallRealtimeAuthenticator.d.ts +78 -0
- package/dist/types/nodefony/src/authenticator/JwtAuthenticator.d.ts +69 -0
- package/dist/types/nodefony/src/authenticator/SessionAuthenticator.d.ts +70 -0
- package/dist/types/nodefony/src/authenticator/UserPasswordAuthenticator.d.ts +53 -0
- package/dist/types/nodefony/src/authenticator/authenticatorRegistry.d.ts +39 -0
- package/dist/types/nodefony/src/authenticator/bearer.d.ts +22 -0
- package/dist/types/nodefony/src/authenticator/externalSubject.d.ts +27 -0
- package/dist/types/nodefony/src/authenticator/peekIssuer.d.ts +31 -0
- package/dist/types/nodefony/src/crypto/secretCipher.d.ts +31 -0
- package/dist/types/nodefony/src/csp.d.ts +39 -0
- package/dist/types/nodefony/src/csrfToken.d.ts +36 -0
- package/dist/types/nodefony/src/net/ssrfGuard.d.ts +43 -0
- package/dist/types/nodefony/src/oauth/oauthProviderRegistry.d.ts +45 -0
- package/dist/types/nodefony/src/oauth/providers/github.d.ts +9 -0
- package/dist/types/nodefony/src/oauth/providers/oidc.d.ts +35 -0
- package/dist/types/nodefony/src/realtime/UserRealtimeToken.d.ts +62 -0
- package/dist/types/nodefony/src/realtime/frameAuthorizer.d.ts +171 -0
- package/dist/types/nodefony/src/realtime/realtimeContracts.d.ts +139 -0
- package/dist/types/nodefony/src/sessionIdentity.d.ts +20 -0
- package/dist/types/nodefony/src/throttle/LoginThrottler.d.ts +68 -0
- package/dist/types/nodefony/src/token/AnonymousToken.d.ts +23 -0
- package/dist/types/nodefony/src/token/JwtKeystore.d.ts +43 -0
- package/dist/types/nodefony/src/token/MemoryTokenStore.d.ts +66 -0
- package/dist/types/nodefony/src/token/RemoteJwtVerifier.d.ts +149 -0
- package/dist/types/nodefony/src/token/UserToken.d.ts +41 -0
- package/dist/types/nodefony/src/token/jwtRuntime.d.ts +28 -0
- package/dist/types/nodefony/src/token/secretFile.d.ts +70 -0
- package/dist/types/nodefony/src/token/tokenCriteria.d.ts +20 -0
- package/dist/types/nodefony/src/token/tokenFilters.d.ts +76 -0
- package/dist/types/nodefony/src/token/tokenSort.d.ts +33 -0
- package/dist/types/nodefony/src/token/tokenStatus.d.ts +38 -0
- package/dist/types/nodefony/src/token/tokenStoreRegistry.d.ts +38 -0
- package/dist/types/nodefony/src/totp/MemoryTotpSecretStore.d.ts +43 -0
- package/dist/types/nodefony/src/totp/totpCipher.d.ts +9 -0
- package/dist/types/nodefony/src/totp/totpCrypto.d.ts +164 -0
- package/dist/types/nodefony/src/totp/totpOperations.d.ts +73 -0
- package/dist/types/nodefony/src/totp/totpSecretStoreRegistry.d.ts +27 -0
- package/dist/types/nodefony/src/voter/RoleVoter.d.ts +25 -0
- package/dist/types/nodefony/src/voter/ScopeVoter.d.ts +30 -0
- package/dist/types/nodefony/src/voter/voterRegistry.d.ts +33 -0
- package/dist/types/nodefony/src/webauthn/MemoryWebAuthnCredentialStore.d.ts +39 -0
- package/dist/types/nodefony/src/webauthn/webAuthnCredentialStoreRegistry.d.ts +26 -0
- package/dist/types/nodefony/src/webhook/MemoryWebhookStore.d.ts +37 -0
- package/dist/types/nodefony/src/webhook/WebhookDispatcher.d.ts +69 -0
- package/dist/types/nodefony/src/webhook/webhookCipher.d.ts +8 -0
- package/dist/types/nodefony/src/webhook/webhookDelivery.d.ts +28 -0
- package/dist/types/nodefony/src/webhook/webhookFilters.d.ts +64 -0
- package/dist/types/nodefony/src/webhook/webhookSignature.d.ts +20 -0
- package/dist/types/nodefony/src/webhook/webhookSort.d.ts +39 -0
- package/dist/types/nodefony/src/webhook/webhookStoreRegistry.d.ts +31 -0
- package/docs/api-keys.md +691 -0
- package/docs/audit.md +751 -0
- package/docs/authenticators.md +487 -0
- package/docs/authorization.md +497 -0
- package/docs/cors.md +497 -0
- package/docs/csrf.md +392 -0
- package/docs/external-jwt.md +181 -0
- package/docs/firewall.md +546 -0
- package/docs/headers.md +616 -0
- package/docs/index.md +207 -0
- package/docs/lexique.md +190 -0
- package/docs/oauth2.md +575 -0
- package/docs/obtenir-un-jeton.md +225 -0
- package/docs/tokens.md +520 -0
- package/docs/totp.md +804 -0
- package/docs/webauthn.md +733 -0
- package/docs/webhooks.md +1016 -0
- package/package.json +83 -0
package/docs/index.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "@nodefony/security — la sécurité de bout en bout"
|
|
3
|
+
navTitle: "@nodefony/security"
|
|
4
|
+
lang: fr
|
|
5
|
+
module: "@nodefony/security"
|
|
6
|
+
topic: security
|
|
7
|
+
section: "Sécurité"
|
|
8
|
+
audience: [developer]
|
|
9
|
+
tags:
|
|
10
|
+
[
|
|
11
|
+
securite,
|
|
12
|
+
firewall,
|
|
13
|
+
authentification,
|
|
14
|
+
autorisation,
|
|
15
|
+
jwt,
|
|
16
|
+
oauth2,
|
|
17
|
+
webauthn,
|
|
18
|
+
csrf,
|
|
19
|
+
cors,
|
|
20
|
+
audit,
|
|
21
|
+
]
|
|
22
|
+
version: "doc"
|
|
23
|
+
status: stable
|
|
24
|
+
updated: 2026-07-19
|
|
25
|
+
source: "src/packages/@nodefony/security/docs/index.md"
|
|
26
|
+
coverageModule: security
|
|
27
|
+
coverageFiles: firewall.ts,authFlow.ts,tokenService.ts,webAuthn.ts,totp.ts,apiKeys.ts,webhooks.ts,auditService.ts,oauth2.ts
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# @nodefony/security — la sécurité de bout en bout
|
|
31
|
+
|
|
32
|
+
> Le pare-feu applicatif de Nodefony : un modèle par **zones**, des **authenticators** enfichables,
|
|
33
|
+
> des **voters** de droits, et les briques qui vont avec (jetons, passkeys, 2FA, OAuth2, CSRF, CORS,
|
|
34
|
+
> en-têtes, webhooks, audit). Principe directeur : **Zero Trust** — sur une zone protégée, pas de
|
|
35
|
+
> preuve d'identité valide, pas d'accès. Le **même** firewall protège HTTP et WebSocket.
|
|
36
|
+
|
|
37
|
+
📍 [Documentation](../../../../../docs/index.md) › **Sécurité**
|
|
38
|
+
|
|
39
|
+
## 🧭 Par où commencer
|
|
40
|
+
|
|
41
|
+
Quatre parcours selon ce que tu viens faire. L'ordre compte : chaque étape suppose la précédente.
|
|
42
|
+
|
|
43
|
+
**Je découvre la sécurité Nodefony** — comprendre le modèle avant de configurer quoi que ce soit.
|
|
44
|
+
|
|
45
|
+
1. [Firewall](firewall.md) — zones, Zero Trust, la chaîne de décision. **Tout part d'ici.**
|
|
46
|
+
2. [Authenticators](authenticators.md) — les six façons de prouver **qui** appelle.
|
|
47
|
+
3. [Autorisation](authorization.md) — rôles, scopes, voters : **ce qu'il a le droit** de faire.
|
|
48
|
+
4. [Jetons](tokens.md) — ce qui matérialise une identité prouvée, et comment on la révoque.
|
|
49
|
+
|
|
50
|
+
**Je protège une API pour des machines** — scripts, CI, partenaires, agents.
|
|
51
|
+
|
|
52
|
+
1. [Firewall](firewall.md) — déclarer la zone et ses authenticators.
|
|
53
|
+
2. [Clés d'API](api-keys.md) — émettre, faire tourner, révoquer une clé opaque.
|
|
54
|
+
3. [Jetons](tokens.md) — le JWT quand la vérification doit rester sans état.
|
|
55
|
+
4. [Jetons d'un émetteur TIERS](external-jwt.md) — accepter Keycloak, Auth0 ou Entra sans leur
|
|
56
|
+
céder l'application.
|
|
57
|
+
5. [Autorisation](authorization.md) — borner chaque clé par des scopes.
|
|
58
|
+
|
|
59
|
+
**J'ouvre un login à des humains** — navigateur, comptes, second facteur.
|
|
60
|
+
|
|
61
|
+
1. [Authenticators](authenticators.md) — la session BFF, et pourquoi le login est **déjà fourni**.
|
|
62
|
+
2. [OAuth2](oauth2.md) — « se connecter avec GitHub/Google » et le Shadow User.
|
|
63
|
+
3. [WebAuthn / passkeys](webauthn.md) — se connecter sans mot de passe, résistant au phishing.
|
|
64
|
+
4. [TOTP](totp.md) — le second facteur classique, et l'élévation de privilège (step-up).
|
|
65
|
+
|
|
66
|
+
**J'audite avant une mise en production** — la passe qu'on regrette de ne pas avoir faite.
|
|
67
|
+
|
|
68
|
+
1. [En-têtes de sécurité](headers.md) — CSP, HSTS, COOP/COEP : ce que le navigateur applique pour toi.
|
|
69
|
+
2. [CSRF](csrf.md) — empêcher un site tiers d'agir au nom de ton utilisateur.
|
|
70
|
+
3. [CORS](cors.md) — qui a le droit de **lire** tes réponses.
|
|
71
|
+
4. [Journal d'audit](audit.md) — prouver après coup qui a fait quoi.
|
|
72
|
+
5. [Webhooks](webhooks.md) — notifier un système tiers sans se faire piéger (SSRF).
|
|
73
|
+
|
|
74
|
+
## 🗂️ Les briques du module
|
|
75
|
+
|
|
76
|
+
Le tableau pour choisir en cinq secondes ; les cards en dessous pour le détail.
|
|
77
|
+
|
|
78
|
+
| Brique | Ce qu'elle résout | Tu en as besoin quand… |
|
|
79
|
+
| --------------------------------------- | --------------------------------------------- | ------------------------------------------------ |
|
|
80
|
+
| [Firewall](firewall.md) | qui passe, qui est bloqué, sur quelles routes | toujours — c'est la fondation |
|
|
81
|
+
| [Authenticators](authenticators.md) | prouver l'identité de l'appelant | tu as autre chose que du public |
|
|
82
|
+
| [Autorisation](authorization.md) | rôles, scopes, voters métier | tous tes utilisateurs n'ont pas les mêmes droits |
|
|
83
|
+
| [Jetons](tokens.md) | émission, keystore, rotation, révocation | API sans état, ou révocation immédiate |
|
|
84
|
+
| [Clés d'API](api-keys.md) | accès machine révocable (PAT opaque) | un script/CI/partenaire appelle ton API |
|
|
85
|
+
| [Obtenir un jeton](obtenir-un-jeton.md) | émettre un porteur en ligne de commande | un agent MCP ou un script doit appeler ton app |
|
|
86
|
+
| [CSRF](csrf.md) | requête authentifiée forgée par un site tiers | tu sers un front avec cookie de session |
|
|
87
|
+
| [CORS](cors.md) | lecture cross-origine de tes réponses | ton front est sur un autre domaine |
|
|
88
|
+
| [En-têtes](headers.md) | CSP, HSTS, COOP/COEP, Referrer-Policy | tu sers du HTML à un navigateur |
|
|
89
|
+
| [OAuth2](oauth2.md) | login social + provisionnement d'identité | « se connecter avec … » |
|
|
90
|
+
| [WebAuthn](webauthn.md) | passkeys, connexion résistante au phishing | tu veux supprimer les mots de passe |
|
|
91
|
+
| [TOTP](totp.md) | second facteur temporel + step-up | 2FA, ou re-preuve avant une action sensible |
|
|
92
|
+
| [Webhooks](webhooks.md) | notifier un tiers, signé et sans SSRF | un système externe doit réagir à tes événements |
|
|
93
|
+
| [Journal d'audit](audit.md) | tracer les événements de sécurité | conformité, investigation, supervision |
|
|
94
|
+
|
|
95
|
+
```nodefony-cards
|
|
96
|
+
[
|
|
97
|
+
{ "icon": "🛡️", "title": "firewall", "href": "firewall.md", "featured": true,
|
|
98
|
+
"desc": "Le pare-feu applicatif : trois questions pour chaque requête — est-ce une zone protégée ? qui es-tu ? as-tu le droit ? Le chemin chaud (détecter) est séparé du chemin froid (décider), donc une route publique ne paie rien.",
|
|
99
|
+
"meta": "à lire en premier — toutes les autres briques s'y branchent" },
|
|
100
|
+
{ "icon": "🪪", "title": "authenticators", "href": "authenticators.md",
|
|
101
|
+
"desc": "Prouver qui appelle : six stratégies au même contrat — session, userpassword, jwt, apikey, anonymous, firewall-realtime — qui se composent dans l'ordre au sein d'une zone.",
|
|
102
|
+
"meta": "commence par « Ordre et modes » : les pièges de configuration sont là" },
|
|
103
|
+
{ "icon": "⚖️", "title": "authorization", "href": "authorization.md",
|
|
104
|
+
"desc": "Décider des droits : rôles hiérarchisés, scopes, et voters métier qui portent le vrai pouvoir applicatif. Le jury vote, la stratégie tranche.",
|
|
105
|
+
"meta": "juste après les authenticators — authentifier sans autoriser ne protège rien" },
|
|
106
|
+
{ "icon": "🎫", "title": "tokens", "href": "tokens.md",
|
|
107
|
+
"desc": "L'identité matérialisée : émission, keystore, rotation, révocation — et le choix structurant du framework, session opaque côté serveur pour le web, JWT pour les API.",
|
|
108
|
+
"meta": "et pourquoi ce n'est pas « full stateless »" },
|
|
109
|
+
{ "icon": "🔑", "title": "obtenir un jeton", "href": "obtenir-un-jeton.md",
|
|
110
|
+
"desc": "L'autre voie d'émission : l'application signe elle-même un porteur en ligne de commande, sans serveur en marche ni mot de passe — c'est ce dont un client MCP ou un script d'exploitation a besoin.",
|
|
111
|
+
"meta": "le refus le plus fréquent : l'audience n'est pas déclarée" },
|
|
112
|
+
{ "icon": "📓", "title": "audit", "href": "audit.md",
|
|
113
|
+
"desc": "La mémoire de ce qui s'est passé : qui s'est connecté, quel accès a été refusé, quelle clé a été révoquée. Conçu pour ne pas peser sur le chemin chaud de la requête.",
|
|
114
|
+
"meta": "alimente aussi les webhooks" }
|
|
115
|
+
]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## 🏛️ Place dans le framework
|
|
119
|
+
|
|
120
|
+
```mermaid
|
|
121
|
+
flowchart LR
|
|
122
|
+
HTTP["@nodefony/http<br/>transport, contextes, sessions"] --> SEC["@nodefony/security<br/>firewall, authn, authz"]
|
|
123
|
+
USER["@nodefony/user<br/>identité IUser"] --> SEC
|
|
124
|
+
SEC --> FW["@nodefony/framework<br/>@IsGranted, @CurrentUser"]
|
|
125
|
+
SEC -.->|stores| DB["drizzle · mongoose · redis"]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Le module consomme `@nodefony/user` (jamais l'inverse) et n'importe `@nodefony/http` / `framework`
|
|
129
|
+
qu'en **type-only** — le couplage runtime resterait une dette.
|
|
130
|
+
|
|
131
|
+
## 🧰 Surface publique
|
|
132
|
+
|
|
133
|
+
Services `Firewall`, `AuthFlow`, `TokenService`, `ApiKeyService`, `Authorization`, `WebAuthnService`,
|
|
134
|
+
`OAuth2Service`, `AuditService`, `TotpService`, `WebhookService` ; briques `SecuredArea`,
|
|
135
|
+
`Csrf`/`CsrfTokenManager`, `Cors`, `SecurityHeaders`, `RoleHierarchyWalker` ; voters `RoleVoter`,
|
|
136
|
+
`ScopeVoter` ; les `*Authenticator` ; stores mémoire et `JwtKeystore`.
|
|
137
|
+
|
|
138
|
+
Les signatures exactes vivent dans le graphe généré — `jq '.symbols.Firewall' .ai/symbols.json` —
|
|
139
|
+
jamais recopiées ici (elles divergeraient).
|
|
140
|
+
|
|
141
|
+
## ⚙️ Configuration
|
|
142
|
+
|
|
143
|
+
Un seul point d'entrée : `use("@nodefony/security", { … })` dans `nodefony.config.ts`, validé par Zod
|
|
144
|
+
au boot. Blocs : `areas` (zones + authenticators), `cors`, `csrf`, `headers`, `loginThrottle`
|
|
145
|
+
(backoff NIST), puis un bloc par brique (`jwt`, `apiKeys`, `totp`, `webhooks`, `audit`, `passkeys`,
|
|
146
|
+
`oauth2`). **Chaque page de brique détaille son bloc**, avec une table dérivée du schéma.
|
|
147
|
+
|
|
148
|
+
## 📜 Normes appliquées
|
|
149
|
+
|
|
150
|
+
<!-- prettier-ignore -->
|
|
151
|
+
| Domaine | Normes |
|
|
152
|
+
| --- | --- |
|
|
153
|
+
| Auth / challenge (401) | RFC 7235 |
|
|
154
|
+
| JWT | RFC 7519, 8725 (BCP) |
|
|
155
|
+
| OAuth 2 | RFC 9700 (BCP), 8707, 8693, 9449 (DPoP) |
|
|
156
|
+
| Passkeys | W3C WebAuthn L3, CTAP2 |
|
|
157
|
+
| TOTP / HOTP | RFC 6238, 4226 |
|
|
158
|
+
| Mots de passe / 2FA | NIST SP 800-63B (throttling, timeouts) |
|
|
159
|
+
| Cookies | RFC 6265bis (`SameSite`, `__Host-`) |
|
|
160
|
+
| CSRF | Fetch Metadata (`Sec-Fetch-Site`) + `Origin`/`Referer` |
|
|
161
|
+
| En-têtes | CSP (W3C), HSTS (RFC 6797), COOP/COEP/CORP |
|
|
162
|
+
| Rate limit | RFC 6585 (429) |
|
|
163
|
+
| Général | OWASP Top 10, OWASP ASVS |
|
|
164
|
+
|
|
165
|
+
## 📖 Lexique
|
|
166
|
+
|
|
167
|
+
| Sigle | Sens |
|
|
168
|
+
| ---------- | -------------------------------------------------------------------------------- |
|
|
169
|
+
| WAF | Web Application Firewall : filtre applicatif des requêtes selon des règles. |
|
|
170
|
+
| Zero Trust | « ne rien accorder sans preuve » : aucune requête n'est de confiance par défaut. |
|
|
171
|
+
| JWT | JSON Web Token : jeton signé porté par le client (RFC 7519). |
|
|
172
|
+
| OAuth 2 | Protocole de délégation d'autorisation (RFC 9700 BCP). |
|
|
173
|
+
| WebAuthn | Authentification par passkey/clé (W3C WebAuthn L3). |
|
|
174
|
+
| TOTP/HOTP | Codes à usage unique temporels/à compteur — 2FA (RFC 6238 / 4226). |
|
|
175
|
+
| MFA / 2FA | Authentification à plusieurs / deux facteurs. |
|
|
176
|
+
| CSRF | Cross-Site Request Forgery : requête authentifiée forgée par un site tiers. |
|
|
177
|
+
| CORS | Cross-Origin Resource Sharing : règles d'appel cross-origine. |
|
|
178
|
+
| CSP | Content-Security-Policy : restreint les sources de scripts (anti-XSS). |
|
|
179
|
+
| HSTS | HTTP Strict Transport Security : force le TLS (RFC 6797). |
|
|
180
|
+
| RBAC | Role-Based Access Control : droits selon le rôle. |
|
|
181
|
+
| Voter | Composant qui vote « accès accordé/refusé » sur un critère (rôle, scope). |
|
|
182
|
+
| BFF | Backend-For-Frontend : le serveur gère la session/les jetons pour le front. |
|
|
183
|
+
| PAT | Personal Access Token : une clé d'API opaque, révocable côté serveur. |
|
|
184
|
+
|
|
185
|
+
## 📡 Observabilité — Studio
|
|
186
|
+
|
|
187
|
+
Quatre écrans dédiés (`@nodefony/studio/frontend/src/routes/`) : **Firewall** (zones et décisions,
|
|
188
|
+
état runtime), **ApiKeys**, **Audit** (journal), **Webhooks** — plus les pages `Roles`, `Sessions`,
|
|
189
|
+
`Login`, `Users`. Data plane admin : `SecurityAdminApi` / `WebhookAdminApi` sous
|
|
190
|
+
`/nodefony/security/api/*`.
|
|
191
|
+
|
|
192
|
+
## 🧪 Tests & couverture
|
|
193
|
+
|
|
194
|
+
Le module est le plus testé du framework. Chaque page de brique porte l'**inventaire de ses tests**
|
|
195
|
+
(unitaires, intégration, E2E sur base réelle, bancs de contrat, tests d'attaque) **et dit ce qui
|
|
196
|
+
manque** — un trou de couverture nommé vaut mieux qu'un chiffre flatteur. Les compteurs sont
|
|
197
|
+
recomptés à chaque génération, jamais figés dans le texte.
|
|
198
|
+
|
|
199
|
+
## 🔗 Pour aller plus loin
|
|
200
|
+
|
|
201
|
+
- ⬆️ **Remonter** : [Toute la documentation](../../../../../docs/index.md)
|
|
202
|
+
- 🧭 **Modules voisins** : [`@nodefony/user`](../../user/docs/index.md) (l'identité) ·
|
|
203
|
+
[`@nodefony/http`](../../http/docs/index.md) (transport et sessions) ·
|
|
204
|
+
[`@nodefony/framework`](../../framework/docs/index.md) (décorateurs `@IsGranted`, `@CurrentUser`)
|
|
205
|
+
- 🏛️ **Transverse** : [pipeline de requête](../../../../../docs/architecture/pipeline-requete.md) —
|
|
206
|
+
où le firewall s'insère exactement dans le trajet d'une requête.
|
|
207
|
+
- 📖 [Lexique général](../../../../../docs/lexique.md) du framework.
|
package/docs/lexique.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Lexique sécurité — sigles & termes expliqués"
|
|
3
|
+
navTitle: Lexique sécurité
|
|
4
|
+
lang: fr
|
|
5
|
+
module: "@nodefony/security"
|
|
6
|
+
topic: lexique-securite
|
|
7
|
+
section: "Sécurité"
|
|
8
|
+
audience: [developer]
|
|
9
|
+
tags: [lexique, securite, jwt, oauth, webauthn, csrf, rbac, voters, glossaire]
|
|
10
|
+
status: stable
|
|
11
|
+
updated: 2026-07-20
|
|
12
|
+
source: "src/packages/@nodefony/security/docs/lexique.md"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Lexique sécurité Nodefony
|
|
16
|
+
|
|
17
|
+
📍 [Documentation](../../../../../docs/index.md) › [Sécurité](index.md) › **Lexique**
|
|
18
|
+
|
|
19
|
+
> Chaque sigle de la sécurité Nodefony : développé → une explication simple. Toute nouvelle
|
|
20
|
+
> abréviation rencontrée dans le code/doc DOIT avoir son entrée ici. Les termes transverses
|
|
21
|
+
> (opt-in, lazy, DI, fail-closed…) vivent dans le [lexique général](../../../../../docs/lexique.md) —
|
|
22
|
+
> ce fichier ne porte que le vocabulaire PROPRE à la sécurité.
|
|
23
|
+
|
|
24
|
+
## 📖 Lexique
|
|
25
|
+
|
|
26
|
+
### Architecture & patterns
|
|
27
|
+
|
|
28
|
+
<!-- prettier-ignore -->
|
|
29
|
+
| Sigle | Développé | En clair |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| **BFF** | Backend For Frontend | Le « majordome du navigateur » : le serveur garde les jetons, le navigateur n'a qu'un ticket de vestiaire (cookie de session opaque, illisible en JavaScript). Pattern n°1 IETF pour les apps web. |
|
|
32
|
+
| **Zero Trust** | — | « Fermé sauf si explicitement ouvert » : zone protégée + visiteur anonyme → 401, toujours. Aucune confiance implicite. |
|
|
33
|
+
| **ALS** | AsyncLocalStorage (Node.js) | Le « fil d'Ariane » d'une requête : un espace de stockage attaché à la requête en cours, accessible partout sans passer d'argument. L'utilisateur authentifié y vit. |
|
|
34
|
+
| **mTLS** | mutual TLS (TLS mutuel) | HTTPS contrôle l'identité du serveur ; mTLS contrôle AUSSI celle du client (certificat client exigé) — l'ambassade vérifie ton passeport avant d'ouvrir. Machine↔machine, zones admin. |
|
|
35
|
+
| **CRUD** | Create Read Update Delete | Les 4 opérations de base sur une ressource. |
|
|
36
|
+
|
|
37
|
+
### Jetons & sessions
|
|
38
|
+
|
|
39
|
+
<!-- prettier-ignore -->
|
|
40
|
+
| Sigle | Développé | En clair |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| **JWT** | JSON Web Token | La « carte plastifiée signée » : un jeton auto-porteur (identité + rôles + expiration dedans, signé). Personne ne peut le modifier, mais on ne peut pas le rappeler avant expiration. Réservé API/machines chez Nodefony. |
|
|
43
|
+
| **JWKS** | JSON Web Key Set | L'annuaire public des clés de signature du serveur — permet aux autres services de vérifier les JWT sans secret partagé. |
|
|
44
|
+
| **`kid`** | Key ID | L'étiquette dans l'en-tête d'un JWT qui dit QUELLE clé l'a signé → permet la rotation des clés sans invalider les anciens jetons. |
|
|
45
|
+
| **`jti`** | JWT ID | Numéro de série unique d'un JWT → permet de le révoquer individuellement (liste noire). |
|
|
46
|
+
| **`aud`** | Audience | Le claim « pour qui est ce jeton » : un jeton volé pour le service A ne marche pas sur le service B. Validation obligatoire (RFC 8707/9700). |
|
|
47
|
+
| **DPoP** | Demonstrating Proof of Possession | Jeton « menotté » au client : le porteur prouve qu'il détient une clé privée à chaque usage → un jeton volé seul ne sert à rien. (RFC 9449) |
|
|
48
|
+
| **`cnf`** | confirmation (key binding) | Empreinte de la clé à laquelle un jeton est **menotté** (_sender-constrained_) : `jkt` (DPoP, RFC 9449) ou `x5t#S256` (mTLS, RFC 8705). Un jeton volé sans la clé privée = inutilisable. Slot réservé du store Nodefony. |
|
|
49
|
+
| **PAT** | Personal Access Token | Clé API personnelle (style GitHub : `nf_xxx_secret`) — stockée hachée, affichée une seule fois. |
|
|
50
|
+
|
|
51
|
+
### JWT — claims, signature & portée
|
|
52
|
+
|
|
53
|
+
<!-- prettier-ignore -->
|
|
54
|
+
| Sigle | Développé | En clair |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| **JWS** | JSON Web Signature | La signature qui rend un JWT infalsifiable : la 3ᵉ partie (`en-tête.charge.SIGNATURE`). |
|
|
57
|
+
| **JWK** | JSON Web Key | Une clé cryptographique au format JSON. Une JWK **publique** ne contient jamais le paramètre privé `d`. |
|
|
58
|
+
| **claim** | revendication | Une affirmation portée par le JWT. Standards (RFC 7519) : `iss` (émetteur), `sub` (sujet), `aud` (destinataire), `exp` (expire le), `nbf` (pas avant), `iat` (émis à), `jti` (n° série). |
|
|
59
|
+
| **Bearer** | « au porteur » | Mode d'envoi `Authorization: Bearer <jwt>`. Quiconque le détient s'en sert (billet au porteur) → HTTPS + `exp` court obligatoires. Chez Nodefony le JWT voyage ainsi, jamais en cookie. |
|
|
60
|
+
| **EdDSA / Ed25519** | Edwards-curve DSA | Algo de signature moderne (rapide, déterministe, clés de 32 o). **Défaut JWT** de Nodefony. Ed25519 = la courbe utilisée. |
|
|
61
|
+
| **OKP** | Octet Key Pair | La famille de clé (`kty`) des courbes Edwards (Ed25519) au format JWK. |
|
|
62
|
+
| **Refresh token** | jeton de rafraîchiss. | Jeton long qui obtient un nouvel _access_ court sans re-login. Stocké serveur → **révocable** (≠ access auto-porté). |
|
|
63
|
+
| **Rotation** | — | À chaque rafraîchissement : ancien refresh invalidé, nouveau émis (OWASP RFC 9700). |
|
|
64
|
+
| **Reuse detection** | détection de rejeu | Un refresh déjà tourné qui resurgit = preuve de fuite → on révoque toute la **famille** de jetons. |
|
|
65
|
+
| **Scope** | portée | Capacités accordées à UN jeton (`orders:read`), axe **distinct** des rôles → `@RequireScope`. Un PAT peut en avoir moins que son porteur. |
|
|
66
|
+
| **Downscoping** | réduction de portée | Un jeton n'accorde jamais plus que son porteur : création scopes ⊆ droits du user, usage scopes ∩ droits actuels. |
|
|
67
|
+
| **Least privilege** | moindre privilège | N'accorder que le strict nécessaire : un PAT « lecture seule » d'un admin ne peut pas écrire. |
|
|
68
|
+
|
|
69
|
+
### Authentification
|
|
70
|
+
|
|
71
|
+
<!-- prettier-ignore -->
|
|
72
|
+
| Sigle | Développé | En clair |
|
|
73
|
+
| --- | --- | --- |
|
|
74
|
+
| **MFA** | Multi-Factor Authentication | Plusieurs preuves d'identité de catégories **différentes** (ce que je sais + ce que je possède + ce que je suis). Terme **générique** : 2 facteurs ou plus → englobe le 2FA. |
|
|
75
|
+
| **2FA** | Two-Factor Authentication | Cas **particulier** du MFA à **exactement 2** facteurs (ex. mot de passe + TOTP). Deux preuves de la MÊME catégorie (2 mots de passe) ≠ 2FA. « MFA » a remplacé « 2FA » car plus général, pas par rebranding. |
|
|
76
|
+
| **Facteur** | Authentication factor | Une preuve d'identité d'**une** des 3 catégories : savoir (mot de passe), possession (passkey, TOTP), inhérence (biométrie). Combiner ≥2 catégories = MFA. |
|
|
77
|
+
| **TOTP** | Time-based One-Time Password | Le code à 6 chiffres qui change toutes les 30 s (Google Authenticator). Legacy : phishable (un faux site peut te le demander). |
|
|
78
|
+
| **OTP** | One-Time Password | Mot de passe à usage unique (par mail, SMS…). SMS = déconseillé (NIST). |
|
|
79
|
+
| **KBA** | Knowledge-Based Authentication | Les « questions secrètes » (nom du chien…). **INTERDIT** par NIST : trouvable sur les réseaux sociaux. |
|
|
80
|
+
| **WebAuthn** | Web Authentication (standard W3C) | L'API navigateur des passkeys : le site demande, l'appareil signe avec une clé privée qui ne sort JAMAIS (Touch ID, Windows Hello, clé USB). |
|
|
81
|
+
| **FIDO2** | Fast IDentity Online v2 | L'alliance industrielle + protocoles derrière WebAuthn. |
|
|
82
|
+
| **Passkey** | — | Identifiant WebAuthn synchronisé (trousseau Apple/Google) : rien à retenir, rien à voler côté serveur (clé publique seulement), **non-phishable** (liée au domaine exact). |
|
|
83
|
+
| **RP / rpId** | Relying Party (ID) | « La partie qui fait confiance » = ton site, identifié par son domaine — une passkey créée pour `exemple.fr` refuse de signer ailleurs (c'est ça l'anti-phishing). |
|
|
84
|
+
| **AAL2/AAL3** | Authenticator Assurance Level | Niveaux de confiance NIST d'une authentification : AAL2 = MFA solide (passkeys synced OK), AAL3 = matériel dédié (clé physique). |
|
|
85
|
+
|
|
86
|
+
### OAuth & délégation
|
|
87
|
+
|
|
88
|
+
<!-- prettier-ignore -->
|
|
89
|
+
| Sigle | Développé | En clair |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| **OAuth 2.x** | Open Authorization | Le protocole « je laisse l'app X agir sur mon compte Y sans lui donner mon mot de passe » (login Google/GitHub…). |
|
|
92
|
+
| **OIDC** | OpenID Connect | OAuth + une carte d'identité standardisée (ID Token) : pas juste « accède », aussi « voici qui je suis ». |
|
|
93
|
+
| **PKCE** | Proof Key for Code Exchange (« pixie ») | Cadenas anti-interception du code OAuth : l'app prouve que c'est bien elle qui a démarré le flow. Obligatoire partout (OAuth 2.1). |
|
|
94
|
+
| **ROPC** | Resource Owner Password Credentials | L'app demande directement ton mot de passe — **banni** par OAuth 2.1 (c'est exactement ce qu'OAuth devait éviter). |
|
|
95
|
+
| **CIBA** | Client-Initiated Backchannel Authentication | « Approbation à distance » : l'action attend qu'un humain valide sur SON appareil (notification). Pattern clé pour les actions sensibles d'agents IA. |
|
|
96
|
+
| **SPIFFE** | Secure Production Identity Framework For Everyone | Standard d'identité des **machines/workloads** (pas des humains) : chaque process reçoit une identité vérifiable. Pertinent P12 (agents). |
|
|
97
|
+
| **Token Exchange** | RFC 8693 | « Troc de jeton » : un service/agent échange son jeton contre un autre pour agir **au nom de** quelqu'un (on-behalf-of), avec une portée réduite. Base de la délégation microservices ET agents IA. Slot Nodefony (`tokenExchange`, P12). |
|
|
98
|
+
| **`act`** | actor (acteur) | Le claim « qui agit au nom de qui » d'un Token Exchange : chaîne d'acteurs **auditable** (l'agent A agit pour l'utilisateur U) → délégation EXPLICITE, jamais une usurpation muette (≠ impersonation). |
|
|
99
|
+
|
|
100
|
+
### Attaques & défenses web
|
|
101
|
+
|
|
102
|
+
| Sigle | Développé | En clair |
|
|
103
|
+
| ------------------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
104
|
+
| **XSS** | Cross-Site Scripting | Injection de JavaScript malveillant dans ta page → il lit tout ce que le JS peut lire (d'où : jetons JAMAIS lisibles en JS → BFF). |
|
|
105
|
+
| **CSRF** | Cross-Site Request Forgery | Un site tiers fait émettre par TON navigateur (qui porte tes cookies) une requête que tu n'as pas voulue. Défense moderne : Fetch Metadata + SameSite. |
|
|
106
|
+
| **Fetch Metadata** | en-têtes `Sec-Fetch-*` | Le « cachet de la poste » : le navigateur tamponne lui-même chaque requête avec sa provenance (`Sec-Fetch-Site: cross-site`) — infalsifiable par le site attaquant. |
|
|
107
|
+
| **SameSite** | attribut de cookie | Quand le cookie voyage-t-il depuis un autre site ? `Lax` (défaut) : navigation oui, mutations non. `Strict` : jamais (casse les liens entrants). `None` : toujours (exige Secure). |
|
|
108
|
+
| **SSRF** | Server-Side Request Forgery | Faire émettre par TON serveur une requête vers une cible interne (ex. métadonnées cloud `169.254.169.254`). Défense webhooks : refuser les IP privées. |
|
|
109
|
+
| **HSTS** | HTTP Strict Transport Security | En-tête « ce site est HTTPS-only pour 1 an » → le navigateur refuse tout HTTP même si l'utilisateur tape http://. |
|
|
110
|
+
| **CSP** | Content-Security-Policy | Liste blanche de ce que la page a le droit de charger/exécuter — l'anti-XSS structurel. Le « nonce » = jeton unique par requête qui signe les scripts légitimes. |
|
|
111
|
+
| **HMAC** | Hash-based Message Authentication Code | Signature symétrique d'un message avec un secret partagé — prouve l'origine ET l'intégrité (webhooks signés). |
|
|
112
|
+
| **CSPRNG** | Cryptographically Secure PRNG | Générateur d'aléa imprévisible (≠ `Math.random()`). Obligatoire pour les ID de session. |
|
|
113
|
+
|
|
114
|
+
### Attaques JWT & durcissement cookie
|
|
115
|
+
|
|
116
|
+
| Sigle | Développé | En clair |
|
|
117
|
+
| ----------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| **`alg=none`** | — | Attaque JWT : un jeton déclare « aucune signature » ; une lib naïve l'accepte → usurpation totale. Défense : **allowlist** d'algos serveur, jamais l'`alg` reçu. |
|
|
119
|
+
| **Algorithm confusion** | substitution d'algo | Attaque JWT : faire vérifier un RS256 comme un HS256 avec la clé **publique** en secret HMAC. Défense : 1 clé = 1 algo, fixé serveur. |
|
|
120
|
+
| **allowlist/denylist** | liste blanche / noire | Allowlist = « seulement ceux-ci » (algos acceptés) ; denylist = « tous sauf » (`jti` révoqués). En sécu, préférer l'allowlist. |
|
|
121
|
+
| **`__Host-`** | préfixe de nom de cookie | Le navigateur refuse `__Host-x` sans `Secure` + `Path=/` + sans `Domain` → cookie cloué à l'hôte exact (anti sous-domaine pirate). Nodefony : la **session**, pas le JWT. |
|
|
122
|
+
|
|
123
|
+
### Autorisation (qui a le droit de faire quoi)
|
|
124
|
+
|
|
125
|
+
> **authn ≠ authz.** L'**authentification** (authn) répond « QUI es-tu ? » (le firewall, le login).
|
|
126
|
+
> L'**autorisation** (authz) répond « as-tu le DROIT de faire ça ? » (les voters, `@IsGranted`).
|
|
127
|
+
> On peut être authentifié ET refusé (un `user` connecté sur une route `ROLE_ADMIN` → **403**, pas 401).
|
|
128
|
+
|
|
129
|
+
| Sigle / terme | Développé | En clair |
|
|
130
|
+
| ----------------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
131
|
+
| **RBAC** | Role-Based Access Control | Droits par RÔLES (`ROLE_ADMIN` peut X). Simple, couvre 80 % des besoins. Niveau **A** chez Nodefony (`RoleVoter`). |
|
|
132
|
+
| **ABAC** | Attribute-Based Access Control | Droits par ATTRIBUTS contextuels (le **propriétaire** du document peut le modifier) → les voters reçoivent le `subject`. Niveau **C**. |
|
|
133
|
+
| **Voter** | « votant / juré » | Petit juge spécialisé : pour une décision donnée il rend **un** verdict parmi 3 (GRANT / DENY / ABSTAIN). On en empile autant qu'on veut (rôles, propriété, horaires…), chacun sur son domaine. |
|
|
134
|
+
| **GRANT / DENY / ABSTAIN** | accorde / refuse / s'abstient | Les 3 verdicts d'un voter. **ABSTAIN** = « pas mon rayon » (ne compte pas). C'est la combinaison des votes qui tranche, pas un seul. |
|
|
135
|
+
| **`AuthorizationService.decide()`** | — | Le **juge en chef** (`authorization.ts`, J6) : interroge tous les voters et applique la stratégie de vote → un seul booléen GRANT/DENY. |
|
|
136
|
+
| **Stratégie affirmative** | — | « **un seul GRANT suffit** » (tant qu'aucun DENY) — la stratégie de `decide()`. Permissive sur l'accord, stricte sur le refus. |
|
|
137
|
+
| **Veto (DENY)** | — | « **un seul DENY refuse tout** », même si d'autres votent GRANT. Le refus l'emporte toujours (sécurité d'abord). |
|
|
138
|
+
| **Default DENY** | refus par défaut | Tous ABSTAIN, ou **zéro** voter, ou aucun GRANT → **refusé** (Zero Trust). Il faut un OUI explicite, le silence ne suffit pas. |
|
|
139
|
+
| **Fail-closed (voter)** | « échoue fermé » | Si un voter **plante** (throw) → compté comme DENY + log ERROR, jamais une 500 qui laisserait passer. L'erreur ne doit jamais ouvrir la porte (cf lexique général `fail-closed`). |
|
|
140
|
+
| **`voterRegistry`** | registre de voters | Fabrique pluggable (convention-frère de `authenticatorRegistry`) : on **ajoute** un voter sans toucher `decide()`. Le futur `PermissionVoter` (RBAC ORM, niveau B/J6b) s'y branchera. |
|
|
141
|
+
| **`RoleVoter`** | — | Le voter niveau **A** : GRANT si le token porte le rôle demandé (via `RoleHierarchyWalker`), ABSTAIN sinon — **jamais de veto** (il ne bloque pas les attributs qu'il ne connaît pas). |
|
|
142
|
+
| **Attribute** | attribut (de décision) | La chose demandée passée à `decide()` : un rôle (`ROLE_ADMIN`), une permission (`post:edit`)… Ne PAS confondre avec l'ABAC « attribut contextuel » (le `subject`). |
|
|
143
|
+
| **Subject** | sujet / ressource ciblée | L'objet **sur lequel** porte l'action (le document à éditer), passé au voter pour les règles ABAC (« est-il le propriétaire ? »). Optionnel — souvent un param de route via `@IsGranted(..., { subject })`. |
|
|
144
|
+
|
|
145
|
+
### Décorateurs sécurité (panoplie J7)
|
|
146
|
+
|
|
147
|
+
> Annotations posées sur un **controller** ou une **méthode d'action** (cf lexique général `décorateur`).
|
|
148
|
+
> Ils vivent dans `@nodefony/framework` mais expriment des règles de sécurité ; le moteur d'autorisation
|
|
149
|
+
> est appelé **par son nom** (0 cycle de dépendance). La **garde** s'exécute dans `Resolver.executeAction`,
|
|
150
|
+
> AVANT d'instancier le controller → un refus court-circuite tout (403 sans rien allouer).
|
|
151
|
+
|
|
152
|
+
<!-- prettier-ignore -->
|
|
153
|
+
| Décorateur | Rôle |
|
|
154
|
+
| --- | --- |
|
|
155
|
+
| **`@IsGranted`** | « exige ce(s) droit(s) ». `@IsGranted("ROLE_ADMIN")`. **Empilés = ET** (toutes les conditions). **Tableau = OU** (`@IsGranted(["ROLE_A", "ROLE_B"])` → l'un OU l'autre). Absorbe `@HasAnyRole`/`@HasAllRoles`. |
|
|
156
|
+
| **`@Anonymous`** | « route **publique** » : bypasse le firewall, et **annule** un `@IsGranted` posé au niveau de la classe. À déclarer explicitement (Zero Trust : sinon tout est fermé). |
|
|
157
|
+
| **`@CurrentUser`** | Injecte l'utilisateur authentifié (lu dans l'ALS) **en paramètre** de l'action — pas besoin d'aller le chercher dans le contexte à la main. |
|
|
158
|
+
| **Garde (guard)** | La vérification elle-même : le code du Resolver qui lit les métadonnées `@IsGranted`, appelle `decide()`, et laisse passer (GRANT) ou lève **403** (DENY). **Une seule garde couvre tous les transports** (HTTP, WS `api.request`, forward) — c'est l'invariant « 1 garde = N transports ». |
|
|
159
|
+
|
|
160
|
+
### Organismes & textes
|
|
161
|
+
|
|
162
|
+
<!-- prettier-ignore -->
|
|
163
|
+
| Sigle | Développé | En clair |
|
|
164
|
+
| --- | --- | --- |
|
|
165
|
+
| **IETF** | Internet Engineering Task Force | L'organisme qui écrit les standards d'Internet (les RFC). |
|
|
166
|
+
| **RFC** | Request For Comments | Un standard IETF numéroté (RFC 9700…). Malgré le nom modeste, c'est LA norme. |
|
|
167
|
+
| **BCP** | Best Current Practice | Catégorie de RFC : « les bonnes pratiques actuelles » consolidées. |
|
|
168
|
+
| **W3C** | World Wide Web Consortium | Standards du web côté navigateur (WebAuthn, CSP…). |
|
|
169
|
+
| **NIST** | National Institute of Standards and Technology | Agence US dont les guidelines (SP 800-63) font référence mondiale pour l'identité numérique. |
|
|
170
|
+
| **OWASP** | Open Worldwide Application Security Project | Communauté de référence sécu applicative (Top 10, Cheat Sheets). |
|
|
171
|
+
| **ANSSI** | Agence Nationale de la Sécurité des Systèmes d'Information | L'autorité française de cybersécurité. |
|
|
172
|
+
|
|
173
|
+
## ⚠️ Pièges — confusions fréquentes en sécurité
|
|
174
|
+
|
|
175
|
+
Un même mot recouvre deux réalités : les confondre ouvre une faille ou brouille un raisonnement.
|
|
176
|
+
|
|
177
|
+
| Confusion | À garder en tête |
|
|
178
|
+
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| **authn ≠ authz** | authn = « QUI es-tu ? » (firewall, login). authz = « as-tu le DROIT ? » (voters, `@IsGranted`). Authentifié **et** refusé = **403**, jamais 401. |
|
|
180
|
+
| **MFA vs 2FA** | 2FA = cas particulier du MFA à **exactement 2** facteurs de catégories **différentes**. Deux mots de passe ≠ 2FA (même catégorie). |
|
|
181
|
+
| **scope vs rôle** | Deux axes distincts : le **rôle** dit qui tu es (`ROLE_ADMIN`) ; le **scope** dit ce que CE jeton peut (`orders:read`). Un PAT a des scopes ⊆ des droits de son porteur. |
|
|
182
|
+
| **Attribute (decide) vs attribut ABAC** | `Attribute` = la chose demandée à `decide()` (un rôle, une permission). L'« attribut » ABAC = le **contexte** (le `subject`, ex. le propriétaire). Homonymes, sens opposés. |
|
|
183
|
+
| **allowlist vs denylist** | allowlist = « seulement ceux-ci » (algos JWT acceptés) ; denylist = « tous sauf » (`jti` révoqués). En sécu, préférer l'allowlist. |
|
|
184
|
+
| **JWT en cookie ?** | **Non.** Chez Nodefony le JWT voyage en `Authorization: Bearer` (API/machines) ; le **cookie** ne porte qu'une session opaque BFF (web/Studio). Les confondre casse le modèle hybride. |
|
|
185
|
+
|
|
186
|
+
## 🔗 Pour aller plus loin
|
|
187
|
+
|
|
188
|
+
- ⬆️ **Retour au hub** : [Sécurité — vue d'ensemble](index.md) · [Toute la documentation](../../../../../docs/index.md)
|
|
189
|
+
- 📖 [Lexique général](../../../../../docs/lexique.md) — le vocabulaire transverse (opt-in, lazy, DI, fail-closed…)
|
|
190
|
+
- 🔥 [Firewall](firewall.md) · 🎫 [Jetons](tokens.md) · 🛡️ [CSRF](csrf.md) — les briques où ces termes s'appliquent
|