Access-control lists
Endpoint: /api/security/
Manage the command, server and file access-control lists (ACLs) that restrict tokens. You must be signed in through the console or CLI. No personal API token (alpat-) or service token (alpst-) can call these routes: both receive 403 permission_denied, even with command_acl, server_acl or file_acl scopes.
On Alpacon Cloud, set command rules under Pre-approved commands on the token’s page in the web console. Managing this list requires Command ACL admins access, separate from your workspace role; being a Superuser does not grant it. If the card says it is managed by Command ACL admins, ask one of them to add you. Choose Connect if the console asks you to connect your browser. The command ACL rows returned by this API do not decide which token commands run. Every command ACL write, including bulk requests, returns 405 command_acl_moved. Server and file ACL writes remain available.
Access and targets
You can see ACLs for your own personal tokens and for service tokens you can manage. Admins can see all service-token ACLs, including those belonging to deleted applications. Other callers can manage service tokens only for applications they may bind tokens to, and only when the token’s existing server ACLs are within their visible servers. Server ACL lists omit deleted servers.
Every ACL belongs to exactly one token. Set either token or service_token. For writes, a personal token must be your own enabled token; a service token must be approved, enabled and manageable by you. A pending or disabled service-token target returns 400 does_not_exist on service_token. Server ACL bulk deletion also accepts disabled tokens. To change token kind, clear the other field in the same request.
A service-token ACL must match the token’s scopes: command ACLs require a command scope, file ACLs require an uploaded_file or downloaded_file scope, and server ACLs require a resource that accepts server restrictions. A server ACL must also remain within the application’s server scope. Personal-token ACLs do not have these two service-token checks.
Routes
Use command-acl, server-acl or file-acl for {resource} below.
| Method | Route | Response |
|---|---|---|
GET | /api/security/{resource}/ | 200, paginated ACLs |
POST | /api/security/{resource}/ | 201, created ACL |
GET | /api/security/{resource}/{id}/ | 200, ACL |
PUT, PATCH | /api/security/{resource}/{id}/ | 200, updated ACL |
DELETE | /api/security/{resource}/{id}/ | 204, no body |
POST | /api/security/{resource}/bulk/ | 201, array of matching ACLs |
POST | /api/security/{resource}/bulk/delete/ | 200, {"deleted": 2} |
POST | /api/security/command-acl/bulk/update/ | 200, array of updated ACLs |
POST | /api/security/file-acl/bulk/update/ | 200, array of updated ACLs |
There is no server ACL bulk-update route. Duplicate items in a bulk-create request do not create duplicate ACLs. Bulk delete and update ignore IDs outside your visible ACLs.
Request and response fields
All ACLs return id (UUID), token, service_token and the read-only token_name, plus the fields for their type. Send token IDs, not token secrets.
Command ACL
| Field | Type | Required | Description |
|---|---|---|---|
token | UUID | One token field | Your personal API token ID |
service_token | UUID | One token field | Service token ID |
command | string | Yes | One command pattern, up to 255 characters; no operators, newlines or multiple commands |
username | string | No | Up to 128 characters; default empty. Empty means the personal-token owner, or any user for a service token; * means any user |
groupname | string | No | Up to 128 characters; default empty. Empty or * means any group |
Username and group values otherwise match exactly. Newline, carriage-return and null characters are refused. A command is matched after shell tokenization: a final word * matches one or more further arguments, while other * characters match within one word. A quoted * matches nothing. Nothing may follow the final literal. To permit sudo command, the pattern must include the sudo prefix.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": null,
"service_token": "3f1c2a9e-7b6d-4e1f-9a2b-5c8d7e6f4a31",
"token_name": "ci-deploy",
"command": "df -h",
"username": "deploy",
"groupname": ""
}Server ACL
Send token or service_token, plus the required server UUID. The server must be visible to you. On read, server is an object with id, name, os, platform, is_connected and is_deleted.
{
"service_token": "3f1c2a9e-7b6d-4e1f-9a2b-5c8d7e6f4a31",
"server": "7e3984de-49ab-4cc6-bcdf-21fbd35858b8"
}File ACL
Send token or service_token, plus these fields:
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Up to 512 characters; * matches any characters. Control characters are refused; .. segments are normalized while a trailing wildcard is preserved |
action | string | Yes | upload, download or * for both |
username | string | No | Same matching rules as command ACLs; default empty |
groupname | string | No | Same matching rules as command ACLs; default empty |
{
"service_token": "3f1c2a9e-7b6d-4e1f-9a2b-5c8d7e6f4a31",
"path": "/srv/releases/*",
"action": "upload",
"username": "deploy",
"groupname": ""
}Bulk requests
| Resource and action | Body |
|---|---|
Command bulk/ | token or service_token, and items containing 1–100 objects with command, optional username and optional groupname |
File bulk/ | token or service_token, and items containing 1–100 objects with path, action, optional username and optional groupname |
Server bulk/ | token or service_token, and servers containing 1–100 UUIDs |
Server bulk/delete/ | token or service_token, and servers containing 1–100 UUIDs |
Command or file bulk/delete/ | ids containing 1–100 ACL UUIDs |
Command bulk/update/ | ids containing 1–100 ACL UUIDs, and at least one of username, groupname |
File bulk/update/ | ids containing 1–100 ACL UUIDs, and at least one of username, groupname, action |
Bulk creation returns matching rows, including existing matches. For server ACLs, the result contains the token’s ACL rows for the submitted servers. Field limits match single creation.
For example, create server ACLs with this body:
POST /api/security/server-acl/bulk/{
"service_token": "3f1c2a9e-7b6d-4e1f-9a2b-5c8d7e6f4a31",
"servers": ["7e3984de-49ab-4cc6-bcdf-21fbd35858b8"]
}List filters and pagination
| Parameter | Description |
|---|---|
token | Filter by personal token UUID |
api_token | Alias for token |
service_token | Filter by service token UUID |
search | Search personal and service token names |
page | Integer page number, starting at 1 |
page_size | Default 15, maximum 100; larger values are clamped to 100 |
{
"count": 0,
"current": 1,
"next": null,
"previous": null,
"last": 1,
"results": []
}The array contains ACL objects. next and previous are integer page numbers or null; follow page=next until next is null.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_input | Both or neither token fields, invalid control characters, or bulk update without a field to change |
400 | acl_command_not_allowed | Command pattern contains operators, a newline or multiple commands |
400 | acl_exists | Duplicate ACL: same token and command/user/group, server, or path/user/group/action |
400 | does_not_exist | Service-token target is pending, disabled or unavailable to you; reported on service_token |
400 | acl_service_token_forbidden | You cannot bind tokens to any application; reported on service_token |
400 | acl_type_not_allowed_for_token | The token has no scope that permits this ACL type |
400 | acl_server_outside_application_scope | A server lies outside the application’s server scope |
401 | auth_token_missing | Authentication is missing |
403 | permission_denied | A personal API token or service token was used instead of a signed-in session |
403 | workspace_suspended | Write attempted in a suspended workspace |
404 | api_not_found | ACL does not exist or is outside your visible ACLs |
405 | command_acl_moved | Command ACL write on Alpacon Cloud |
There is no plan gate on these ACL routes. See the API reference for the error envelope and Service tokens for token management.