ROADMAP: done items moved out of "Next" (codegen rewrite, SSR bridge, edge manifest, X-Mizan-Invalidate, return-type branching, affects_params, kernel extraction, two-stage codegen, mizan-ts). Real "Next" in: framework-adapter wrapper layer (MizanContext + useMizan + DjangoError on top of the kernel) for React/Vue/Svelte; A1–A4 from ISSUES.md. CLAUDE: 4-package layout replaced with the actual 7-package layered architecture (backend protocol adapters + frontend kernel + framework adapters + SSR worker). "STALE codegen" section rewritten to describe what's emitted vs. the wrapper layer that isn't yet. docs/ now tracked (6 files). AFI_ARCHITECTURE rewritten — replaced the speculative `mizan-ast`/`mizan-csr`/`mizan-rpc`/`mizan-schema` package names with the real layout, dropped KDL-schema language for the actual schema-export format. The other 5 docs/ files were already current and are tracked as-is. ARCHITECTURE-REWORK.md deleted — same expert review is re-tracked in the fresher ISSUES.md, two parallel trackers was sediment. README.md deleted — drift was beyond surgical fixes (`mizan_clients.py` convention, `<DjangoContext>` provider, removed `@compose` and `context='local'`, wrong codegen output filenames, 3-package structure vs. 7). Rewrite waits for the wrapper-layer codegen to land so user-facing examples reflect reality. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1.9 KiB
1.9 KiB
MWT — Mizan Web Token
Decided 2026-04-06.
MWT is a standard JWT (RFC 7519, HMAC-SHA256) with Mizan-specific
claims, traveling on the X-Mizan-Token header. It is the
protocol's identity layer for cache keying and permission staleness
detection.
Claims
| Claim | Purpose |
|---|---|
sub |
User ID — goes into HMAC cache key derivation |
pkey |
Deterministic hash of user's permission state at issuance |
exp |
Configurable short TTL — controls permission staleness window (Django setting) |
iat |
Issued at |
kid |
Key ID — for secret rotation |
aud |
Audience binding — prevents cross-tenant replay |
Key decisions
- Standard JWT envelope, not proprietary. Uses standard libraries for signing and validation.
X-Mizan-Tokenheader, notAuthorization: Bearer. Avoids collision with DRF, allauth, and existing JWT systems. Cloudflare WAF/Access do not inspect custom headers.- Replaces
JWTUser+_try_jwt_authentirely. Old approach is deleted. - App handles authentication (session, social, etc.). Mizan issues MWT from the authenticated identity.
- Edge Worker validates MWT, extracts
subfor HMAC cache key, checksexp. pkeycomputation must be deterministic:sorted(user.get_all_permissions())then hash.- Client-side: proactive refresh before expiry. Check TTL before dispatch, not reactively after a 401.
- Header-based, not cookie-based. A cookie would force
Vary: Cookie, destroying PSR cache.
HMAC canonical form
JSON with sorted keys:
HMAC(secret, JSON.stringify({"c": context, "p": sorted_params, "u": user_id}))
What this solves
- DRF token collision
JWTUser-too-thin problem- Permission staleness race condition
- Single validation path across Python and TypeScript Edge
Usage rule
All cache-layer auth code uses MWT, not Django session or raw JWT.
The @client(auth=...) parameter gates on MWT validity.