Skip to content
flypod
Concepts

Tokens & ownership

Understand flypod account sessions, per-site manage tokens, claim tokens, and how each credential changes ownership and expiry.

A flypod site is either temporary (deployed without an account, expires in 14 days) or yours (attached to an account, no expiry). Three credentials move a site between those states: an account session proves who you are, a per-site manage token proves you may change one specific site, and a claim token converts one anonymous site into an owned one. The CLI stores and sends all three for you; you almost never handle one by hand.

How ownership works

There are two states and one action:

StateWhat it means
TemporaryAnonymous deploy. Live immediately, expires in 14 days.
YoursAttached to an account. No expiry, listed on your account page.
flypod ./dist     # → temporary
flypod login      # → everything you deployed on this machine becomes yours

That is the whole model. flypod login claims every anonymous site this machine remembers, not just the last one — so "deploy now, log in whenever" is a real workflow, not a hopeful one. You never have to learn what a token is, and the happy path never shows you one.

Then why do tokens exist?

With no account there is nothing else that can prove a site is yours, so each site gets a manage_token: possession is ownership. It's plumbing, not something you handle. flypod writes it to projects.json (mode 0600), keyed by the folder you deployed from — which is how update, rollback, and versions work with no arguments, and how flypod login proves ownership of every remembered site at once. In the normal case the token is created, used, and retired without you ever seeing it.

The server stores only its SHA-256 hash, so it can't be re-issued, rotated, or revoked. A leak is permanent until the site expires or is deleted. That is exactly why it isn't printed.

The one case where flypod does show you a token

Hiding a credential is only safe while the system is holding it for you. So:

If flypod cannot remember a site for you, it tells you, and it gives you the token. It never creates a site it can't get back to, silently.

If the config directory is read-only or ephemeral (a CI container, a locked-down FLYPOD_CONFIG_DIR), the registry write fails while the deploy still succeeds — the site is live and nobody is holding its credential. flypod warns loudly and prints the manage_token, and emits it on stderr even under -q. That is the one moment you genuinely need it.

Otherwise, flypod token reveals it on demand — for the rare case of acting on a site from a machine that doesn't remember it. Rarer than it sounds: if the site is yours, logging in on the second machine is the better path, because a session can be replaced and a manage_token cannot.

Credential map

CredentialScopeUsed for
Account session tokenOne accountOwned deploys, account site listing, and managing sites owned by that account. Created by the flypod login device flow.
manage_tokenOne siteReading metadata, adding versions, rolling back, and proving control during login auto-attach.
claim_tokenOne anonymous siteCross-machine fallback for attaching an anonymous site to an account.

Account session token

flypod login obtains a Better Auth session token after you approve a device in the browser. The CLI saves it outside the project and sends it as a bearer token. For stateless automation, FLYPOD_TOKEN can supply an existing session directly.

Treat this token like a password: it represents the whole account. The separate custom API-key system — and its key-creation subcommand — is retired; FLYPOD_API_KEY remains only as a legacy environment-variable fallback.

A note on prefixes, since the retired API keys used one too: fk_ is the current prefix for per-site capability tokens. Both manage_token and claim_token are 32 random bytes rendered as fk_<base64url>. Seeing fk_ tells you nothing about which credential you're holding, only that it's a site-scoped capability token rather than an account session.

manage_token

Every deploy returns a manage_token. It authorizes the version loop for that specific site: reading metadata, adding versions, rolling back. Anonymous CLI deploys store it in projects.json so flypod update and flypod rollback work without flags — you don't handle it.

A manage_token cannot delete a site. There is no delete route that accepts one; deletion is account-only, from the signed-in dashboard.

If you use the HTTP API or the library directly, the calculus flips — there is no registry holding the token for you, so you must save what the response returns. The CLI is the surface that saves it on your behalf.

claim_token

Anonymous deploys also return a claim_token, valid for exactly one route: POST /sites/:id/claim, behind flypod claim <site_id> <claim_token>. It's a cross-machine fallback, and it is not the recommended path — flypod login is. It can't re-point a site that already belongs to someone else: that route returns 409 if the site has a different owner.

Don't have agents or CI jobs stash a claim_token for later. Authenticate the job, or log in on the machine.

Anonymous vs owned

AnonymousOwned
Created byDeploy with no account sessionDeploy with a saved login or FLYPOD_TOKEN
Managed viamanage_tokenAccount session (or the manage_token, if one was stored before claiming)
Deleted viaNothing — it expiresAccount dashboard
Expiry14 daysNone
Search indexingnoindexIndexable

Claiming through the CLI — flypod login or flypod claim — also clears the 14-day expiry on the local folder link, so it doesn't quietly self-destruct on day 14 and leave your next flypod making a second site on a new URL. The browser flow can't reach local files, so a site claimed from the dashboard is permanent server-side while this machine's folder link still ages out; re-running flypod update from that folder after it lapses is the case to watch for.

On this page