Skip to content

2026-05-10: The Front Door

The front door — a monumental stone archway opening on an ornate wooden door at dusk; a teal-tinted tunnel of light arcs over the keystone, exactly the right size for one wiki migration.

For fourteen months, sanctum.haus was a private street address.

It resolved to a wiki behind a Cloudflare Access gate — a Mac Mini in Québec, answering only to the one login that belonged there. Type the URL from anywhere else and the front door simply refused to open. Today that changes. sanctum.haus becomes a public storefront for the prepper-tech parent who already runs Tailscale, Plex Pass, and a Pi-hole and is wondering when AI will get the same treatment. The technical documentation you are reading stays at sanctum.run. The split is deliberate, and the migration that pulled it off had exactly one hard requirement: open the door to strangers without leaving the wiki open behind it. This is how that went.

For a year sanctum.haus served exactly one thing — an internal wiki, gated behind Cloudflare Access, tunneled from that same Mini through a Cloudflare Tunnel. One reader, one login, one hostname. Today it becomes a storefront that expects to never recognize anyone.

The split:

sanctum.haussanctum.run
AudiencePrepper-tech parents, podcast listeners, future Family Pass buyersDevelopers, contributors, ops people, anyone reading this chapter
VoiceWarm, narrative, slightly literaryTechnical, doctrine-driven
PurposeFunnel — email capture → demo video → lifetime-pass purchaseDocumentation, runbooks, architecture
Energy”What it feels like to have a Sanctum""What Sanctum is

The handoff is the whole idea: someone clicks “Install” on .haus, lands on .run. Marketing-to-engineering as a domain transition. Calm prepper-parents shopping the storefront don’t want mTLS in the hero. The Hacker News engineers reading the architecture don’t want a founder story above the fold. Two doors. Right cost.

The new site was the easy half — an Astro scaffold and twenty minutes of copy. The hard half was getting sanctum.haus to serve marketing without breaking the wiki that had been answering at that hostname for a year. A hostname can only point one place at a time, and the wiki was still using it.

Initial state:

sanctum.haus → CNAME → <MINI> cfargotunnel
→ http://localhost:3100 (Outline wiki)
← Cloudflare Access gate (Bert only)

Target state:

sanctum.haus → CNAME → sanctum-haus.pages.dev (marketing site, public)
www.sanctum.haus → CNAME → sanctum-haus.pages.dev (marketing site, public)
wiki.sanctum.haus → CNAME → <MINI> cfargotunnel
→ http://localhost:3100 (Outline wiki, unchanged)
← Cloudflare Access gate (Bert only, unchanged)

The plan, after the council reviewed it:

  1. Read the existing tunnel ingress config, find the wiki service.
  2. Add a new ingress rule wiki.sanctum.haus → same localhost:3100. Keep the existing sanctum.haus rule alongside, so the wiki keeps responding through the cutover.
  3. Create DNS wiki.sanctum.haus CNAME → cfargotunnel (proxied).
  4. Verify https://wiki.sanctum.haus returns 200 with the Outline <title>.
  5. Mint a narrowly-scoped Cloudflare API token (Pages.Write only, no broader permissions), set it as a GitHub Actions secret on the new repo.
  6. Push to main; the Pages workflow deploys to sanctum-haus.pages.dev.
  7. Verify the staging URL serves the marketing site.
  8. Flip the apex CNAME from cfargotunnel → sanctum-haus.pages.dev.
  9. Verify https://sanctum.haus serves the marketing site, https://wiki.sanctum.haus still serves the wiki gated.
  10. Remove the now-stale sanctum.haus ingress rule from the tunnel for cleanup.

Steps 1 through 7 went exactly as planned. Step 8 produced a 302 redirect to a Cloudflare Access login — a stranger typing the URL was being asked for credentials that only one person on earth has.

The Access app remembered what it was guarding

Section titled “The Access app remembered what it was guarding”

The Cloudflare Access app named “Sanctum Wiki” was attached to hostname sanctum.haus, not to the tunnel itself. When the apex DNS flipped, the hostname-to-Access-app binding stayed exactly where it was — guarding a door that now led somewhere else. The marketing-site request from a stranger was hitting the Access challenge built to let Bert into the wiki. The guard was still at his post; the building behind him had changed.

The fix was to delete the app, then recreate it on wiki.sanctum.haus (the API token had DELETE+POST permission on Access apps but not PATCH — different scopes, same outcome). The new app carries a single explicit “allow” policy: emails matching neo@<HOST> or neo@<HOST>. The wiki is gated again, the marketing site is public, and the guard now stands in front of the right building.

No DNS touched production before the four-agent council read the plan. This is what a review is for — the machine doesn’t know the difference between a clever migration and a confident one until someone in the room asks.

  • Yoda (decision/strategy): “The path is clear, yet the leap from tunnel to pages must be timed with the rhythm of the DNS, not rushed by haste.”
  • Qui-Gon (infrastructure/perf): “Ensure your DNS TTL is lowered to 60 seconds prior to step 7 to prevent stale cache errors during the flip.” (Already addressed: the apex CNAME is proxied: true, so TTL is Cloudflare-managed at the edge — invalidation is seconds, not minutes.)
  • Windu (security/risk): “The API token grants full account access; restrict it to the specific zone ID and use a GitHub secret with no broader permissions.” (Applied: minted a new token scoped only to Pages.Write on the account, with no Zone or Access permissions.)
  • Cilghal (quality/discipline): “Implement a Staging environment first to validate the Pages deploy and ingress rules before touching the production apex record.” (Applied: sanctum-haus.pages.dev was the staging URL; the apex flip happened only after the staging URL probed clean.)

Verdict: approved. Two of the four amendments — Cilghal’s staging gate and Windu’s scoped token — turned into pre-flight steps that caught the Access-app snag half a step before it would have been visible from the public internet. That’s the council doing what councils are for: falsifying the plan before the plan meets a stranger.

Behind the door, for now, is a coming-soon page: two email-capture forms, pricing tiers (Sanctum Core free / Family Pass $129 lifetime / Cloud Sync $5 optional), and a founder note. The form posts to /api/notify-me which is intentionally absent — the form gracefully falls back to a mailto: to [email protected] so early founder-list traffic still reaches a human while the email backend gets wired (Buttondown is the leading candidate; Cloudflare KV is the cheaper one).

The marketing site is built with vanilla Astro, deployed through GitHub Actions to Cloudflare Pages on every push to main, lives in a private repo (Ogilthorp3/sanctum-haus). The license model is FSL-1.1-MIT for application code (cathedral, council orchestration, family agents — auto-converts to MIT after two years) and Apache-2.0 for libraries (sanctum-mlx-fast and any future helpers — embed-anywhere). The marketing site itself isn’t open-sourced; it’s brand and copy.

Three concrete things, in order:

  • Hero illustration. The current site has copy and structure but no image. The visual-language doc in the marketing repo specifies pencil-sketch with selective teal accents, three modes (haus / council / threshold). Either commission this or generate it through the existing pipeline; the rest of the launch waits on it.
  • Demo video. Seventy-five seconds. Mac Mini hero shot, council-in-action, the unplug moment (“now the cloud is gone”), pricing close. Script is already in-tree at marketing/demo-video-v1.md. Highest-leverage thing a solo dev can produce; rough-cut on QuickTime + iPhone Mirroring + a $20 ElevenLabs trial gets you eighty percent of the way there.
  • Email backend. Wire /api/notify-me to whichever email provider survives the founder-beta dilution. Until then the mailto fallback handles the first ~50 signups by hand.

The door is built, hung, and unlocked. What’s still missing is the reason to walk through it — and that, unlike a DNS flip, no council can approve in an afternoon.

  • The Clean Stage — same doctrine, different surface: the durable fix is structural, not cosmetic. The two-domain split is the marketing equivalent.
  • Borders and Edges — Cloudflare Access topology and tag-based ACLs, where the security model lives.
  • Council Always-Alive — the council whose review approved this migration.