Fabric Quickstart
Goal: from "what is this?" to "I have a credential in the vault" in under 5 minutes.
You need:
- The shared invite password (mode 0600 at
~/.optimalos/transfers/.fabric-invite-passwordon the Pi). - A modern browser with WebAuthn support. iPad Safari and desktop Chromium both work.
- A printer or pen and paper for the BIP39 recovery phrase. Don't skip this.
Wrong origin?
If you're on optimal.miami, the vault flow doesn't apply — that's the legacy backup (Pi). Vault routes return 410 GONE there by design. Visit https://fabric.optimal.miami/ for the full Fabric ceremony. See Deployment modes for why the same bundle behaves differently on each origin.
1. Sign in
Open https://fabric.optimal.miami/ and sign in with the invite password.
You should see the home dashboard. If you get a 502 from Cloudflare, the tunnel or optimalos.service on Hetzner is down — see Runbook → Common breakages.
2. Walk vault setup
Navigate to https://fabric.optimal.miami/vault/setup. Four-step wizard, ~3 seconds total on a recent device (Argon2id is the heavy hitter; this is intentional).
- Passphrase — 8+ chars. This derives your
ageidentity via Argon2id. - Passkey — WebAuthn registration. A canary blob is written so the next unlock can detect a non-deterministic authenticator and refuse instead of corrupting state.
- Recovery phrase — 24 BIP39 words displayed once. Print it or write it down now. It is not stored anywhere in plaintext after this screen.
- Challenge — re-enter 4 random words from the phrase. Confirms you actually wrote it down.
If step 4 fails with "no session token; sign in first", you skipped step 1 above. Go back to / and sign in. (UX bug tracked at kanban f9abbb18.)
After successful enrollment, vault_recipients gets two rows (kind=browser + kind=recovery) and you land on / — the OptimalOS Home tab. Your tmux sessions, kanban, loom are right there. The vault dashboard is reachable from a ← OptimalOS button at the top of /vault/dashboard if you visit directly. (Post-ceremony redirect changed 2026-05-05; previously dropped you on /vault/dashboard.)
3. Add your first credential
On the dashboard, click Add Entry. The drawer opens with four fields:
- Name — e.g.
ANTHROPIC_API_KEY - Kind —
api-key,password,token,note - Value — the secret itself
- Metadata (optional JSON) — e.g.
{"rotates":"90d"}
Hit Save. The browser encrypts client-side via age to all active recipients, computes recipients_hash, and POSTs ciphertext only. The server never sees plaintext.
Devtools → Network: you should see POST /api/vault/entries returning 201. If it returns 401, your session expired — re-sign in. If it returns 500, check the Hetzner journal for JWT_SIGNING_KEY issues (see Runbook).
4. Confirm from the Pi
CLI parity exists — same code path, same ciphertext shape:
# Grab the session token from devtools → Application → Cookies → fabric_session
export OPTIMAL_FABRIC_TOKEN='<paste here>'
optimal vault list
# Should show your entry with name, kind, created_at, recipients_hash
optimal vault recipients
# Should show 2 active rows: browser + recoveryIf optimal vault list returns 401 unauthorized, your token is wrong or expired. Re-grab from devtools.
You're done. Total time: ~5 minutes if your printer cooperates.
What's next
- Pair the Pi as a Fabric device so sessions can route there. Tracked at kanban
8f84c30e. Theoptimal pairCLI exists (commitsc132faf,61b296d); the ceremony hasn't been walked end-to-end yet. Today six recipients are active (iPad / MacBook Air M1 / Windows Chrome × browser+recovery), nodevicerow. - Start a Claude session via the Sessions tab (Phase 14-1 thin slice, shipped 2026-05-04 as commit
85d8226). Needs the Pi paired + anANTHROPIC_API_KEYvault entry. - Read the Architecture if you want to understand how the cloud, devices, and vault talk to each other.
- Read the Deployment modes if you want to know why
optimal.miamiandfabric.optimal.miamilook different despite running the same bundle. - Read the Threat model if you're going to handle anything sensitive — 5 P0s are cleared, 7 of 8 P1s are now closed (2026-05-05).
Where to look when something breaks
| Symptom | First place to look |
|---|---|
| 502 from Cloudflare | Hetzner optimalos.service or cloudflared.service — Runbook → Common breakages |
setup-init 500 | JWT_SIGNING_KEY empty — Runbook → JWT_SIGNING_KEY empty |
| Step 4 of vault setup fails with "no session token" | Sign in at / first — known UX bug f9abbb18 |
Add Entry drawer 401 | Session expired; re-sign in |
Add Entry drawer 500 | Check Hetzner journal: journalctl -u optimalos --since "5 min ago" |
| Recovery phrase lost | There is no recovery from this. The vault is unrecoverable for that recipient. Add a second recipient (paired device) before you forget. |