rustio-admin 0.31.0

Django Admin, but for Rust. A small, focused admin framework.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
<p align="center">
  <img src="docs/assets/rustio-logo.png" alt="RustIO" width="250">
</p>

<p align="center">
  <strong>rustio-admin</strong>
</p>

<p align="center">
  A Rust-first business-system engine — the operational foundation for serious software.
</p>

<p align="center">
  <a href="https://crates.io/crates/rustio-admin"><img alt="rustio-admin on crates.io" src="https://img.shields.io/crates/v/rustio-admin.svg?label=rustio-admin"></a>
  <a href="https://crates.io/crates/rustio-admin-cli"><img alt="rustio-admin-cli on crates.io" src="https://img.shields.io/crates/v/rustio-admin-cli.svg?label=rustio-admin-cli"></a>
  <a href="https://docs.rs/rustio-admin"><img alt="docs.rs" src="https://img.shields.io/docsrs/rustio-admin"></a>
  <a href="https://github.com/abdulwahed-sweden/rustio-admin/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/abdulwahed-sweden/rustio-admin/actions/workflows/ci.yml/badge.svg"></a>
  <a href="./LICENSE"><img alt="License" src="https://img.shields.io/crates/l/rustio-admin.svg"></a>
</p>

---

## What is RustIO?

RustIO (`rustio-admin`) is a **Rust-first business-system engine** — the
operational foundation you build serious software on: admin panels, workflows,
dispatch and booking backends, audit trails, and the internal tools a real
business runs on. It is not a throwaway dashboard or one more CRUD screen; it is
the layer *underneath* those things, engineered to stay fast, safe, and
understandable as a company grows.

**The problem it solves.** RustIO was born from a real market problem, not from
a wish to build another admin panel. A fast-growing housing platform in the
Swedish market — serving well over a million customers — began to crack under
its own success. Not because of its engineers, but because the foundation it was
built on was never designed to be a heavy-duty operational engine. As data
grows, workflows multiply, and operational pressure rises, conventional web
stacks start to show their limits: slower performance, climbing infrastructure
cost, fragile changes, and constant firefighting. The problem was never the
team — it was a weak foundation.

RustIO exists for exactly that moment: **when a business outgrows its first
system and needs a foundation that won't collapse under its own growth** — one
built for speed, memory safety, structural correctness, and long-term evolution.

**From idea to a safe foundation.** The workflow is deliberately simple:

> **Idea → Draft schema → Validate → Human review → Safe operational foundation.**

You describe what you need; the [`rustio-draft`](https://github.com/abdulwahed-sweden/rustio-draft)
companion drafts a `schema.json`; RustIO validates it against strict, checked-in
rules; a human reviews and approves the change; and you are left with a
foundation you can keep evolving for years. *AI drafts. RustIO validates. Diff
protects. Human approves.*

**What makes it different.** 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, not assembled from separate parts**, and governed by
checked-in contract documents. The CRUD is the easy layer on top. (In Django
terms, it is "the Rust answer to Django Admin" — but built for operations that
have to last.)

**Who it's for.** Teams building operational software that has to survive
growth: internal admin, workflow and dispatch backends, and business systems
that outgrew a first-generation stack. You get a trustworthy core without wiring
auth + sessions + recovery + audit together from separate crates — and without a
frontend build step.

Postgres only. No build step. Single binary deployment.


## 30-second example

An admin surface is one derive, one impl, one register call.

```rust
#[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?;
```

A model that wants more control fills in the `ModelAdmin` body:

```rust
impl ModelAdmin for Post {
    fn list_display()  -> &'static [&'static str] { &["title", "published", "created_at"] }
    fn list_filter()   -> &'static [&'static str] { &["published"] }
    fn search_fields() -> &'static [&'static str] { &["title", "body"] }
    fn ordering()      -> &'static [&'static str] { &["-created_at"] }
}
```


## Why RustIO exists

Three observations shape the framework.

### CRUD is the surface

The weight of production administrative work sits underneath —
authority transitions, session lifecycle, recovery, audit chains.

RustIO treats these as first-class concerns.

### Doctrine before implementation

Authentication, recovery, session invalidation, and audit
behaviour are governed by checked-in contract documents.

Pull requests are reviewed against the doctrine, not only
against the implementation diff.

### Operational clarity over flexibility

The framework targets one database, ships one stylesheet, and
requires no build step.

Authority, sessions, recovery, and audit receive the
engineering attention. The rest stays intentionally simple.

---

The framework surface stays intentionally narrow so the
security-sensitive paths remain reviewable.


## Core principles

The invariants the framework refuses to break.

> **Doctrine 22**
> Session invalidation has a single writer.

> **Uniform outward responses**
> Recovery and login surfaces collapse every failure mode
> into a single response shape.

> **Audit-by-default**
> Every authority mutation emits a typed `AuditEvent`.

> **No plaintext at rest**
> Argon2id for passwords. SHA-256 for session and reset tokens.


## What's in the box

The surface is grouped into these concerns.

### Admin surface

- `#[derive(RustioAdmin)]` on a struct generates list, create,
  edit, and delete pages.
- `impl ModelAdmin` overrides defaults — `list_display`,
  `list_filter`, `search_fields`, `ordering`, `list_per_page`.
- Per-model RBAC over a five-tier role hierarchy.

### Identity and sessions

- DB-backed sessions with Argon2id passwords.
- Hashed-at-rest session tokens.
- Centralised invalidation through `auth::sessions::invalidate_sessions`.

### Recovery

- Self-service forgot and reset.
- Admin-driven password reset, lock, unlock, and revoke.
- Auto-throttle on failed logins.
- Re-auth wall for destructive admin actions.

### Audit and observability

- Typed `AuditEvent` with stable string identifiers.
- Per-request correlation IDs.
- Redaction helpers for tokens and passwords.

### AI assistant permissions

- `rustio ai` governs what an external AI coding assistant (Claude
  Code, Copilot, Cursor, …) may do in the project — a permissions /
  approval / audit layer, **not** an embedded model.
- A version-controlled `.rustio/ai.toml` policy sorts every capability
  into Allowed / Needs approval / Blocked. Changes are proposed,
  reviewed, approved (distinct approvers enforced), and applied as an
  explicit step; Blocked is refused outright.
- Offline by default. `--as <email>` authenticates the approver against
  the users table and mirrors the decision into `rustio_admin_actions`.
- Contract: [`DESIGN_AI_ASSISTANT.md`]./docs/design/DESIGN_AI_ASSISTANT.md.

### Project memory (CLOUD.md)

- `rustio memory` records the *why* behind a project — business intent,
  decisions, **rejected ideas**, accepted assumptions — as a project memory
  an AI assistant (or a new teammate) reads to understand years of reasoning
  in minutes.
- **Non-authoritative by design.** Code, schema, and the database are the
  source of truth; memory explains *why*, never *how the system works*. On
  any conflict, code wins.
- **Append-only and human-ratified.** It reuses the same
  propose → approve → apply pipeline as `rustio ai` (one governance path);
  entries are superseded, never rewritten; `redact` is the one bounded
  exception for removing a leaked secret. Entries render into a
  human-readable `CLOUD.md`. The running admin never reads it — dev-time
  tooling only.
- Guide: [`docs/memory.md`]./docs/memory.md. Contract:
  [`DESIGN_CLOUD.md`]./docs/design/DESIGN_CLOUD.md.

### Operational

- Postgres-only. Hyper, sqlx, and minijinja under the hood.
- Single binary deploy. No build step. One stylesheet.
- Project templates and CSS embedded at compile time.

### Visual design

- Hand-written CSS driven by `--rio-*` custom-property tokens.
- `rio-theme` (build-time companion crate) generates a safe
  `tokens.css` from one or more brand colors — WCAG-checked,
  vivid colors auto-tamed, brand-vs-semantic-state collisions
  resolved.
- v0.19 "Quiet Expert" design language: unified `.rio-section`,
  `.rio-empty-state`, `.rio-confirm`, kebab row actions,
  area-chart sparklines. See [`CHANGELOG.md`]./CHANGELOG.md
  `[0.19.0]` for the per-page record.

---

Most projects use a subset. The framework does not require
adopting all of it.


## Install

The library and the CLI ship as separate crates.

```toml
[dependencies]
rustio-admin = "0.31.0"
tokio  = { version = "1", features = ["macros", "rt-multi-thread"] }
chrono = { version = "0.4", features = ["serde"] }
```

```sh
cargo install rustio-admin-cli      # provides the `rustio-admin` binary
```


## Documentation

Full documentation index: [`docs/README.md`](./docs/README.md).

| Path                                       | Contents                                                       |
|--------------------------------------------|----------------------------------------------------------------|
| [`docs/`]./docs/                         | Guides, doctrine, architecture overview.                       |
| [`docs/design/`]./docs/design/           | Long-form design contracts — one file per security-sensitive subsystem. |
| [`docs/public-api.md`]./docs/public-api.md | Enumerated public API surface (generated; descriptive, not normative). |
| [`docs/archive/`]./docs/archive/         | Historical and superseded planning material.                   |


## Reading paths

Where to start depends on the work.

**New to the framework**
→ 30-second example above
→ [`docs/getting-started.md`](./docs/getting-started.md)
→ [`DESIGN_SYSTEM.md`](./docs/design/DESIGN_SYSTEM.md)

**Working on authentication or recovery**
→ [`DESIGN_RECOVERY.md`](./docs/design/DESIGN_RECOVERY.md)
→ [`DESIGN_R2_ORGANISATIONAL.md`](./docs/design/DESIGN_R2_ORGANISATIONAL.md)

**Auditing authority boundaries**
→ [`DESIGN_AUDIT.md`](./docs/design/DESIGN_AUDIT.md)
→ [`DESIGN_SESSIONS.md`](./docs/design/DESIGN_SESSIONS.md)

**Building on the published crate**
→ Install above
→ [`docs/modeladmin.md`](./docs/modeladmin.md)
→ [`examples/clinic/`](./examples/clinic/) — multi-crate reference project
→ [`examples/shop/`](./examples/shop/) — single-crate e-commerce admin, also a
  standalone project: **[abdulwahed-sweden/shop](https://github.com/abdulwahed-sweden/shop)**
  ([`v0.1.0`](https://github.com/abdulwahed-sweden/shop/releases/tag/v0.1.0), on rustio-admin 0.27.6)

**Understanding scope and design history**
→ [`docs/architecture.md`](./docs/architecture.md)
→ [`STRATEGIC_RESET_PLAN.md`](./docs/archive/STRATEGIC_RESET_PLAN.md)
→ [`CHANGELOG.md`](./CHANGELOG.md)


## Doctrine documents

Security-sensitive behaviour is governed by explicit contract
documents reviewed alongside the code.

### [`DESIGN_SYSTEM.md`]./docs/design/DESIGN_SYSTEM.md

Visual, token, and branding contract.

### [`DESIGN_SESSIONS.md`]./docs/design/DESIGN_SESSIONS.md

Session lifecycle, trust escalation, and Doctrine 22 — the
single-writer invariant on `revoked_at`.

### [`DESIGN_AUDIT.md`]./docs/design/DESIGN_AUDIT.md

Typed audit events, correlation-id chains, and the required
middleware ordering.

### [`DESIGN_RECOVERY.md`]./docs/design/DESIGN_RECOVERY.md

Self-service password recovery (R1, ships in 0.5.0).

### [`DESIGN_R2_ORGANISATIONAL.md`]./docs/design/DESIGN_R2_ORGANISATIONAL.md

Admin-driven recovery, auto-throttle, re-auth wall (R2,
ships in 0.6.0).

### [`DESIGN_AI_ASSISTANT.md`]./docs/design/DESIGN_AI_ASSISTANT.md

Permissions, approval, and audit layer over external AI coding
assistants — the `rustio ai` policy, proposal lifecycle, and opt-in
audit mirroring (ships in 0.23.0).

### [`DESIGN_CLOUD.md`]./docs/design/DESIGN_CLOUD.md

Project memory — the non-authoritative *why-layer* (`rustio memory` /
CLOUD.md). What it may never become, and the invariants that keep it
subordinate to code: subordinate, append-only, human-ratified (ships in
0.27.0). Implementation design: [`DESIGN_CLOUD_IMPL.md`](./docs/design/DESIGN_CLOUD_IMPL.md).

---

Each document is the source of truth for its surface.


## Workspace layout

Four crates ship together. The split keeps proc-macros, the
theme engine, and CLI compilation off the project's hot path.

| Crate | Purpose |
|---|---|
| `rustio-admin`        | The library. Re-exports the macros. |
| `rustio-admin-macros` | Proc-macros (re-exported from `rustio-admin`). |
| `rustio-admin-cli`    | The `rustio-admin` binary — `new` (friendly alias for `startproject`), `startproject`, `startapp`, `migrate`, `user`, `group`, `perm`, `theme`, `ai` (AI assistant permissions), `memory` (project memory / CLOUD.md), `doctor`, `docs`, `builder new`. |
| `rio-theme`           | Build-time theme engine. Turns raw brand colors into a WCAG-safe `tokens.css`. Not depended on by `rustio-admin` at runtime. |

```sh
cargo build --workspace
cargo test  --workspace
```


## Non-goals

RustIO is intentionally narrow in scope.

- Not a general-purpose web framework.
- Not an ORM. The `Model` trait is a thin sqlx shim.
- Not a content management system.
- Not AI-augmented — the framework embeds no model or planner. (`rustio ai`
  *governs* an external AI assistant via a permissions / approval / audit
  layer; it does not call out to one.)
- Not multi-database. Postgres only, by design.
- Not schema-contract-driven.


## CLI

See [`docs/cli.md`](docs/cli.md) for the full command reference.


## Naming — what about `rustio`?

There's a separate project at **[`rustio`](https://github.com/abdulwahed-sweden/rustio)** — a strict-by-construction system builder with SQLite, a guided schema-evolution wizard (`rustio evolve`), and an admin UI. Through `rustio-admin`'s v0.21.x line, this project also shipped a CLI binary called `rustio`, which meant `cargo install rustio-admin-cli` and `cargo install rustio-cli` silently overwrote each other in `~/.cargo/bin`.

As of v0.22.0 the binary published by this project is named **`rustio-admin`**, so the two no longer collide. You can install both on the same machine; `rustio-admin` always means this project, `rustio` always means the other.

The two are different in scope — this project (`rustio-admin`) targets Postgres-only admin panels with a narrow, doctrine-governed surface; the sibling project layers an admin UI, an ORM, and a guided schema-evolution wizard over a strict typed core with SQLite. Same name prefix, different goals.

**Install target.** The crate to install is **`rustio-admin-cli`** (`cargo install rustio-admin-cli`), which provides the **`rustio-admin`** binary. Do **not** `cargo install rustio` — that crate name is unrelated and is not this project.

For how the active `rustio-admin` line relates to the earlier `rustio-core` line, the separate `rustio-draft` companion, and the reserved `rustio-pro-*` crates, see [`docs/project-status.md`](./docs/project-status.md) and [`docs/versioning.md`](./docs/versioning.md). Release steps live in [`RELEASING.md`](./RELEASING.md).


## License

MIT — see [`LICENSE`](./LICENSE).


## Sponsor RustIO

> Build systems quickly.
> Evolve them safely.
> Stay in control.

RustIO is developed and maintained independently — no company, investors, or
outside funding behind it. Sponsorship is early backing for open Rust
infrastructure, not a personal donation. It funds the open-source work and keeps
the core free and inspectable.

**What sponsorship funds**

- Documentation, guides, and onboarding.
- Realistic examples and reference verticals.
- Testing, review, and long-term maintenance of the security-sensitive
  authority, session, and audit surfaces.
- Schema-driven admin generation and developer experience.

**Who it's for.** Rust developers, technical teams, and small companies building
internal tools, admin panels, and workflow/dispatch software who want a safe,
PostgreSQL-first foundation instead of an expensive SaaS stack.

RustIO stays free and MIT-licensed regardless of sponsorship. A separate,
open-core commercial layer (the `rustio-pro` line — hosted option, vertical
packs, support) funds sustained work without gating the core; see
[`docs/commercial-model.md`](./docs/commercial-model.md).

→ **[Sponsor on GitHub](https://github.com/sponsors/abdulwahed-sweden)** · tiers
in [`SPONSORS.md`](./SPONSORS.md) · details in
[`docs/sponsorship.md`](./docs/sponsorship.md).