Opt in and create
CallPOST /api/v1/databases/{databaseId}/legacy-roles/opt-in with an empty
body. The response contains the overlay ID, generation and reserved or
active status. Repeating the request for the same database uses the same
overlay. A database outside the activated set is refused.
Call POST /api/v1/databases/{databaseId}/legacy-roles with a stable
Idempotency-Key header and an exact body:
accessProfile is custom, read_only or read_write. A database may have
up to three extra roles; each role has a connection limit from 1 to 20.
custom receives no object grants automatically. The response gives a
generated roleId and PostgreSQL username, never the password. Reuse the
same idempotency key after an uncertain result; changing its choices conflicts.
Call POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/prepare
with an empty body. This prepares the login and returns sql_ready. The
database owner must grant CONNECT to the generated username if it is not
already granted. Call
POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/admit with an
empty body after the grant. Admission checks the exact role, TLS connection
and grant before returning ready. If an agent outcome is uncertain, call
POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/reconcile with
an empty body before retrying another step.
List, credentials and changes
GET /api/v1/databases/{databaseId}/legacy-roles lists metadata only. Use
?includeRevoked=true to include roles that have been revoked.
POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/credentials
with an empty body explicitly reveals the ready role’s current password. The
response is marked no-store; keep the password in a secret store and do not
put it in logs or an application repository. The original owner credential is
never returned by this endpoint.
To rotate or revoke a role, call
POST /api/v1/databases/{databaseId}/legacy-roles/{roleId}/changes with a
stable Idempotency-Key and {"kind":"rotate","confirmDisconnect":true}
or {"kind":"revoke","confirmDisconnect":true}. Open sessions may be
disconnected. Read the returned operation via
GET /api/v1/databases/{databaseId}/legacy-roles/{roleId}/changes/{operationId}.
For an uncertain outcome, replay the exact change through POST at that
operation URL with {"confirmDisconnect":true}. Removing a role uses
DELETE /api/v1/databases/{databaseId}/legacy-roles/{roleId} and refuses
unresolved dependencies rather than cascading through customer objects.