Chelabase

Access per route

The credential and access level every route requires, generated from the route table the gateway and services share.

Every route is declared once, in chelabase-routes, with the credential it takes and an access level. The gateway and the services read the same table. The table below is generated from it and checked by a test, so it can't drift.

Access levels

LevelMeaning
PublicNo identity. Health, the API document, sign-in and accept-invite (the code is the credential).
Data API keyA data API key, checked by the gateway.
Signed inAny verified identity (/v1/me).
Instance adminSelf-hosted: an active tenant admin. Platform: an active member of the operator tenant (CHELABASE_OPERATOR_TENANT_ID).
Tenant memberAny active member of the caller's tenant.
Tenant adminAn active tenant admin.
Project roleThe caller's effective platform role on the project is at least role (Viewer, Developer, Admin). A tenant admin is Admin on every project.
BranchThe minimum depends on the target branch: one role for an unprotected branch, another for a protected one. For merges the target is the branch merged into.
Act asAt least the given platform role, and the Postgres role asked for (?role=, or the console's and SQL editor's role) must be in the caller's effective set. The owner needs Admin. Owner-level, LOGIN and reserved roles, and chains through them, are Admin-only.

How a refusal answers:

CaseStatusCode
No grant on the project (its existence isn't revealed)404not_found
Grant too low, or the role isn't allowed403forbidden, with error.required (the level needed, owner, role:<name>, or connect)
A member with no grants anywhere403no_access_yet
A sign-up waiting for approval403pending_approval
A feature not designed for platform mode403not_available_in_platform_mode

GET /v1/me returns the caller's capabilities: tenant admin, instance admin, and per project the platform role, the Postgres roles they may act as and (projects[].databases) the databases a grant override narrows. It answers 200 for a pending sign-up too, with member.status: "pending". Studio only hides what you can't do; the API decides. See Members and invites and Roles and schema isolation.

Effective access

A member's effective access on a project combines their own grant with the grants of their teams (see Teams), then narrows it by their per-database overrides:

  • Union of sources. The platform role is the best level among the own grant and the team grants. Admin from any source is Admin, holding every Postgres role.
  • Per-role levels. Each Postgres role keeps the highest level among the sources that name it. An Act as route needs the platform level the route asks for and the role held at that level or above: a role held only at Viewer can't be used on POST …/sql.
  • Narrowing afterwards. A database override is intersected with the union; it never widens.
  • Checked on every write. Own-grant, override, team and invite writes are checked on the resulting union for each affected member and database.
  • The data API's extras. anon and authenticated are held only when a source names them, Admins included.

GET /v1/me reports the union per project. POST …/tables/{schema}/{table}/cell (Act as: Viewer) for a role held below Developer is read through the data API's connection, so it needs the data API on for the Postgres database (409 data_api_disabled when off).

Every route

Sorted by path. Credentials: Member token is a member access token from POST /auth/v1/token (Studio's sign-in); the data API's keys are described under Data API.

MethodPathCredentialAccess
POST/auth/v1/accept-invitenonePublic
POST/auth/v1/app/change-emailpublic data keyData API key
POST/auth/v1/app/change-passwordpublic data keyData API key
GET/auth/v1/app/jwksnonePublic
POST/auth/v1/app/password-resetpublic data keyData API key
POST/auth/v1/app/password-reset/confirmpublic data keyData API key
POST/auth/v1/app/refreshpublic data keyData API key
POST/auth/v1/app/resend-codepublic data keyData API key
POST/auth/v1/app/sign-inpublic data keyData API key
POST/auth/v1/app/sign-outpublic data keyData API key
POST/auth/v1/app/sign-uppublic data keyData API key
GET/auth/v1/app/userpublic data keyData API key
POST/auth/v1/app/verify-emailpublic data keyData API key
GET/auth/v1/instancenonePublic
POST/auth/v1/invitenonePublic
POST/auth/v1/logoutnonePublic
POST/auth/v1/password-resetnonePublic
POST/auth/v1/password-reset/confirmnonePublic
POST/auth/v1/resend-codenonePublic
POST/auth/v1/sign-innonePublic
POST/auth/v1/sign-upnonePublic
GET/auth/v1/studio-confignonePublic
POST/auth/v1/tokennonePublic
POST/auth/v1/verify-emailnonePublic
POST/data/v1/queryany data keyData API key
GET/data/v1/schemasecret data keyData API key
GET/data/v1/typessecret data keyData API key
GET/healthnonePublic
GET/v1/access-eventsMember tokenTenant admin
POST/v1/databasesMember tokenProject Admin
DELETE/v1/databases/\{id\}Member tokenProject Admin
GET/v1/databases/\{id\}Member tokenProject Viewer
PATCH/v1/databases/\{id\}Member tokenProject Admin
GET/v1/databases/\{id\}/branchesMember tokenProject Viewer
POST/v1/databases/\{id\}/branchesMember tokenProject Developer
DELETE/v1/databases/\{id\}/branches/\{branch_id\}Member tokenBranch: Developer unprotected, Admin protected
PATCH/v1/databases/\{id\}/branches/\{branch_id\}Member tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/connectionMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/console/queryMember tokenAct as: Viewer and the role in your set
GET/v1/databases/\{id\}/branches/\{branch_id\}/console/schemaMember tokenAct as: Viewer and the role in your set
GET/v1/databases/\{id\}/branches/\{branch_id\}/data-api/schemaMember tokenProject Viewer
GET/v1/databases/\{id\}/branches/\{branch_id\}/data-api/typesMember tokenProject Developer
GET/v1/databases/\{id\}/branches/\{branch_id\}/databasesMember tokenProject Viewer
GET/v1/databases/\{id\}/branches/\{branch_id\}/guard-exemptionsMember tokenProject Developer
DELETE/v1/databases/\{id\}/branches/\{branch_id\}/guard-exemptions/\{role\}Member tokenProject Admin
PUT/v1/databases/\{id\}/branches/\{branch_id\}/guard-exemptions/\{role\}Member tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/keysMember tokenProject Viewer
POST/v1/databases/\{id\}/branches/\{branch_id\}/keysMember tokenProject Developer
DELETE/v1/databases/\{id\}/branches/\{branch_id\}/keys/\{key_id\}Member tokenProject Developer
PATCH/v1/databases/\{id\}/branches/\{branch_id\}/keys/\{key_id\}Member tokenProject Developer
POST/v1/databases/\{id\}/branches/\{branch_id\}/keys/\{key_id\}/rotateMember tokenProject Developer
POST/v1/databases/\{id\}/branches/\{branch_id\}/mergesMember tokenBranch: Developer unprotected, Admin protected
GET/v1/databases/\{id\}/branches/\{branch_id\}/objectsMember tokenProject Viewer
PATCH/v1/databases/\{id\}/branches/\{branch_id\}/pg-databases/\{name\}Member tokenProject Admin
DELETE/v1/databases/\{id\}/branches/\{branch_id\}/pg-databases/\{name\}/data-apiMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/pg-databases/\{name\}/data-apiMember tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/pg-databases/\{name\}/privilegesMember tokenProject Viewer
POST/v1/databases/\{id\}/branches/\{branch_id\}/reset-passwordMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/reset-to-parentMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/branches/\{branch_id\}/restoreMember tokenBranch: Developer unprotected, Admin protected
GET/v1/databases/\{id\}/branches/\{branch_id\}/reviewMember tokenProject Developer
POST/v1/databases/\{id\}/branches/\{branch_id\}/review/acknowledgeMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/review/fixMember tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/rolesMember tokenProject Viewer
POST/v1/databases/\{id\}/branches/\{branch_id\}/rolesMember tokenProject Admin
DELETE/v1/databases/\{id\}/branches/\{branch_id\}/roles/\{role\}Member tokenProject Admin
PATCH/v1/databases/\{id\}/branches/\{branch_id\}/roles/\{role\}Member tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/roles/\{role\}/delete-previewMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/roles/\{role\}/reset-passwordMember tokenProject Admin
GET/v1/databases/\{id\}/branches/\{branch_id\}/roles/\{role\}/sessionsMember tokenProject Admin
POST/v1/databases/\{id\}/branches/\{branch_id\}/schema-changesMember tokenAct as, by branch: Developer unprotected, Admin protected, and the role in your set
POST/v1/databases/\{id\}/branches/\{branch_id\}/sqlMember tokenAct as: Developer and the role in your set
POST/v1/databases/\{id\}/branches/\{branch_id\}/sql/runs/\{run_id\}/cancelMember tokenProject Developer
GET/v1/databases/\{id\}/branches/\{branch_id\}/sql/schemaMember tokenAct as: Developer and the role in your set
GET/v1/databases/\{id\}/branches/\{branch_id\}/tables/\{schema\}/\{table\}Member tokenProject Viewer
POST/v1/databases/\{id\}/branches/\{branch_id\}/tables/\{schema\}/\{table\}/cellMember tokenAct as: Viewer and the role in your set
POST/v1/databases/\{id\}/branches/\{branch_id\}/tables/\{schema\}/\{table\}/rows/defaultMember tokenAct as: Developer and the role in your set
GET/v1/databases/\{id\}/branches/\{branch_id\}/typesMember tokenProject Viewer
GET/v1/databases/\{id\}/connectionMember tokenProject Admin
GET/v1/databases/\{id\}/mergesMember tokenProject Viewer
GET/v1/databases/\{id\}/merges/\{merge_id\}Member tokenProject Viewer
PATCH/v1/databases/\{id\}/merges/\{merge_id\}Member tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/abandonMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/applyMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/cancelMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/finishMember tokenBranch: Developer unprotected, Admin protected
GET/v1/databases/\{id\}/merges/\{merge_id\}/plan.sqlMember tokenProject Viewer
POST/v1/databases/\{id\}/merges/\{merge_id\}/recomputeMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/rehearseMember tokenBranch: Developer unprotected, Admin protected
POST/v1/databases/\{id\}/merges/\{merge_id\}/retryMember tokenBranch: Developer unprotected, Admin protected
PUT/v1/databases/\{id\}/personal-loginMember tokenProject Developer
POST/v1/databases/\{id\}/personal-login/reset-passwordMember tokenProject Developer
GET/v1/databases/\{id\}/personal-loginsMember tokenProject Admin
DELETE/v1/databases/\{id\}/personal-logins/\{member_id\}Member tokenTenant member
POST/v1/databases/\{id\}/reset-passwordMember tokenProject Admin
GET/v1/databases/\{id\}/sql-queriesMember tokenProject Developer
POST/v1/databases/\{id\}/sql-queriesMember tokenProject Developer
DELETE/v1/databases/\{id\}/sql-queries/\{query_id\}Member tokenProject Developer
GET/v1/databases/\{id\}/sql-queries/\{query_id\}Member tokenProject Developer
PATCH/v1/databases/\{id\}/sql-queries/\{query_id\}Member tokenProject Developer
GET/v1/instance/settingsMember tokenInstance admin
PATCH/v1/instance/settingsMember tokenInstance admin
POST/v1/invitesMember tokenTenant admin
GET/v1/invites/deliveryMember tokenTenant member
DELETE/v1/invites/\{invite_id\}Member tokenTenant admin
POST/v1/invites/\{invite_id\}/resendMember tokenTenant admin
GET/v1/meMember tokenSigned in
GET/v1/membersMember tokenTenant member
DELETE/v1/members/\{member_id\}Member tokenTenant admin
PATCH/v1/members/\{member_id\}Member tokenTenant admin
POST/v1/members/\{member_id\}/approveMember tokenTenant admin
POST/v1/members/\{member_id\}/declineMember tokenTenant admin
GET/v1/members/\{member_id\}/personal-loginsMember tokenTenant member
POST/v1/members/\{member_id\}/reinstateMember tokenTenant admin
POST/v1/members/\{member_id\}/revoke-postgres-accessMember tokenTenant admin
POST/v1/members/\{member_id\}/suspendMember tokenTenant admin
GET/v1/members/\{member_id\}/teamsMember tokenTenant member
GET/v1/openapi.jsonnonePublic
GET/v1/projectsMember tokenTenant member
POST/v1/projectsMember tokenTenant admin
DELETE/v1/projects/\{id\}Member tokenProject Admin
GET/v1/projects/\{id\}Member tokenProject Viewer
PATCH/v1/projects/\{id\}Member tokenProject Admin
GET/v1/projects/\{id\}/access-eventsMember tokenProject Admin
DELETE/v1/projects/\{id\}/app-usersMember tokenProject Admin
GET/v1/projects/\{id\}/app-usersMember tokenProject Viewer
PUT/v1/projects/\{id\}/app-usersMember tokenProject Admin
GET/v1/projects/\{id\}/grantsMember tokenProject Admin
DELETE/v1/projects/\{id\}/grants/\{member_id\}Member tokenProject Admin
PUT/v1/projects/\{id\}/grants/\{member_id\}Member tokenProject Admin
DELETE/v1/projects/\{id\}/grants/\{member_id\}/overridesMember tokenProject Admin
PUT/v1/projects/\{id\}/grants/\{member_id\}/overridesMember tokenProject Admin
POST/v1/projects/\{id\}/invitesMember tokenProject Admin
GET/v1/projects/\{id\}/team-grantsMember tokenProject Admin
GET/v1/projects/\{id\}/usersMember tokenProject Viewer
POST/v1/projects/\{id\}/usersMember tokenProject Developer
DELETE/v1/projects/\{id\}/users/\{user_id\}Member tokenProject Developer
GET/v1/projects/\{id\}/users/\{user_id\}Member tokenProject Viewer
PATCH/v1/projects/\{id\}/users/\{user_id\}Member tokenProject Developer
POST/v1/projects/\{id\}/users/\{user_id\}/deactivateMember tokenProject Developer
POST/v1/projects/\{id\}/users/\{user_id\}/reactivateMember tokenProject Developer
DELETE/v1/projects/\{id\}/users/\{user_id\}/sessionsMember tokenProject Developer
GET/v1/projects/\{id\}/users/\{user_id\}/sessionsMember tokenProject Viewer
GET/v1/realtime/socketnonePublic
POST/v1/realtime/ticketsMember tokenSigned in
GET/v1/teamsMember tokenTenant member
POST/v1/teamsMember tokenTenant admin
DELETE/v1/teams/\{team_id\}Member tokenTenant admin
GET/v1/teams/\{team_id\}Member tokenTenant member
PATCH/v1/teams/\{team_id\}Member tokenTenant admin
DELETE/v1/teams/\{team_id\}/grants/\{project_id\}Member tokenTenant admin
PUT/v1/teams/\{team_id\}/grants/\{project_id\}Member tokenTenant admin
DELETE/v1/teams/\{team_id\}/members/\{member_id\}Member tokenTenant admin
PUT/v1/teams/\{team_id\}/members/\{member_id\}Member tokenTenant admin
PATCH/v1/tenantMember tokenTenant admin

On this page