# Hosting and security (/product/infrastructure/hosting)



Isolation spans three planes. The **data plane** is one database per tenant, identical in every tier. The **runtime** is which deployment serves the tenant, and so the blast radius of a leaked environment. The **control plane** is the provisioning root that can reach any tenant. Only the runtime and the secret store vary by tier.

## Hosting tiers

| Tier                      | Runtime                                             | Per-tenant secrets      | For                |
| ------------------------- | --------------------------------------------------- | ----------------------- | ------------------ |
| **Shared**                | One deployment, subdomain-routed.                   | None; platform sandbox. | Free and approved. |
| **Dedicated, Pro**        | Own Vercel project serving the tenant's host alone. | Own Vercel environment. | Paid.              |
| **Dedicated, Enterprise** | Own Vercel project, own repository.                 | Own Vercel environment. | Paid, custom code. |

Blast radius follows the runtime. A shared-runtime compromise reaches every shared tenant; a dedicated tenant's reaches only itself. Dedicated is not new architecture: it is the same tenant app given an exact host that overrides the shared wildcard. Holding any live payment or integration secret promotes a tenant to dedicated.

## Database roles

The owner role Neon provisions owns the schema, runs migrations, and is the definer behind every privileged function. Beneath it sit the four runtime roles: `anonymous` and `authenticated` for the Data API, both row-level scoped; `reader` for cached server reads; and `rpc_writer`, which holds no table grants and can only execute the write functions.

A privileged write bypasses row-level security through a definer function. Each such function pins its search path, is owned by a scoped role rather than a superuser, and re-checks authorization in its own body, because the policies no longer gate it.

## Secrets

A tenant's service secrets, payment gateway keys, the Shopify token, webhook signing secrets, never reach the browser and never live in the tenant database. A dedicated tenant carries them as write-only Vercel secrets on its own project. A shared tenant holds none and transacts against platform sandbox credentials in a no-real-money demo mode. The client-safe half of each integration, a publishable key or a storefront domain, stays in settings, where the browser can read it and so it is effectively public.

The one server-only secret in a tenant database is its storage keys, needed by the shared runtime that has no per-tenant environment. The row is double-walled, revoked from the Data API roles and readable only by the read-only role, and its contents are sealed under a key held only in the runtime environment, so a backup or a dump yields ciphertext.

## The control plane

Above both runtimes sits the provisioning root: the Neon key that can create and delete projects. It is reserved for exactly those two operations. Every other fleet operation, migrate, seed, grant, snapshot, rotate, storage, Data API, takes the tenant's own **project-scoped** key, minted at provision time, sealed under a secret that lives only in the operations environment, and stored on the tenant's fleet row. That key is an editor over one project and cannot delete it, so the routine paths cannot reach another tenant or destroy their own.

Reaching the fleet needs the platform database **and** the operations runtime. Neither alone is a credential.

## The fleet directory

The platform database has two schemas. The public one holds everything a customer reaches, accounts, organizations, projects, plans, chats, under row-level security. The sealed `fleet` schema holds the slug-to-endpoint directory and the sealed keys: no customer-facing role has usage on it, no grants exist inside it, and the API cannot address it. Provisioning fails if any of that regresses.

A table belongs in the sealed schema only if it is an input to provisioning or routing and is never read under a customer token. Plans and modules describe what a customer is owed, so they are public.

## Custody

Kikstart keeps custody of every tenant it provisions; a dedicated runtime does not shrink the control plane. Only a customer owning their own Neon project removes that custody, and that is a contractual option, not a code change.
