LORE RBAC & Airlock Auth Flow
lore intermediate 6 min read
ELI5
LORE has three types of visitors: admins (who see everything across all organisations), operators (who see everything for their own organisation), and viewers (who can only read). The door guard is a shared system called Airlock that checks everyone’s badge before they enter, using a cookie that works across all devarno websites.
Technical Deep Dive
Role Hierarchy
| Role | Scope | Capabilities |
|---|---|---|
| admin | All orgs | Full read across all orgs. Can see all decisions, all agents, all analytics |
| operator | Single org | Full read within own org. Sees decisions, agents, analytics scoped to their org |
| viewer | Read-only | Read-only access to public/org-scoped content. Cannot access admin features |
Roles are derived from Airlock’s RBAC system — LORE itself has no local role store. The middleware extracts the airlock session, maps the user’s org memberships and global role flags, and emits x-lore-user-* headers.
Auth Flow
1. Browser requests lore.devarno.cloud2. LORE middleware reads .devarno.cloud session cookie3. Middleware calls airlock.devarno.cloud/api/auth/session4. Airlock validates cookie, returns user + orgs + roles5. Middleware computes LoreRole from airlock claims6. Middleware emits x-lore-user-id, x-lore-user-role, x-lore-user-orgs headers7. Page/API route reads headers to enforce RBACAirlock Integration (Pattern A — Same-Apex SSO)
LORE uses the canonical Pattern A integration from the airlock runbook:
- 3 files needed:
middleware.ts,lib/auth.ts,lib/airlock-client.ts - ~40 lines of middleware total
- Zero OIDC client registration needed — cookie is scoped to
.devarno.cloudso all same-apex subdomains inherit it clientSlug: "lore"registered in airlock’strustedOrigins
Role Computation
// Simplified from lore/src/lib/auth.tsfunction computeLoreRole(airlockSession): LoreRole { if (airlockSession.user.roles.includes("admin")) return "admin" if (airlockSession.user.roles.includes("operator")) return "operator" return "viewer"}Security Properties
- HttpOnly session cookies (no JS access)
- Secure (HTTPS only)
- SameSite=Lax (protects against CSRF while allowing top-level navigation)
- Cross-subdomain scope (
.devarno.clouddomain) - No local auth state — LORE is fully stateless; session validation is always live
Key Terms
- Pattern A → Same-apex SSO:
.devarno.cloudcookie inherited by all subdomains, zero OIDC registration - clientSlug → Short name registered in airlock’s
trustedOrigins—"lore"for LORE - LoreRole → Computed from airlock user roles:
"admin" | "operator" | "viewer" - x-lore-user-* → Custom headers emitted by middleware containing user ID, role, and org memberships
- RBAC → Role-Based Access Control — enforced at both middleware (session gate) and page (role gate) layers
Q&A
Q: Does LORE store its own users table? A: No. All user/role/org data lives in airlock. LORE is fully stateless and derives roles from the session.
Q: How does the middleware forward cookies to airlock?
A: It reads the incoming Cookie header, extracts the session cookie, and forwards it in the Cookie header of the airlock validation request.
Q: What happens if airlock is down? A: The middleware cannot validate the session → all requests return a redirect to the login page or a 502 with DegradedBanner (outage).
Examples
LORE’s auth is like a music festival with a central wristband check — you get your wristband once at the entrance (airlock), and every tent (LORE, CAIRNET, hubble, hatch) just checks the wristband colour to know what access you have.
neighbors on the map
- CAIRNET Agent Identity & Sybil Mitigation implementing agent authentication in CAIRNET