Usage du framework Rustwarden (vendored)
Version synchronisée : voir .rustwarden-version à la racine.
Resynchronisation uniquement via update-project (depuis le dépôt
Rustwarden) — jamais de modification manuelle de crates/rustwarden-core/.
Référence API : docs/SERVICES_REFERENCE.md (resynchronisé à chaque update).
Services consommés
| Service / primitive | Usage BotPlace |
|---|---|
| Auth JWT + sessions (mode headless) | Login SSR fourni côté app ; pages protégées via register_protected_prefix (/config, /chat dans src/main.rs ; /home, /profile, /settings, /admin via botplace_ui::with_ssr_auth_policy) |
rustwarden_core::auth::auth_api_routes() | Routeur machine canonique (/api/v1/auth/* : login, refresh, 2FA, reset, vérification, changement d'email, limite IP sur les routes pré-session) monté tel quel par botplace_ui::machine_routes() + /health (plan 006, tranche C) |
| Users / teams | Identités et groupes du cabinet (teams = « groupes » de la spec) |
| RBAC (rôles/permissions) | Distinction admin vs collaborateur (file des déviances, adoption) |
EmailChangeService::admin_force_change | Correction d'adresse par l'admin depuis la fiche compte (PUT /admin/users/{id}) — audit framework email_changed_by_admin, sessions de la cible révoquées (plan 006, tranche D) |
ensure_default_admin (bootstrap) | Création de l'admin au démarrage (seul chemin qui accepte le nom réservé admin) ; réutilisé par les harnais de tests (tests/common/mod.rs) |
SecurityHeadersConfig | CSP explicite (DEFAULT_CONTENT_SECURITY_POLICY, avec 'unsafe-eval') via botplace_ui::with_alpine_csp — voir Workarounds |
| CSRF structurel (canal browser) | Toutes les routes HTMX du plan 001 |
| Rate limiting | Défauts du framework ; limite IP sur login/register/refresh/2FA héritée d'auth_api_routes() |
Hooks on_audit_event | Prévu : alimentation du journal d'audit métier (tranche 6) |
| Personal Access Tokens | Prévu : authentification des instances hermes-agent (canal machine, plan ultérieur) |
Hooks implémentés
on_user_login (src/main.rs, BotplaceHooks) : couche utilisateur,
composition scellée, provisionnement de l'instance — jamais bloquant.
Workarounds / besoins upstream
Format : date, besoin, workaround appliqué, renvoi RFC upstream si le besoin persiste.
2026-10-02 — CSP par défaut sans 'unsafe-eval' vs build Alpine standard
- Besoin : les écrans de gouvernance chargent
crates/web/static/alpine.min.js(build Alpine 3.14.9 standard, 98 expressions inline dans 10 templates) qui compile ses expressions parnew Function. La CSP par défaut 1.1.0 (RFC 0039 phase 2) retire'unsafe-eval': toute l'interactivité casserait en silence. - Workaround :
botplace_ui::with_alpine_csp(builder)repose la politique 1.0.1 (DEFAULT_CONTENT_SECURITY_POLICY), constante fournie par le framework exactement pour ce retour arrière. Test :crates/botplace-ui/tests/politique_csp.rs. - Sortie : migration vers
@alpinejs/csp+ composantsAlpine.data(..)(chantier à formuler). Aucune RFC upstream : le framework documente ce chemin.
2026-10-02 — .auth_failure_mode(..) / .login_path(..) du builder non honorés par AuthService/AdminService
- Besoin : garantir la redirection SSR vers
/loginquel que soit l'environnement (plan 005, A2). - Constat : dans
RustwardenApp::build, les couchesAuthServiceetAdminServicesont posées à l'extérieur de l'Extension(Arc<AuthConfig>). Au moment où elles s'exécutent l'extension est absente ; elles retombent surAuthConfig::from_env()(fallback assumé par un commentaire du code) et lisent doncAUTH_FAILURE_MODE/LOGIN_PATHdans l'environnement. Les overrides du builder ne sont honorés que par les extracteurs internes (auth_required,admin_required). Mis en évidence le 2026-10-02 parprefixes_proteges.rs(première exécution sur base disponible). - Workaround :
AUTH_FAILURE_MODE=redirectdocumenté dans.env.example(défaut framework identique si absent) ; le builder garde l'override pour les chemins qui le lisent ; le test fixe l'environnement à cette valeur. - RFC upstream à ouvrir :
AuthService::new/AdminService::newdoivent recevoir l'AuthConfigrésolue à la construction (commesecurity_headers_middlewarecapture sonArc), ou l'Extensiondoit être posée plus à l'extérieur que ces couches.
Adaptations aux breaking changes
2026-10-02 — update-project vers 9f3c757 (1.1.0 + RFC 0039 phase 2)
cargo check vert sans modification : ruptures comportementales
uniquement. Détail, Gherkin et décisions :
docs/plans/006-rustwarden-1.1-adaptation.md. Hors crates/rustwarden-* :
- RFC 0036 (
Username) —create_user("admin")refusé (nom réservé) : les harnais de tests bootstrapent l'admin parensure_default_admin(crates/{web,botplace-ui}/tests/common/mod.rs), le nomadminrestant nécessaire (coucheusers/admindes fixtures, relue depuis la base par les handlers). Formulairesuser_new,user_edit,profile:pattern,maxlength="39", aide en français. - 1.0.1 (
AdminConfig::validate) —ADMIN_PASSWORD=passwordrefusé sur le chemin de création : mot de passe fort dans les tests (admin_env()) ;.envlocal à corriger (secret). - 1.0.1 (limiteurs partagés) — les services reset / validation partagent
un limiteur « 3 emails / heure / adresse » par processus : les scénarios de
comptes.rsinvitent « claire » sur une adresse propre à chacun. - RFC 0039 phase 2 — CSP : voir Workarounds.
auth_api_routes()enrichi —machine_routes()délègue au routeur canonique au lieu d'une liste recopiée (qui n'avait ni limite IP sur le login, ni routes email-change). Test :tests/canal_machine.rs.- RFC 0041 —
update_profilerefuse toute nouvelle adresse : fiche admin →admin_force_change; profil → email en lecture seule (self-service à formuler). Tests :comptes.rs. - Migrations 10 et 11 (
totp_last_used_step,pending_email_changes) : jouées sur la base de dev parcargo run --bin migrate;auto_migrate(true)les joue au boot en production mono-instance.
Non concernés : RFC 0037 (aucun patch TOTP local), contrainte
chk_email_queue_email_type (non redéfinie), hook auth.login_blocked (non
implémenté), pin SeaORM (déjà 2.0.0), ADMIN_USERNAME=admin (bootstrap).
2026-08-01 — update-project vers 6261a6b
Trois adaptations, toutes hors crates/rustwarden-* (voir
docs/plans/005-rustwarden-a3-protected-prefixes-migration.md) :
- Pin SeaORM — le core est passé de
2.0.0-rc.20à2.0.0stable ;Cargo.tomlracine (jamais touché parupdate-project) épinglait=2.0.0-rc.41→ résolution de dépendances impossible. Pin aligné sur2.0.0. Aucune rupture d'API métier (cargo checkvert sans autre modification). - A3 — préfixes protégés vidés par défaut (
with_uiles réenregistre, BotPlace ne l'appelle pas) :/home,/profile,/settingset/adminseraient devenus publics. Réenregistrés viabotplace_ui::PROTECTED_PREFIXES/with_ssr_auth_policy. - A2 —
.headless()basculeauth_failure_modesurJson401: l'UI SSR aurait renvoyé401 {"error":"unauthorized"}au lieu d'une redirection vers/login.AuthFailureMode::Redirectimposé par le builder. Concerne aussi/admin, dontAdminServicehonore désormais le même mode d'échec. Correctif 2026-10-02 : l'override du builder n'atteint pas les couchesAuthService/AdminService(voir Workarounds) ; le contrat réel estAUTH_FAILURE_MODE=redirectdans l'environnement.
Non-régression : crates/botplace-ui/tests/prefixes_proteges.rs (monte
l'application par le vrai builder ; ✅ vert le 2026-10-02 avec
AUTH_FAILURE_MODE=redirect).
GitRust