Workload Identities API
Named Vault identities for Coderunners, with per-collection grants and short-lived tokens.
Base path: /v1/workspaces/{workspace_id}
A workload identity is a named Data Vault principal that one or more Coderunners share. You give the identity access to specific Vault collections, bind Coderunners to it, and a bound Coderunner mints a short-lived token that carries only those grants.
See also: Coderunners API · M2M API
A workload-identity token is for the Vault only. Feature-flag routes reject it with 403.
Identities
| Method | Path | Permission |
|---|---|---|
GET | …/workload-identities | read |
POST | …/workload-identities | ddl |
GET | …/workload-identities/{identity_id} | read |
PATCH | …/workload-identities/{identity_id} | ddl |
DELETE | …/workload-identities/{identity_id} | ddl |
Create body:
| Field | Required | Notes |
|---|---|---|
name | Yes | 1 to 120 characters |
slug | No | Lowercase letters, digits and hyphens, up to 63 characters. Derived from the name if omitted. A duplicate returns 409 |
Returns 201 with the identity: id, workspace_id, name, slug, created_by, created_at, updated_at and has_refresh_secret. The list route returns { "identities": [ … ] }.
PATCH renames the identity ({ "name": "…" }); the slug does not change. DELETE returns 204. It removes the identity's Vault grants and unbinds any Coderunners that used it, and those Coderunners can no longer mint Vault tokens until you bind another identity.
Grant Vault access
Grants are set per collection with Collection Access, using a grant that names the identity instead of a site role.
The PUT replaces the collection's whole grant list, so send the grants it already has, admin included, plus the identity. Anything you leave out is removed:
{
"grants": [
{ "role": "admin", "action": "delete" },
{ "role": "user", "action": "write" },
{ "principal_type": "workload_identity", "principal_id": "<identity_id>", "action": "read" }
]
}action is read, write or delete. See what an identity can reach:
GET /v1/workspaces/{workspace_id}/workload-identities/{identity_id}/vault-accessReturns { "workspace_id", "workload_identity_id", "grants": [{ "collection", "action" }] }. Permission: read
Bind a Coderunner
PUT /v1/workspaces/{workspace_id}/coderunners/{coderunner_id}/workload-identity{ "workload_identity_id": "<identity_id>" }Send null to unbind. Returns coderunner_id, workload_identity_id and vault_legacy. An identity from another workspace returns 400; an unknown Coderunner returns 404. Permission: ddl
GET /v1/workspaces/{workspace_id}/coderunners/{coderunner_id}/vault-accessReturns the Coderunner's workload_identity and its grants. 404 if the Coderunner isn't in this workspace. Permission: read
Mint a Vault token
POST /v1/workspaces/{workspace_id}/workload-identities/{identity_id}/vault-token
POST /v1/workspaces/{workspace_id}/coderunners/{coderunner_id}/vault-tokenOptional body: coderunner_id (recorded on the token for audit; on the identity route it must be bound to that identity, otherwise 400) and rotate_refresh (default false).
{
"token": "…",
"expires_in": 300,
"token_type": "Bearer",
"workload_identity_id": "…",
"workspace_id": "…",
"coderunner_id": "…",
"refresh_secret": "…"
}expires_inis in seconds. The default is 300 and the platform can set it between 30 and 3,600.refresh_secretis returned once: on the first mint, and again wheneverrotate_refreshistrue. Store it in Secrets. Rotating replaces the previous secret.- On the Coderunner route, a Coderunner with no identity returns 403, or 409 if it predates workload identities (
vault_legacy); bind an identity first.
Permission: write, the same as deploying a Coderunner.
Refresh a token
POST /v1/workspaces/{workspace_id}/workload-identities/{identity_id}/vault-token/refresh{ "refresh_secret": "…", "coderunner_id": "…" }Returns a new token in the same shape, without refresh_secret. The refresh secret is the credential, so this route takes no platform token. A wrong secret returns 401. refresh_secret must be 16 to 256 characters; coderunner_id is optional.