Guides · Concepts
Data isolation
Each project is physically its own, and the platform — not our code — keeps it that way.
One of everything per project#
A project gets its own SQL database, its own file bucket, and its own isolated worker that has only those two attached. A worker can reach nothing but its own database and bucket: that is a property of the platform's bindings, not a check in a request handler. Two projects of the same account are as separate as two projects of two strangers.
This is also why there are no row-level security policies to write: isolation between customers is physical, and access between the users of one app is decided by the access presets, applied by the API on every request.
The URL addresses, the key authorizes#
A project's data lives at proj-<id>.manybases.com, a label derived from the project id. Owning a URL gives access to nothing: the request lands on that project's worker, which compares "is this key's project mine?" behind the isolation boundary, and refuses with the same neutral 404 a non-existent project would return. The served project is attached to the worker at deployment, never read from the request.
Keys#
Key values are shown once and stored hashed; nobody can read them back. Every request carrying a key is checked against the key service, then against our own records: the account key's own line, or, for a publishable or secret key, the list of cut keys in the project's own database. That is what makes a revoked key refused from the next request on.
Sites and functions#
A deployed site is served on manybases.online, a different domain from the dashboard and the API: a hosted page shares no cookies and no origin with them, and every call it makes to its project's API is a cross-origin request. A site can carry no code, no key and no binding. An edge function runs in its own worker with no attachment to any store: everything it reads or writes goes over HTTP to its project's API with its own secret key, through every check any other request goes through.
Secrets#
Client secrets for edge functions are encrypted at rest, with the encryption bound to the project and the name — a value copied to another project or another name does not decrypt. No route ever returns a value; a signed-in human can read a SHA-256 digest to check a paste.
Region#
Everything a project holds lives in Cloudflare's Western Europe region (weur), fixed at creation and shown on the project card.
What is not isolated#
The account's audit journal, the request log and the SQL history record activity without being attributed to a person — see Retention. And an account key with the "every project" scope opens every project of the account: its scope is the only thing bounding what a compromised key reaches.
