Hi everyone!
I'm excited to share a project we've been working on at Castlecraft: Tenant Registry!
It's a standalone, auth-decoupled, policy-agnostic control plane built entirely on Framework M. If you are building multi-tenant SaaS applications, microservices, or polyglot data planes and struggling with authorization latency or central points of failure, this might be exactly what you need.
Repository: gitlab.com/castlecraft/tenant-registry
The Problem it Solves
In typical multi-tenant architectures, downstream services (Data Planes) constantly query a central authorization service to ask "Is User X allowed to do Y in Tenant Z?"
This creates a massive bottleneck:
- Latency: A network hop on every authorization check.
- Single Point of Failure: If the central auth service goes down, the entire platform halts.
- Fan-out Load: Difficult to scale as internal microservices multiply.
Our Solution: Disconnected Projection
The Tenant Registry solves this by never serving live authorization queries. Instead, it uses a pattern we call Disconnected Projection.
Whenever a commercial reality changes (e.g., a user joins a tenant, a subscription is upgraded, or roles change), the Registry cryptographically signs a CommercialFact using Ed25519 and projects it out to shared infrastructure.
It uses a composite fan-out architecture:
- Storage Layer (Postgres / ClickHouse): For durable, queryable boot-time snapshots.
- Signal Layer (NATS JetStream): For real-time, sub-50ms delta updates.
Your Data Planes (whether written in Go, Python, or Rust) simply read these facts, verify the Ed25519 signature locally, and hydrate their own local authorization engines (like SpiceDB or Cedar). Result: Zero-latency, fully decentralized authorization.
Key Features Built with Framework M
We leaned heavily into the power of Framework M to build this:
- Server-Driven UI (SDUI) Onboarding: A complete, multi-step onboarding saga (invitations, organization creation, bot-protection) entirely driven by the backend. Changing the onboarding flow requires zero frontend deployments.
- Zero-Trust Identity Linking: Strict identity locking for invitations, ensuring users can't accept invites meant for other emails, handled through custom OIDC callbacks.
- Plugin Architecture (Entry Points): Extending the registry is seamless. Using Python package entry points, you can inject custom Onboarding Steps or new Notification Dispatchers (like Twilio) just by installing an MX-package. No core code changes needed!
- Pluggable Anti-Bot Protection: Config-driven
VerificationPortwith built-in adapters for Cloudflare Turnstile, Altcha (Self-hosted Proof-of-Work), or NoOp (for dev/invite-only). - GitOps Ready: App configurations and role vocabularies are managed via
AppMetaDataYAML manifests.
Comprehensive Documentation
We just finished writing a massive documentation hub following the Diátaxis framework and arc42 architecture standards.
If you want to dive deep into how the architecture works, check out our newly minted docs folder in the repository, which includes 6 Architecture Decision Records (ADRs), full conceptual explanations, and step-by-step tutorials to get it running locally via Docker Compose!
I would really appreciate the Framework M community taking a look, try out the local setup tutorial, and give us your feedback. Whether you're interested in the Disconnected Projection pattern, or just want to see a complex real-world implementation of Framework M's SDUI capabilities, there's a lot to explore here.
Check it out here: https://gitlab.com/castlecraft/tenant-registry