Developers
Isolation & keys
How Frontpage fences sites, scopes API keys, and prevents cross-tenant access from the CLI.
Site targeting
Every site-scoped API call requires a subdomain slug (example: asimov-press).
The platform binds work to branch site/<slug>. Clients cannot pass a branch, ref, repo, or
clone URL.
- Accepted:
frontpage use asimov-press,--site asimov-press - Rejected:
asimov-press.frontpage.host,www.example.com, full URLs
API keys
- Minted in the editor (Developers). Prefix
fp_live_. - Stored hashed server-side; the secret is shown once.
- Account-wide: not limited to a single site. The key acts as the minting user on every site they can access.
- Bearer tokens cannot mint keys. Session owners who own at least one live site can mint.
Sharing a key shares that user’s power. There is no “editor-limited” key in v1. Rotate (delete) keys from the Developers panel if leaked.
Authorization outcomes
| Situation | HTTP | CLI exit |
|---|---|---|
| Missing / invalid key | 401 | 4 |
| Member but under-privileged for the action | 403 | 4 |
| Not a member of the site (existence hidden) | 404 | 4 |
| API feature disabled for the environment | 404 “not found” | 5 (message mentions PUBLIC_CLI_ENABLED) |
Important for agents: exit 4 on a 404 often means “no access / not found,” not only a bad password.
What is never returned
- GitHub tokens
- Clone / remote URLs
- Other tenants’ branches or file trees
- Module OAuth secrets and raw secret values (masks only)
What this fence applies to
Every site-scoped v1 route runs the same authorize step: Bearer key → user id → membership on
that subdomain → then the handler. The handler always uses the server’s
claim.siteId. Clients cannot pass a site UUID, a branch name, or another tenant’s
person / lead / file id and reach a different graph.
- File sync:
push/pull/ls/catonly see the allowlisted tree for the claimed site. - People CRM: list, add, hide, notes, and follow-up are
(site_id, person_id). A person UUID from site B used with--siteof site A is 404. Same email on two sites is two people. - Store: items and stock are
(site_id, item_id). The samecamp-haton two sites is two rows. A foreign item id is 404. See Store. - Inbox, SEO, redirects, articles, media, modules, settings: same slug + membership fence. Viewer can read where the route allows it. Editor or admin is required to mutate.
- Not in the CLI: adding or removing site members, transferring ownership,
deleting a site, billing, or minting keys. Those stay in the editor session. A developer
cannot invite themselves onto someone else’s site through
frontpage.
If the caller is an editor or admin of the target site, they can mutate that site. That is membership, not a bypass.
Platform-admin note
API-key authorization does not use platform-admin fleet override. Keys cannot godmode across the fleet. A Frontpage staff account still needs real membership on the site they target with a key.