Authorization
Public API — Authentication
Every Public API request is authenticated with an API key and authorized against the permissions granted to that key through roles. This guide covers the headers, key lifecycle, and the permission model.
Obtaining the key
Public API keys are self-managed and can be generated by Administrators directly in Solidstudio CPMS Admin Panel. Navigate to General Settings -> API Keys -> Generate API Key to create a new API Key
Sending the key
Pass the key in the x-api-key header:
curl -s \
-H "x-api-key: $API_KEY" \
"https://<host>/api/v1/charging-stations"The raw Authorization: <key> header (no Bearer prefix) is still accepted for backwards compatibility only. Migrate to x-api-key.
Key lifecycle
-
Keys are provisioned by a platform administrator and shown once at creation — only a bcrypt hash and a 4-character preview are stored server-side. Store the key in a secrets manager; it cannot be recovered later.
-
Keys have an expiry date. An expired key is deactivated on its first use after expiry and all subsequent requests return
401. -
Legacy keys still work but are deprecated. Responses authenticated with one carry the header:
X-API-Deprecation: This API key uses a deprecated format. Please rotate to a new key.Rotate to a new key when you see it.
Authentication failures
| Response | Cause |
|---|---|
401 Unauthorized | Header missing, key unknown, key deleted, or key expired |
403 Forbidden | Key valid, but its roles do not grant the endpoint's required permission |
Permission model
Authorization is role-based:
flowchart LR
K[API key] -->|has many| R[Roles]
R -->|grant| P["Permissions<br/>resource:action"]
P -->|checked per endpoint| E["Endpoint<br/>@RequirePermission"]
- Permissions are flat strings in
resource:actionform, e.g.session:read,charging-station:remote-control,webhook:manage. - Every endpoint declares the permission it requires.
- A key's effective permissions are the union of all its roles' permissions.
Grant keys the minimum set they need: a monitoring integration needs session:read + cdr:read, not system:root.
Discovering permissions and roles
With a key that has system:manage-iam:
# All permission names known to the system
curl -s -H "x-api-key: $API_KEY" "https://<host>/api/v1/iam/permissions"
# Roles, optionally with their permissions
curl -s -H "x-api-key: $API_KEY" "https://<host>/api/v1/iam/roles?include=permissions"Managing roles via the API
The IAM endpoints (/api/v1/iam, permission system:manage-iam) support the full role lifecycle:
| Operation | Endpoint |
|---|---|
| Create role | POST /iam/roles |
| Update role | PATCH /iam/roles/:id |
| Delete role | DELETE /iam/roles/:id |
| Replace role permissions | PUT /iam/roles/:id/permissions |
| Add permissions | POST /iam/roles/:id/permissions |
| Remove one permission | DELETE /iam/roles/:id/permissions/:permissionName |
| Assign roles to an API key | /api-keys endpoints |
| Assign roles to a user | /users endpoints |
Two safety rules apply:
- System roles are immutable — built-in roles cannot be edited or deleted (
403). - Grant ceiling — a caller can only grant permissions it holds itself; adding a permission your own key lacks is rejected.
Security recommendations
- Call the API host-to-host only; never embed keys in client-side code.
- Use one key per integration so keys can be rotated and revoked independently, and usage attributed (
lastUsedAtis tracked per key). - Set expiry dates and rotate before them; treat
X-API-Deprecationas an action item.
Updated 6 days ago