Read database passwords
capability_id: db:read
display_name: Read database passwords
ui_capability_key: read_database_passwords
scope: db:read
endpoint:
method: POST
path: /db/get
operation: database_password.get
billable: true
environment: not_applicable
Purpose and authorization
db:read authorizes an application to retrieve one named database password through POST /db/get. It is a separate capability from secrets:read.
The application must authenticate with Contract v1 credentials and the authenticated application must have the db:read scope. Retrieval is application-scoped; database host, port, database name, user, charset, and connection handling remain the application's responsibility.
Implementation contract
Request
Send a Contract v1 authenticated POST request to /db/get with a JSON body containing exactly one logical name for the lookup:
POST /db/get
Content-Type: application/json
X-GM-App: app_example
X-GM-Ts: 1791748800
X-GM-Sig: <Contract-v1-signature>
X-GM-Credential-Request-ID: 0123456789abcdef0123456789abcdef
{
"name": "primary"
}
The name is trimmed before validation and must match [a-zA-Z][a-zA-Z0-9_.-]{0,63}. It is at most 64 characters: the first character must be an ASCII letter, and remaining characters may be ASCII letters, digits, ., _, or -. A request must include the signed single-use X-GM-Credential-Request-ID required by this credential route. The request ID is a fresh lowercase 32-character hexadecimal value for each attempt. Contract v1 authentication headers and signing rules apply; see the authentication and contract references below.
Only one name can be requested per call. The endpoint does not list names, enumerate credentials, or provide bulk retrieval. Additional JSON fields are ignored by the current route; clients should send only the documented field.
Successful response: password available
When the requested value is available, the response is HTTP 200:
{
"ok": true,
"name": "primary",
"password": "example-password"
}
Successful response: password unavailable
An unknown or otherwise unavailable logical name is intentionally omitted, not disclosed as a separate absence error. The response is HTTP 200:
{
"ok": true,
"name": "primary"
}
The password property is absent, rather than null, an empty string, or a fabricated value. Applications must distinguish an omitted property from an actual returned password by checking whether the property exists. Both successful response forms use Cache-Control: no-store.
Environment independence
Database passwords are environment-independent. /db/get has no environment selector, and official clients do not add one. A logical name refers to the application-scoped password configured under that name across the application's environments. Applications that need distinct values must use distinct logical names and keep their environment mapping locally.
Error outcomes
The omission rule applies only to credential absence. Genuine operational, authentication, validation, replay, entitlement, concurrency, and accounting failures remain errors:
| Condition | HTTP response | Contract meaning |
|---|---|---|
| Authentication failure | 401 | Authentication is missing, invalid, expired, or otherwise rejected. |
Missing db:read scope | 401 | Scope not allowed. |
| Invalid JSON, missing name, or invalid name | 400 | Invalid JSON or Invalid request. |
| Invalid credential request ID | 401 | Invalid credential request ID. |
| Reused credential request ID | 409 | Credential request already used. |
| Credential retrieval unavailable | 503 | Credential retrieval unavailable. |
| Monthly operation allowance exhausted | 403 | monthly_operation_limit_reached. |
| Operation accounting unavailable | 503 | Operation accounting unavailable. |
| Application concurrency limit reached | 429 | app_concurrency_limit_exceeded. |
| Database password retrieval failed | 500 | Database password unavailable. |
Operation and replay obligations
Every accepted lookup consumes one billable database_password.get operation, regardless of whether a password is returned. Authentication, validation and replay rejections do not consume an operation.
A credential-request identifier is single-use and may be consumed even when a subsequent failure prevents disclosure. If the outcome is uncertain, the application MUST NOT assume that no operation was charged. A new attempt requires a fresh identifier and signature and may consume another operation.
The credential request ID is signed and scoped to the application. An optional idempotency key does not make this credential request reusable or deduplicate it.
Implementation outcome
An implementation conforming to this capability:
- authorizes
db:readand callsPOST /db/getwith one validated logical name; - treats an HTTP
200response withoutpasswordas the intentional unavailable-credential result; - never infers absence from a
404response for this route; - accounts for Gateman charging one billable
database_password.getoperation per accepted lookup, including when no password is returned; - preserves genuine errors and respects the HTTP
Cache-Control: no-storeresponse policy; - does not request database connection metadata; and
- keeps returned plaintext in application-controlled memory only as long as needed, without logging or exposing it.
Implementation instructions for agents
- An integration SHOULD use an official Gateman client where appropriate. A direct HTTP implementation MUST conform to Contract v1.
- The integration MUST use authenticated
POST /db/getwith the application'sdb:readscope and one validated logical name per request. - The integration MUST generate a fresh signed, single-use lowercase 32-character hexadecimal
X-GM-Credential-Request-IDfor every attempt. - The integration SHOULD omit
environmentfrom/db/getrequests. Database-password retrieval is environment-independent, and the endpoint does not useenvironmentto select a password. The integration **MUST NOT** enumerate names or request more than one logical name per call. - The integration MUST treat HTTP
200withpasswordas a returned value and HTTP200without thepasswordproperty as an unavailable value. It MUST preserve the requested logical name. - The integration MUST preserve genuine authentication, validation, replay, accounting, concurrency, and retrieval errors as errors; it **MUST NOT** convert them into an unavailable-password result.
- The integration MUST account for Gateman charging one billable
database_password.getoperation per accepted lookup, whether or notpasswordis present. - The integration SHOULD NOT automatically retry an uncertain disclosure. A deliberate retry policy MAY use a fresh request ID and signature and MUST NOT assume that the ambiguous attempt was unaccepted or unbilled.
- The integration MUST protect returned plaintext and SHOULD keep it in memory only as long as needed; it MUST NOT log, commit, or expose it unnecessarily.
- Database connection details and environment mapping MUST remain the application's responsibility; Gateman does not create database connections or supply connection parameters.
Reusable AGENTS.md block
<!-- gateman:begin capability=db:read -->
- Read one application-scoped database password with authenticated Contract v1
`POST /db/get` using `db:read`.
- Send one validated logical `name` per request. Database passwords are
environment-independent. Omit `environment` from requests; Gateman does
not use it to select a password. Do not attempt enumeration or bulk
retrieval.
- Include the signed, single-use lowercase 32-character hexadecimal
`X-GM-Credential-Request-ID`; use a fresh ID and signature for every retry.
- Names MUST be trimmed before validation and match `[a-zA-Z][a-zA-Z0-9_.-]{0,63}`.
- HTTP `200` with `password` means a value was returned. HTTP `200` without
the `password` property means the requested name is unknown or unavailable;
do not expect a separate absence error.
- The integration MUST account for Gateman charging one
`database_password.get` operation per accepted lookup, whether or not
`password` is present. Authentication, validation, and replay rejections
remain errors and do not consume an accepted lookup.
- Do not assume an ambiguous transport outcome was unaccepted or unbilled;
do not reuse its request ID.
- Treat returned passwords as confidential plaintext: do not log, commit,
expose, or retain them longer than needed. Database connection metadata and
environment mapping remain application-owned.
- Full capability reference: https://docs.getgateman.com/capabilities/database-password.read/
<!-- gateman:end capability=db:read -->
