Sécurité et RBAC¶
Guide production
Pour les bonnes pratiques de déploiement sécurisé (checklist, secrets, HTTPS, cookies, headers, CSRF, RBAC, uploads, logs), voir Sécurité en production.
Auth/User avancée
Pour l'authentification complète (login, MFA, OIDC, sessions, audit, CLI admin), voir Authentification Forge.
Socle de sécurité¶
Forge fournit les briques de sécurité suivantes dans core/security/ :
| Brique | Fichier | Rôle |
|---|---|---|
| Sessions | session.py |
Création, rotation, expiration, stockage en mémoire |
| Hachage | hashing.py |
PBKDF2-HMAC-SHA256, rate limiting sur /login |
| Décorateurs | decorators.py |
@require_auth, @require_csrf, @require_role (déprécié) |
| Middleware | middleware.py |
AuthMiddleware, CsrfMiddleware |
| Nonce CSP | csp.py |
Nonce par requête pour scripts inline contrôlés (APP_CSP_NONCE_ENABLED) |
Le RBAC complet (Role, Permission, @require_permission, make_can…) est fourni par le module opt-in forge-mvc-rbac — il n'y a pas de rbac.py dans core/security/. Voir RBAC — Contrôle d'accès.
TLS du serveur de développement¶
Le serveur HTTPS intégré à Forge impose explicitement TLS 1.2 minimum (ssl.TLSVersion.TLSv1_2). Il est destiné au développement local, à la pédagogie et aux tests — pas à la production.
En production, TLS doit être terminé par Nginx ou un reverse proxy équivalent. Forge écoute en HTTP local derrière Nginx.
Nonce CSP¶
Forge inclut par défaut l'en-tête Content-Security-Policy avec script-src 'self'. Pour autoriser des scripts inline contrôlés sans affaiblir la CSP avec unsafe-inline, activez le mécanisme de nonce :
unsafe-inline n'est jamais ajouté automatiquement. Voir référence API pour les détails.
En-têtes de sécurité¶
Forge applique des en-têtes HTTP de sécurité par défaut sur toutes les réponses (200, 302, 404, fichiers statiques, erreurs). Ces en-têtes sont des garde-fous par défaut — ils ne remplacent pas une configuration de déploiement complète.
Contrat actuel¶
| En-tête | Rôle | Valeur | Limite |
|---|---|---|---|
X-Frame-Options |
Protection clickjacking | DENY |
Complété par frame-ancestors 'none' en CSP |
X-Content-Type-Options |
Blocage MIME sniffing | nosniff |
— |
Strict-Transport-Security |
Forcer HTTPS (HSTS) | max-age=31536000; includeSubDomains |
Émis même en HTTP local ; la protection réelle requiert HTTPS côté reverse proxy |
Referrer-Policy |
Contrôle du referrer | strict-origin-when-cross-origin |
— |
Content-Security-Policy |
Restriction des sources | Voir section CSP | Ne remplace pas une revue des templates |
Permissions-Policy |
Restriction des API navigateur | camera=(), microphone=(), geolocation=(), payment=() |
Ne couvre pas toutes les API navigateur |
CSP¶
La valeur par défaut :
default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;
frame-ancestors 'none'; object-src 'none'; base-uri 'none'; form-action 'self'
unsafe-inline et unsafe-eval ne sont jamais ajoutés automatiquement. Pour les scripts inline contrôlés, activer le nonce par requête (APP_CSP_NONCE_ENABLED=true — voir section Nonce CSP ci-dessus).
HSTS¶
Forge émet Strict-Transport-Security sur toutes les réponses, y compris en HTTP local. En développement, cet en-tête est inoffensif mais techniquement redondant. En production, HTTPS doit être terminé par Nginx ou un reverse proxy équivalent.
Limites¶
Ces en-têtes ne remplacent pas :
- la configuration HTTPS et TLS du reverse proxy ;
- une revue de sécurité des templates applicatifs ;
- une politique de déploiement sécurisé complète (voir Sécurité en production).
Forge ne promet pas une sécurité complète par défaut. Les en-têtes fournis sont des garde-fous raisonnables, testés et verrouillés comme contrat public (SECURITY-HEADERS-DOC-LOCK-001).
Ce que Forge n'émet pas encore¶
Cross-Origin-Resource-PolicyetCross-Origin-Opener-Policyne sont pas émis par défaut.Permissions-Policyne liste pas toutes les API navigateur disponibles.
RBAC — documentation complète¶
La documentation complète du RBAC Forge (rôles, permissions, décorateurs, helper Jinja, génération CRUD, chaîne de confiance) se trouve dans RBAC — Contrôle d'accès.
Résumé rapide¶
from forge_mvc_rbac import require_permission, has_permission, make_can
# Protéger une route serveur
@staticmethod
@require_permission("posts.edit")
def edit(request): ...
# Vérifier une permission dans le code
if has_permission(request, "posts.edit"):
...
# Helper Jinja — injecté automatiquement par BaseController.render(request=request)
# {% if can("posts.edit") %} ... {% endif %}
Injecter les permissions après authentification :
utilisateur = {
"UtilisateurId": row["id"],
"Login": row["login"],
"roles": ["admin"],
"permissions": ["posts.edit", "posts.delete", "users.view"],
}
nouveau_id = authentifier_session(session_id, utilisateur)
Store de session configurable¶
Forge accepte un store de session explicite via :
Le store doit implémenter le protocole SessionStore (core.sessions.contract) :
create, get, set, replace, delete, regenerate, authenticate,
touch_expiry, set_flash, get_flash.
Le store par défaut est MemorySessionStore (mono-processus, sessions perdues au
redémarrage). Passer None réinitialise à ce comportement par défaut.
Trois backends sont disponibles dans core.sessions :
MemorySessionStore, FileSessionStore, MariaDbSessionStore.
Leur documentation complète est traitée dans le ticket SESSIONS-STORE-CONTRACT-DOC-001.
Ce que Forge ne fait pas¶
- Pas d'ORM complet pour les permissions.
- Pas de gestion automatique des politiques (
deny by defaultreste à l'application). - Pas de cache de permissions distribué.
- Pas de hiérarchie de rôles automatique.
- Pas de liaison
user ↔ rôle ↔ permissiondans le core (appartient à l'application).