A system engine, not another dashboard.
Most admin tools treat CRUD as the product and bolt on auth, recovery and audit afterward. RustIO inverts that: authority — who may do what, how sessions end, how access is recovered, what gets recorded — is designed as one system, governed by checked-in contract documents. The CRUD is the easy layer on top.
Authority, sessions, recovery and audit — engineered as one system.
The weight of production administrative work sits underneath the CRUD surface. RustIO treats it as first-class, not an afterthought.
Admin surface
#[derive(RustioAdmin)] generates list, create, edit and delete pages. impl ModelAdmin overrides the defaults. Per-model RBAC over a five-tier role hierarchy.
Identity & sessions
DB-backed sessions with Argon2id passwords, hashed-at-rest tokens, and centralised invalidation. Doctrine 22: session invalidation has a single writer.
Recovery
Self-service forgot & reset, admin-driven reset/lock/unlock/revoke, auto-throttle on failed logins, and a re-auth wall for destructive actions.
Audit by default
Every authority mutation emits a typed AuditEvent with stable identifiers, per-request correlation IDs, and redaction helpers for tokens and passwords.
AI assistant permissions
rustio ai governs what an external AI coding assistant may do — an approval & audit layer, not an embedded model. Every capability sorted Allowed / Needs approval / Blocked.
Project memory
rustio memory records the why behind a project — decisions, rejected ideas, assumptions — so an AI or a new teammate reads years of reasoning in minutes. Code always wins.
Session invalidation has a single writer.
Recovery and login surfaces collapse every failure mode into one response shape.
Every authority mutation emits a typed AuditEvent.
Argon2id for passwords. SHA-256 for session and reset tokens.
An admin surface is one derive, one impl, one register call.
#[derive(RustioAdmin)] pub struct Post { pub id: i64, pub title: String, /* … */ } impl Model for Post { /* TABLE, COLUMNS, from_row, insert_values */ } impl ModelAdmin for Post {} // accept every default let admin = Admin::new().model::<Post>(); let router = register_admin_routes(Router::new(), admin, db, templates); Server::new(router, addr).run().await?;
No longer a single repo — a small, disciplined ecosystem.
Four crates ship together; companions and a commercial line surround the open core. Core repos only — no clutter.