Service Account API — Approval Workflows¶
Service Accounts with the appropriate scope can manage Approval Workflows via the REST API. This enables infrastructure-as-code and GitOps workflows to provision and maintain approval workflow configuration programmatically.
All endpoints are prefixed /api/v1/service/approval-workflows and require a valid session token.
See Authentication for details on obtaining a session token.
Required Scope¶
| Operation | Required scope |
|---|---|
| List or get workflows | approval_workflows — read |
| Create, update, delete, enable, or disable workflows | approval_workflows — write |
Scopes are granted per-service-account by a user with the admin or manager role via the Service Accounts management page. Write scope implicitly grants read access for the same resource.
List Workflows¶
GET /api/v1/service/approval-workflows
Authorization: Bearer <token>
Required scope: read
Supports optional query parameters:
| Parameter | Description |
|---|---|
enabled |
Filter by true or false |
page |
Pagination page (default: 1) |
per_page |
Items per page, max 100 (default: 25) |
Results are ordered alphabetically by name.
Get a Workflow¶
GET /api/v1/service/approval-workflows/{uuid}
Authorization: Bearer <token>
Required scope: read
Returns a single workflow by its UUID. Returns 404 if the workflow does not exist or belongs to a different tenant.
Create a Workflow¶
POST /api/v1/service/approval-workflows
Authorization: Bearer <token>
Required scope: write
Content-Type: application/json
Example request:
{
"name": "Production Cert Approvals",
"description": "Gate all production certificate generation",
"trigger": "generate",
"domain_patterns": ["*.prod.example.com", "api.example.com"],
"bypass_on_renewal": false,
"is_enabled": true,
"approver_user_ids": [12, 34],
"required_approvals": 1,
"approval_timeout_hours": 48
}
Field reference:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Display name for the workflow |
description |
string | No | Optional description |
trigger |
string | Yes | generate, revoke, or both |
domain_patterns |
array | Yes | One or more domain patterns (exact, wildcard, or *) |
bypass_on_renewal |
boolean | No | Skip workflow for renewal operations (default: false) |
is_enabled |
boolean | No | Whether the workflow is active (default: true) |
approver_user_ids |
array | Yes | Array of user IDs from the same tenant |
required_approvals |
integer | No | Number of approvals required before dispatch (default: 1) |
approval_timeout_hours |
integer | No | Hours before a pending request auto-expires (null = no timeout) |
All user IDs in approver_user_ids must belong to the same tenant as the authenticating service account. Cross-tenant user IDs are rejected with a validation error.
Update a Workflow¶
PUT /api/v1/service/approval-workflows/{uuid}
Authorization: Bearer <token>
Required scope: write
Content-Type: application/json
Update requests are partial — include only the fields you want to change. Fields not included in the request body are left unchanged.
Use the same field names and values as the Create endpoint.
Enable a Workflow¶
POST /api/v1/service/approval-workflows/{uuid}/enable
Authorization: Bearer <token>
Required scope: write
Enables a disabled workflow. Idempotent — returns the current state even if the workflow was already enabled.
Disable a Workflow¶
POST /api/v1/service/approval-workflows/{uuid}/disable
Authorization: Bearer <token>
Required scope: write
Disables an active workflow. Idempotent. Pending approval requests created before the workflow was disabled are not affected.
Delete a Workflow¶
DELETE /api/v1/service/approval-workflows/{uuid}
Authorization: Bearer <token>
Required scope: write
Permanently deletes the workflow. Existing approval requests created by the workflow are retained for audit purposes.
Response Format¶
All endpoints return a consistent response envelope:
{
"success": true,
"data": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"name": "Production Cert Approvals",
"description": "Gate all production certificate generation",
"trigger": "generate",
"domain_patterns": ["*.prod.example.com", "api.example.com"],
"bypass_on_renewal": false,
"is_enabled": true,
"approver_user_ids": [12, 34],
"required_approvals": 1,
"approval_timeout_hours": 48,
"created_at": "2026-06-22T00:00:00.000000Z",
"updated_at": "2026-06-22T00:00:00.000000Z"
}
}
Internal database IDs and tenant identifiers are never included in API responses. The uuid field is the stable public identifier for all workflows.
Audit Logging¶
All write operations via the Service Account API generate audit log entries distinct from user-initiated actions:
| Audit event | Triggered by |
|---|---|
approval_workflow.service_account.created |
POST / |
approval_workflow.service_account.updated |
PUT /{uuid} |
approval_workflow.service_account.deleted |
DELETE /{uuid} |
approval_workflow.service_account.enabled |
POST /{uuid}/enable |
approval_workflow.service_account.disabled |
POST /{uuid}/disable |
Each entry includes the service account UUID, service account name, the affected workflow UUID and name, and the caller's IP address.