Service Accounts
Service Accounts provide programmatic, non-human access to your Phase organisation. Each Service Account has its own Role, authentication tokens, and can be granted access to specific Apps and Environments. On this page, we'll look at the API endpoints for managing Service Accounts, their access, and their lifecycle.
The Service Account model
Properties
- Name
id- Type
- string
- Description
Unique identifier for the service account.
- Name
name- Type
- string
- Description
The name of the service account.
- Name
role- Type
- object
- Description
The assigned role, with
idandname.
- Name
createdAt- Type
- timestamp
- Description
Timestamp of when the service account was created.
- Name
updatedAt- Type
- timestamp
- Description
Timestamp of when the service account was last updated.
Detail Properties
When fetching a single service account, additional detail fields are included:
- Name
tokens- Type
- array
- Description
Array of active tokens, each with
id,name,createdAt, andexpiresAt.
- Name
apps- Type
- array
- Description
Array of accessible apps, each with
id,name, and anenvironmentsarray containing the environments the service account can access within that app.
List Service Accounts
Retrieve all active service accounts in the organisation.
Request
curl https://api.phase.dev/v1/service-accounts/ \
-H "Authorization: Bearer {token}"
Response
[
{
"id": "8ab27128-02d8-42c1-b893-12acaffbbd4b",
"name": "deploy-bot",
"role": {
"id": "d3a2124c-9770-42d5-abf8-599b4a372e9d",
"name": "Service"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-01T12:00:00Z"
}
]
Create Service Account
Create a new service account. The server generates all cryptographic keys and mints an initial authentication token, which is returned in the response.
The token and bearerToken fields are only returned once at creation time. Store them securely — they cannot be retrieved again.
JSON Body
Required fields
- Name
name- Type
- string
- Description
The service account name. Maximum 64 characters.
- Name
role_id- Type
- string
- Description
The ID of the role to assign. Must not be a role with global access (e.g. Owner or Admin).
Optional fields
- Name
token_name- Type
- string
- Description
A name for the initial token. Defaults to
"Default".
Request
curl -X POST https://api.phase.dev/v1/service-accounts/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "deploy-bot",
"role_id": "d3a2124c-9770-42d5-abf8-599b4a372e9d",
"token_name": "CI Token"
}'
Response
{
"id": "8ab27128-02d8-42c1-b893-12acaffbbd4b",
"name": "deploy-bot",
"role": {
"id": "d3a2124c-9770-42d5-abf8-599b4a372e9d",
"name": "Service"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-01T12:00:00Z",
"token": "pss_service:v2:<token_value>:<kx_pub>:<share_a>:<wrap_key>",
"bearerToken": "ServiceAccount <token_value>"
}
Get Service Account
Retrieve a single service account with full detail, including tokens and app/environment access.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the service account.
Request
curl https://api.phase.dev/v1/service-accounts/8ab27128-02d8-42c1-b893-12acaffbbd4b/ \
-H "Authorization: Bearer {token}"
Response
{
"id": "8ab27128-02d8-42c1-b893-12acaffbbd4b",
"name": "deploy-bot",
"role": {
"id": "d3a2124c-9770-42d5-abf8-599b4a372e9d",
"name": "Service"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-01T12:00:00Z",
"tokens": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "CI Token",
"createdAt": "2024-06-01T12:00:00Z",
"expiresAt": null
}
],
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"name": "My App",
"environments": [
{
"id": "af6b7a8e-c268-48c2-967c-032e86e26110",
"name": "Development",
"envType": "dev"
},
{
"id": "c23d4e5f-6789-01bc-def2-3456789012cd",
"name": "Production",
"envType": "prod"
}
]
}
]
}
Update Service Account
Update a service account's name and/or role. At least one field must be provided.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the service account.
JSON Body
- Name
name- Type
- string
- Description
The new name. Maximum 64 characters. HTML tags and ASCII control characters are stripped; whitespace is trimmed.
- Name
role_id- Type
- string
- Description
The ID of the new role. Must not be a global-access role — service accounts cannot hold roles with
global_access: true.
Request
curl -X PUT https://api.phase.dev/v1/service-accounts/8ab27128-02d8-42c1-b893-12acaffbbd4b/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "deploy-bot-v2",
"role_id": "6aec9df5-cd75-4645-a9d0-8b6f6aff78d6"
}'
Response
{
"id": "8ab27128-02d8-42c1-b893-12acaffbbd4b",
"name": "deploy-bot-v2",
"role": {
"id": "6aec9df5-cd75-4645-a9d0-8b6f6aff78d6",
"name": "Developer"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-02T14:00:00Z",
"tokens": [],
"apps": []
}
Delete Service Account
Delete a service account. All associated tokens are immediately invalidated (subsequent requests with those tokens return 403 Forbidden), and all app/environment access grants are removed.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the service account.
Request
curl -X DELETE https://api.phase.dev/v1/service-accounts/8ab27128-02d8-42c1-b893-12acaffbbd4b/ \
-H "Authorization: Bearer {token}"
Response
204 No Content
Manage Access
Set the app and environment access for a service account. This is a declarative endpoint — the request body represents the entire desired access state.
- Apps not in the list will have their access revoked.
- Each app entry must include at least one environment.
- To revoke all access for a service account, send an empty
appsarray. - Only apps with Server-side Encryption (SSE) enabled are supported; the endpoint returns
400 Bad Requestfor non-SSE apps. - The service account's
identity_keymust be set (server-generated at creation). The endpoint returns400 Bad Requestif it is missing or blank.
The server automatically handles cryptographic key wrapping for each environment — decrypting environment keys with the server key and re-encrypting them for the service account's identity key.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the service account.
JSON Body
- Name
apps- Type
- array
- Description
An array of app access objects. Each object must have:
id(string): The app ID.environments(array): A list of environment IDs to grant access to. Must not be empty.
Request
curl -X PUT https://api.phase.dev/v1/service-accounts/8ab27128-02d8-42c1-b893-12acaffbbd4b/access/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"environments": [
"af6b7a8e-c268-48c2-967c-032e86e26110",
"c23d4e5f-6789-01bc-def2-3456789012cd"
]
}
]
}'
Response
{
"id": "8ab27128-02d8-42c1-b893-12acaffbbd4b",
"name": "deploy-bot",
"role": {
"id": "d3a2124c-9770-42d5-abf8-599b4a372e9d",
"name": "Service"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-02T15:00:00Z",
"tokens": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "CI Token",
"createdAt": "2024-06-01T12:00:00Z",
"expiresAt": null
}
],
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"name": "My App",
"environments": [
{
"id": "af6b7a8e-c268-48c2-967c-032e86e26110",
"name": "Development",
"envType": "dev"
},
{
"id": "c23d4e5f-6789-01bc-def2-3456789012cd",
"name": "Production",
"envType": "prod"
}
]
}
]
}