Orkestia
Blog
Core Concepts

App Data

Platform-owned application data for apps you build on Orkestia — declared structures, injected principals, several doors, no DSN in the frontend

TL;DR

  • App Data is the data plane for apps you build on Orkestia. You declare tables and ownership. Orkestia stores the rows and enforces who can touch them.
  • The frontend never holds a DSN. End-users never send SQL. Access is through typed record workflows, the Data API, PostgREST, or an exposed virtual.
  • Operators have Query. query.orkestia.dev runs admitted SELECT and can mint a read-only login. That is not the end-user path.
  • Ownership is injected from the token. owner (the signed-in end-user), app (a shared catalog), or organization (a workspace). A caller cannot pick another user.
  • Physical Postgres is an instance. shared or dedicated dbhost, provisioned with appdata.instance.*. You never name a host.

It sits next to identity: members operate the org, end-users sign in with @orkestia/auth, and App Data is where those users' rows live. App Host attaches this instance to a public site.

Customer setup lives in the App Data section. This page is the mental model.

The idea

An app that only has "Sign in with Orkestia" still needs state. The unsafe answers are a shared Postgres URL or ad-hoc SQL in the frontend. App Data is the safe answer: virtual structures compiled into catalog metadata and serving DDL, and typed record workflows (or the Data API / PostgREST) as the end-user access path.

declare structure  →  apply  →  (optional) instance.provision + migrate
                 →  write / query as a workflow  →  expose a virtual to end-users

Because every mutating record op is a workflow run, App Data inherits the engine's properties: org scoping, RBAC, history, and Lumen observability. Reads in data.* are treated as safe to start from an assistant.

Ownership in one line

KindIsolation
ownerThe signed-in end-user
appShared catalog for the identity app
organizationThe user's active workspace inside the app, capability-gated

The principal and the active workspace are injected from the token. This is the same isolation tuple (org, app, end-user) described in Identity & multi-tenancy.

How you call it

CallerPath
Org member or agentdata.appdata.* / appdata.* over MCP or the workflow SDKs
Org operator (SQL)Query — admitted SELECT, not the browser app
Browser end-userAn exposed virtual plus the @orkestia/auth JWT, never the raw catalog type
App-user HTTPPostgREST with the end-user JWT
App-user agentThe App Data MCP: discover, describe, read, create, update, delete, call

Ask your AI assistant

prompts
List the data.appdata.* and appdata.instance.* workflow types available to my org and tell me which ones read and which ones write.

Describe the App Data structures declared for identity app <identity_app_uuid>.

Declare a structure called "notes" with fields title (string) and body (text), owned by the end-user. Show me the definition and wait for my confirmation before applying it.

For AI agents

RuleDetail
Reads are safedata.appdata.structure.query, data.appdata.record.query / .read, appdata.instance.status are reads.
Writes are confirmedStructure apply, record create/update/delete, instance provision/migrate, credential create are mutations. Confirm first.
Never fake a principalOwnership comes from the token. There is no input that lets you act as another user.
Omit database_slug only when uniquerecord.* may omit it if the app has exactly one serving database; otherwise it is required.
End-users go through virtualsNever hand a browser the raw catalog type. Expose a composition instead.
No backup verbDo not start appdata.instance.backup — it is not in the catalog.
Not BuzzOrdered append is a table policy. Buzz is Nostr on App Host.
Not FilesOrg-member objects on site MinIO are apphost.file.*. document.* wraps customer storage.* and needs an end-user.

Read the App Data section

Declare, instances, Data API, Query, ownership, expose.