Orkestia
Blog
App Data

App Data

Platform-owned application data — declare tables, never hold a DSN in the frontend. Workflows, Data API, PostgREST, and an admitted SQL console for operators.

App Data is Orkestia's data plane for apps you build on the platform. You declare databases, tables, fields, and ownership. Orkestia stores the rows, binds the caller, and enforces isolation. Your frontend never receives a database credential.

It is the missing half of App Enablement: "Sign in with Orkestia" authenticates the user; App Data is where that user's (or that workspace's) rows live.

App Data is in open beta: every Orkestia account can use it, with no invite or waitlist. Structure apply, record workflows, instances, credentials, ownership modes, PostgREST, and the Data API MCP are live. Treat type names and field lists as illustrative — resolve them from the live catalog (data.appdata.*, appdata.*).

Why it exists

Vibecoded and product apps need persistent state. Giving those builders a raw Postgres URL, or asking them to write multi-tenant SQL in the browser, is how isolation bugs ship. App Data inverts that:

  • You declare a virtual structure (database → tables → fields → ownership).
  • Orkestia compiles it into catalog metadata and serving DDL.
  • End-user reads and writes are typed workflows (or the Data API / PostgREST on top of those rules).
  • The principal is injected server-side from the verified token. A caller cannot pick another user's id.
  • Your team can run admitted SQL in Query. That door is org-operator only.

Catalog rows are scoped to (organization_uuid, identity_app_uuid). The physical Postgres is a serving instance (shared or dedicated dbhost) — not a DSN you paste.

Surfaces

SurfaceWhat you do there
Structure (data.appdata.structure.apply / .query)Declare or inspect virtual databases and tables
Instances (appdata.instance.*)Own Postgres for the app — provision, status, migrate, pause, resume
Records (data.appdata.record.*, data.appdata.transaction.apply)Create, read, query, update, delete rows (soft delete)
Documents (data.appdata.document.*)Upload slots, confirm, query, download URLs — end-user files wrapping storage.*, not the Identity app Files tab
Data API / MCPdiscover → describe → read / create / update / delete / call — no SQL
PostgREST HTTPStandard /rest/v1 with an Orkestia end-user JWT — no DSN
Query consoleAdmitted SELECT and read-only logins at query.orkestia.dev
Exposed virtualsWhat a browser with an end-user JWT is allowed to start

Declare structures

Virtual databases, tables, fields, uniqueness, and ownership policy.

Records & Data API

CRUD through workflows or the App Data MCP — structured filters, never SQL from the browser.

Ownership & workspaces

Owner-scoped rows, app-owned catalogs, organization workspaces, and RBAC.

Expose to end-users

Compose a virtual, expose it, invoke it with the @orkestia/auth JWT.

PostgREST HTTP

Point a standard PostgREST client at /rest/v1 with the public JWKS.

Ordered append

Server-allocated positions, exactly-once replay, and membership-scoped rows.

Databases and instances

Shared plane vs dedicated Postgres. Provision, migrate, pause.

Query console

Operator SQL admission, live schema, read-only credentials.

What App Data is not

  • It is not a DSN you put in frontend source, and it is not a place for end-users to send SQL.
  • It is a place for operators to run admitted SELECT in Query, and for a process to use a platform-minted DATABASE_URL.
  • It is not Lumen. Lumen stores telemetry; App Data stores your app's business rows.
  • It is not your cloud database. Side-effecting cloud data still lives in your accounts, reached through connections and workflows.
  • It is not Buzz, and it is not a Chat Relay. Ordered append + membership is the data primitive for streams; Buzz is a Nostr websocket on a different hostname.
  • It is not the Identity app Files tab. Org-member objects on site MinIO are apphost.file.*. document.* is the end-user path that wraps a customer storage.* bucket.
  • Backup / restore of an instance is not a catalog workflow yet.

See Security & compliance for the custody boundary. App Data is a deliberate, scoped store: the rows of apps that opted into the platform data plane, isolated by identity and ownership — not a copy of customer cloud data.

To attach this instance to a hosted site (so a process or Buzz can use it) and to browse records in the console, see App Host.

Typical path

1. Provision the identity app          identity.app.provision
2. (For a public site) go live         identity.app.set-mode → live
3. Claim the site (optional)          apphost.site.claim
4. Declare tables                    data.appdata.structure.apply
5. Dedicated instance when needed    appdata.instance.provision → migrate
6. Compose end-user-eligible virtuals composition / DevKit vw
7. Expose them                       identity.app.expose-virtual-workflow
8. Sign the user in                  @orkestia/auth
9. Read / write as that user         exposed virtual, Data API, or PostgREST
An end-user browser starts only an exposed virtual (virtual.<uuid>@<version>), never a raw data.appdata.record.write. The catalog type stays on the org / agent side. See Expose.