Query console and SQL
Query is how your team looks at the app's Postgres. It is not how end-users read rows, and it is not a second database.
Open query.orkestia.dev. Sign in with the same org session as the console. Pick the Identity app.
Who may send SQL
| Caller | SQL? | Path |
|---|---|---|
| Org member / operator | Yes, through admission | Query console → POST /sql/v1/query on the Data API |
| Process on App Host | The runtime holds DATABASE_URL; you do not paste it into a browser | Attach Postgres |
| End-user / browser | No | Data API, PostgREST, or an exposed virtual |
The frontend still never receives a DSN. Query talks to https://appdata.orkestia.dev with your org token. Placement (which instance, which schema) is resolved from the catalog.
What admission allows
The SQL path is read-only by default:
- exactly one statement per request;
SELECTonly (no INSERT / UPDATE / DDL);- relations in this app's schema only;
BEGIN READ ONLY, statement timeout, row cap;- always rolled back — even a SELECT cannot leave a transaction open.
A refused statement is an error, not an empty grid. 401 / 403 on the Data API fail closed — there is no privileged fallback.
Credentials (direct connection)
Query can mint a read-only LOGIN for tools such as DBeaver or psql:
| Workflow | Use |
|---|---|
appdata.credential.create | Mint a reader role. Password once. |
appdata.credential.list | Active credentials for the app |
appdata.credential.rotate | New password, same role |
appdata.credential.revoke | Drop the login |
The password is a one-time reveal. The console will not show it again.
That login is not the App Host process login. Re-attaching Postgres on the site calls appdata.credential.ensure-app and rotates a writable DATABASE_URL. Neither secret is meant for the frontend.
Direct credentials require a dbhost instance. Apps still on the shared plane need provision first.
Live schema vs declared structure
data.appdata.structure.query is the declaration. appdata.schema.introspect reads what Postgres actually has (tables, views, RPCs, sizes) on the backend that app points at. Query uses both. Drift (declared but missing, or live but undeclared) is a warning, not a merge.
Saved-query and history types (appdata.query.save, .list, .get, .update, .delete, appdata.query.history) are registered org workflows — the same surface an agent can call. Treat field lists as catalog truth.
What Query is not
- It is not Lumen.
- It is not a Chat Relay, and it is not Buzz.
- It does not back up or restore the instance.
- It does not let an end-user JWT run SQL.
