Flagship

Docs.

Concrete answers, no fluff. Pick a starting point.

Quick start

Three steps. About ten minutes.

1. Install the phone app. Pick a username. Approve biometrics. Your master key never leaves the phone.

2. Get Flagship Studio on your computer. In the phone app, choose Add server → Pair with Studio and scan the QR Studio shows. Studio receives the signed recipe and writes the boot USB for you. Plug in and boot. When the server asks to be approved, check that the six-digit code on its screen matches the one in the app.

3. Vibe-code your first app from the phone. Done.

Architecture

Three planes. flagshipserver.com handles identity. flagship.services is a stateless pipe (SNI passthrough + tunnel hub). Your box terminates TLS itself with a real Let's Encrypt cert. We literally cannot read your data.

The phone holds your keys. The .com Worker is the registrar; it never sees plaintext content. The .services Fly app is a dumb router that sees encrypted bytes only.

How Flagship works

Five stages, start to finish. Your phone signs every step — we never see your content, even when you're registering for the first time.

1 · Pair your phone. You install the Flagship app. It generates a master key and wraps it with a key held in your phone's secure hardware (the Secure Enclave on iPhone, the hardware-backed Keystore on Android), unlocked with Face ID, Touch ID or your fingerprint. The master key never leaves the phone. From it we derive three more: one for identity (your username), one for backup-authorization (LUKS unlock), one for working keys (per-server secrets). You pick a username; the phone signs a registration request; flagshipserver.com records the username and the public half. No email, no password, no SMS.

2 · Mint & deliver a recipe. Your phone pairs directly with Flagship Studio using the QR or short code Studio shows. After you confirm the matching security code, the phone mints and sends a small signed recipe naming your server and carrying a short, single-use expiry. Studio fetches the right base OS and writes the boot USB — you never pick or download an OS image yourself.

3 · Boot & install. The USB boots a hardened Linux base on your hardware. A first-boot script validates the recipe signature locally, then installs one Flagship release package for an exact version, after checking the maintainers' signature on it; no git checkout or package manager runs. It formats the disk with LUKS, generates a per-box identity, requests a real Let's Encrypt cert (DNS-01 wildcard), registers with flagshipserver.com, and boots into steady state. The first time it asks to be approved, your phone pins the server's own key: the server proves it was built from your recipe, and if it has a screen it shows a six-digit code that your phone shows too. Then your phone lights up: "Your Flagship is online."

4 · Every-boot unlock. When the box reboots, the LUKS-encrypted root won't open. The boot stage polls flagshipserver.com for an unsealed unlock key. Your phone, woken by a push, asks for biometrics, decrypts the sealed blob locally, and deposits the unsealed key with a 10-minute TTL. The box consumes it; the row is deleted on read; the disk opens. A stolen box without your phone is a brick — even we can't help, because we never had the unsealed key.

5 · Live. Vibe-code. Share. From the phone you describe a service in plain language. An LLM writes it (your own provider key, Flagship Inference's free credits, or a model you downloaded to your own server, which never sends anything out). The daemon builds the container, provisions a Postgres database and a files folder scoped to the service, deploys it, and registers a subdomain — live within a minute at app.you.flagship.services. Sharing is one tap: a signed invite or a username search. Services never see cookies; the daemon injects identity headers after a membership check.

If you lose the phone. Cloud recovery stores only an encrypted copy of your master key. On iOS, recovering it requires both your recovery passphrase and access to the iCloud Keychain holding your Flagship passkey; Flagship cannot read the key or reset your passphrase. Without cloud recovery, a single-device account must use the slower waiting-period claim process.

Install & first boot

The first-boot bootstrap is public in our open-source repo and pinned by hash inside the signed recipe. It installs the server software from one release package that Flagship's maintainers signed, checking the signature first. It formats the disk with LUKS, generates a server identity, requests a Let's Encrypt cert via DNS-01, and registers with .com. The server software runs as an ordinary user; its keys are held by a separate key service.

Every subsequent boot, the phone has to approve the LUKS unlock, unless you turned on Auto-unlock for that server. Without Auto-unlock, a stolen box without your phone is a brick. With it, revoke the server in the app: it gets no unlock key at its next start.

Assemble your server

Flagship Studio turns a spare computer into your personal server. You give it two things — your certificate (the signed recipe) and a USB drive — and it fetches the right hardened Linux base for you and bakes your recipe in. Here's what each piece is and how it works.

A certificate

The certificate is a small JSON file your phone signs. It names the server you're creating and proves the request came from you — the phone is the only thing that can authorize a new Flagship server, and it never leaves your pocket.

To get one, install Flagship Studio on your computer. Studio shows a QR and short code; scan or enter it from Add server in the phone app. After you confirm the matching security code, the app signs the server recipe and sends it directly to Studio. Webapp users can instead download the signed JSON recipe and open it in Studio.

It's single-use and short-lived. A certificate is good for a few hours and authorizes exactly one server, so a leftover file on disk can't be replayed. Generate a fresh one whenever you need it.

Get a certificate

A boot drive

The USB drive is a one-time installer, not the server itself. It carries your certificate, turns a spare machine into your Flagship server, and then it's done — you can wipe and reuse it.

Assemble the drive

Drop your certificate and a USB drive into the Builder and hit Assemble. It fetches the base OS for you and bakes your certificate inside the installer image, so the drive needs nothing from the network to know which server it's setting up.

The drive is erased — everything on it is overwritten. Use a spare one.

Boot the target machine

Plug the drive into the computer you want to become your server and turn it on, choosing the USB drive as the boot device. The installer runs unattended — partitions the disk, installs the base system, sets up the Flagship daemon. No keyboard babysitting.

Register, unattended

On first boot the new server generates its own identity, presents your signed certificate, and registers its subdomain. From this moment TLS terminates on your box — flagship.services becomes a dumb pipe that literally cannot read your content.

Reclaim the drive

Once the server is live, the boot drive has done its job. The certificate it carried is single-use and time-limited, so an old drive can't be replayed. Reformat the stick and use it for anything you like.

Phone pairing

Your keys live on your phone and your other devices. Everything else pairs to them with a QR code, and both screens show the same short code, so you can check you are pairing the screen in front of you. Every QR code is an ordinary https://flagshipserver.com/… link: scanned with the phone's camera it opens the Flagship app, and without the app it offers the store pages.

A browser on any computer (Remote). Open remote.flagshipserver.com; it shows a QR code at once. Scan it with the Flagship app, check the codes match, pick a server and approve with Face ID or your fingerprint. The phone mints a one-use ticket on that server and seals it so only that browser can read it; the browser redeems it on your server. The browser holds no keys: anything that needs your signature goes back to your phone to approve. Browser sessions are listed under Settings → Browser sessions; end one any time.

Another device on your account. On an admin device (one that holds your account's admin key), open Settings → Trusted devices → Add device. On the new phone, tablet or browser, choose Connect to an existing account and scan the code. The two meet through a relay on flagshipserver.com that passes sealed bytes along and can't read them; when the codes match, the key moves over. Only an admin device can add devices; on any other device the button is greyed out. Remove a device under Settings → Trusted devices.

Flagship Studio. Studio shows a QR code and a short code; the phone pairs with it the same way and sends it a signed recipe (see How Flagship works).

Apps & manifest

An app is a container your server builds from its source and a flagship.app.json manifest at the root of its repo. The manifest names the runtime the server builds it on, the data stores it needs (Postgres, a files folder), the internet hosts it may reach, and what anyone can open without signing in. The server injects identity headers, so apps never handle passwords.

You describe an app in a build chat (the AI writes the source and the manifest, never a Dockerfile) or import a git repo. Either way your server builds it, runs it in its own sandbox, and routes it.

Manifest reference

The fields, all checked when the app is installed:

  • schema_version: 1, or 2 for the fields new in 0.3 (below). name: a DNS label (lowercase letters, digits and dashes). version: semver, like 1.2.0. description: optional.
  • runtime: base is node-24, python-3.13 or static, plus port (the app listens on $PORT), start (the start command as a list; node-24 defaults to npm start) and env. Keys starting with FLAGSHIP_ are the server's. An imported repo with its own Dockerfile names an image instead of a base.
  • data.stores: postgres: true gives the app a Postgres 18 database (FLAGSHIP_PG_URL, with pgvector and the common extensions); files: true gives it a writable folder at /data (FLAGSHIP_FILES_DIR) that survives restarts and redeploys. There is no S3 and no Redis.
  • network: subdomain, served at <subdomain>.<server>.<you>.flagship.services, and egress, the hosts the app asks to reach, each with why. Nothing goes out until you approve it in the app's access list.
  • access: enabled: true (apps can't opt out of identity), default_role, optional custom_roles, public_routes (paths anyone can open when the app is members-only) and queryable_by.
  • migration.verification: standard (biometric) or elevated (biometric and a second factor), for apps holding money, health or password data.
  • Optional: browser.domains, the sites an app may drive in your server's own browser, approved at install.
  • Schema 2 only: runtime.kind wasi for a WebAssembly app; components, up to eight parts of one app that start in order; localAi, to use the model on your own server; accelerator, to ask for a graphics card, which waits for the owner's approval. The details are in docs/manifest.md, docs/wasi-apps.md and docs/app-groups.md in the repo.
{
  "schema_version": 1,
  "name": "habits",
  "version": "0.1.0",
  "description": "Daily habit tracker.",
  "runtime": { "base": "node-24", "port": 8080, "start": ["node", "server.js"] },
  "data": { "stores": { "postgres": true } },
  "network": { "subdomain": "habits" },
  "access": { "enabled": true, "default_role": "member" },
  "migration": { "verification": "standard" }
}

URL multiplexing

When you have one install of game, the URL game.john.flagship.services just works. When you have two installs of game on different boxes, that short URL is ambiguous and we serve a disambiguation page. The full long form (game.home.john.flagship.services) always works.

You declare and release short-URL aliases from the phone. Full design →

Recovery

Your account key lives on your devices. There are three ways to get it onto a new one, and if you have none of them your data can't be recovered, like a hardware wallet. The apps say so while you set up.

  • Another of your devices. On a device that's signed in, open Settings → Trusted devices → Add device. On the new one, choose Connect to an existing account and scan the code under Join with a pairing code, or paste its link (or Settings → Scan a pairing code when it's already signed in elsewhere). Both show the same code; when they match, the key moves over, end to end encrypted.
  • A cloud backup. If you turned on recovery, a passkey kept by iCloud Keychain or Google Password Manager unlocks a sealed copy of your key. On a new phone, sign in with your account name and confirm with Face ID or your fingerprint.
  • Your account key file. Settings → Back up account key saves a passphrase-protected .flagshipkey file. Open it on the new device with its passphrase.

Recovering without a working device is a takeover, so it needs a recovery credential and then waits so a thief can't rush it: 3 days on an account with one device, 24 hours on an account with several, which also needs your authenticator code or a recovery code. Your other devices are told at once. Only the device that started the recovery can cancel it. Afterwards each server pairs with the new device.

API reference

What an app on your server can count on:

  • Who is calling. The server drops every X-Flagship-* header a client sends and sets its own: X-Flagship-Visitor is member, api or anonymous; for a member, X-Flagship-User is an id that is stable for this app only (the same person has unrelated ids in two apps) and X-Flagship-Role is their rank, member, manager or master. Anonymous visitors get no user or role.
  • Sign-in. Send people to /__flagship/sign-in?next=/path on the app's own host (and /__flagship/sign-out). They approve on their phone; the app never sees a password.
  • API keys. Scripts and devices call the app with Authorization: Bearer fsk_<keyId>_<secret>, a key the owner creates on the app's page, read-only or read and write. The server checks it first and the app sees X-Flagship-Visitor: api and X-Flagship-Api-Scope.
  • Live connections. Responses stream, and WebSocket upgrades pass through.
  • Data. FLAGSHIP_PG_URL for its Postgres database and FLAGSHIP_FILES_DIR for its files folder.

Everything else, between your devices, your servers and flagshipserver.com, is signed orders rather than a public API. The specs are in the open source repo: github.com/ibisllc/flagship, starting with docs/app-apis.md and docs/manifest.md.