End-user data
Once a user is signed in, your app can have them run workflows — query their rows, place an order, send a message — by presenting their JWT. Orkestia injects the user's identity into the run immutably (the caller cannot set or override it), so a workflow can be written to only ever act on that user's data.
How it works
end-user JWT ──► POST /api/workflows ──► Orkestia injects the end-user principal
│
└──► the workflow runs scoped to the user
Three rules the platform enforces for an end-user token:
- It can only start workflows you have explicitly exposed to your app.
- Only virtual (composed) workflows are startable — never raw platform workflows.
- The end-user principal is injected server-side from the verified token; an end-user-scoped workflow reads it and refuses to run without it.
1. Expose a workflow to your end-users
identity.app.expose-virtual-workflow({
identity_app_uuid: "…",
composition_uuid: "…", // a composition you authored
version: 1,
})
Every step in the composition must be marked end_user_eligible. A scoped data step (for example a structured, allow-listed read) is bound so its tenant filter is forced from the end-user's identity — there is no way for the caller to widen it.
2. Invoke it as the user
From your frontend, present the session token as a Bearer:
const res = await fetch('https://workflow-api.orkestia.dev/api/workflows', {
method: 'POST',
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${session.token}` },
body: JSON.stringify({ workflow_type: 'virtual.<uuid>@1', initial_data: { /* free inputs only */ } }),
})
const { state_data } = await res.json() // returns only this user's rows
The user supplies only the free inputs (a filter, a page size). The sensitive parts — which table, which tenant column, the connection — are fixed when you expose the workflow; the user can neither see nor change them.
Why this is safe
No data credential in your app
Your frontend never holds a database or API secret — Orkestia runs the workflow on its side.
Tenant isolation enforced
The user's identity is injected immutably and the scope is forced — one user can never read another's rows.
Audited
Every end-user action is recorded — see identity.end-user.audit-query.
This is the generic pattern behind any Orkestia-backed app: expose a capability, invoke it as the user, let the platform enforce the boundary. Step-by-step author → invoke → share → enable: Compositions. For declared tables see App Data — browsers still never send SQL; operators use Query. Mint the JWT with @orkestia/auth; start the virtual with the Node or Python workflow SDK. End-user HTTP without a virtual is PostgREST.
Sign in with Orkestia
Add hosted, secure-by-default login to your app — PKCE in the browser, RS256 JWTs, MFA and email verification handled for you.
Compositions — use, invoke, share
Save a virtual workflow, invoke it, expose it to your app's users, and let them run it with their Sign in with Orkestia JWT.
