Airlock × External Apex
The Pitch
Until today, airlock’s promise (“one identity, every devarno product”) had a quiet asterisk: as long as every product lives on a*.devarno.cloud subdomain. That constraint mattered — it ruled out branded consumer apps, domain-specific launches, and acquisitions.
As of 2026-04-20, airlock mints short-lived Ed25519 JWTs scoped to any registered external apex. stratt.dev is live as the first consumer: sign in once at airlock, land at stratt.dev with a signed session, never reach a login form on the stratt domain.
The wiring cost for the next external apex is ~10 minutes: one row in HATCH’s handoff_consumers table, three env vars on the consumer’s host, and a copy of the 200-line reference implementation from apps/meridian.
Why this matters
- Brand independence without auth sprawl. Ship a product on its own domain (
stratt.dev,example.com, anything an acquisition brings) without rebuilding auth, without syncing user tables, without per-product login UIs. - One consent surface. The user’s account, their connected identities (GitHub, etc.), their 2FA — all stay in airlock. New external apps inherit it transparently.
- Security by asymmetric signatures. The consumer verifies handoffs against airlock’s published JWKS (
GET /api/auth/jwks). No shared secret between airlock and the consumer. No secret to rotate when onboarding a new apex. No secret to leak from a consumer breach. - A clear wall between metadata and gating. CASA’s App Registry catalogs apps for the launcher; HATCH’s
handoff_consumersgates which apexes airlock will sign for. One is UX, one is security. Both are operator self-service.
What shipped today
| Capability | Where |
|---|---|
| Ed25519 handoff JWTs with 60s TTL | airlock/src/routes/handoff.ts |
| DB-backed consumer allowlist with 30s cache + env fallback | handoff_consumers table, HATCH /consumers UI |
Signing-failure 302 back with ?error=signing_failed | Consumer renders friendly error on its own domain |
| Unencrypted JWK at rest | jwt({ jwks: { disablePrivateKeyEncryption: true } }) — keeps the public_key / private_key pair atomic |
| Reference consumer SDK | stratt-hq/stratt-run/apps/meridian/src/lib/airlock-handoff.ts |
What this unlocks
- stratt.dev productization. Meridian (stratt.dev) now has authenticated sessions. Paywall, per-user state, audit trails — all unblocked.
- Any future acquisition or spin-up on its own domain. We are no longer constrained to
*.devarno.cloudnaming for authenticated products. - MCP / agent integrations across domains. Agents authenticated against airlock can hand off to external apexes the same way humans do.
- Customer-facing brands without customer-facing auth. If a product needs to look like
my-brand.com, auth hides behindairlock.devarno.cloud— no compromise on identity consolidation.
Proof of value
Three bugs kept stratt.dev dark for an afternoon (atlas/findings/2026-04-20-stratt-dev-cross-apex-handoff-three-bug-chain.md). Every one of them is now:- Documented in a doctrine so the next apex doesn’t hit them.
- Caught by a diagnostic runbook (atlas/prompt-ops/2026-04-20-a2a-cross-apex-handoff-diagnose.md) in under 10 minutes.
- Fixed in the reference implementation so a verbatim copy into a new app works out-of-the-box.
What’s next
- File upstream to
better-authabout thejwtplugin’s encrypt-at-rest pair drift. The fix we shipped is defensive; ideally upstream either writes both columns atomically or defaults the encryption flag off. - Second external apex. Pattern validation needs N=2. Any candidate? A non-devarno-branded landing page for a single product would surface whatever’s still implicit in the reference implementation.
- Publish
@devarno/airlock-consumeronce a second external apex adopts the flow. Ship the 200-line SDK as a package so the next onboarding is a dependency install, not a file copy. - Improve consumer error copy. Today’s “usually because it expired” is actively misleading for three distinct failure modes. Either consumer-specific copy per jose error code, or a
?diag=query param operators can toggle, would pay for itself the first time someone else debugs this flow.
Blast radius / risk
- Existing same-apex SSO (
hatch,hubble,pebble,manualon*.devarno.cloud) is untouched. This campaign is strictly additive. - One prod
DELETE FROM jwksinvalidated any long-lived airlock-signed tokens from before 14:18 today. No known holders; OIDC consumers re-signed transparently on next request. - Disabling JWK encryption at rest is a calculated trade-off: the DB volume encryption is the trust boundary, and BetterAuth’s encryption path produced silent pair drift that was strictly worse than plaintext.