API key management
API keys give programmatic clients long-lived credentials to authenticate against the Arbitex API. This guide covers the full key lifecycle: creation, use, rotation, temporary suspension, revocation, and org-level governance patterns for multi-team deployments.
For interactive user sessions authenticated via a login flow, use JWT access tokens rather than API keys. API keys are intended for service accounts, CI/CD pipelines, and any non-interactive client that cannot complete an OAuth flow.
How API key authentication works
Section titled “How API key authentication works”Pass the API key in the Authorization header as a Bearer token:
Authorization: Bearer arb_a1b2c3d4e5f6...The key is validated against a stored hash. The plaintext key is never stored after the creation response is returned. If you lose a key, revoke it and generate a replacement — there is no retrieval path.
Creating a key
Section titled “Creating a key”Via API
Section titled “Via API”curl -X POST https://api.arbitex.ai/api/auth/api-keys \ -H "Authorization: Bearer <your_session_token>" \ -H "Content-Type: application/json" \ -d '{ "description": "data-pipeline-prod", "expires_in_days": 90 }'Request body fields:
| Field | Required | Description |
|---|---|---|
description | No | Human-readable label for identifying this key (e.g., "ci-pipeline-staging") |
expires_in_days | No | Days until expiry. Omit for a non-expiring key. |
Response (201 Created):
{ "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "key_prefix": "arb_a1b2", "description": "data-pipeline-prod", "created_at": "2026-03-11T00:00:00Z", "last_used": null, "expires_at": "2026-06-09T00:00:00Z", "is_enabled": true, "api_key": "arb_a1b2c3d4e5f6g7h8..."}The api_key field is the only time the plaintext key is returned. Store it in your secrets manager immediately — it cannot be retrieved again.
Via the admin UI
Section titled “Via the admin UI”Navigate to Settings → API Keys → New API Key. Enter a description and optional expiry. The generated key is shown once after creation.
Key format and identification
Section titled “Key format and identification”Each key has an 8-character prefix (key_prefix) derived from the first 8 characters of the plaintext key. The prefix is stored in the database and shown in key listings.
Full key: arb_a1b2c3d4e5f6g7h8...Prefix: arb_a1b2 ← stored, shown in listingsUse the prefix to match a credential you find in a log or config file to the corresponding key record without exposing the full value.
Listing keys
Section titled “Listing keys”Returns metadata for all keys owned by the authenticated user. The plaintext key and hash are never included.
curl https://api.arbitex.ai/api/auth/api-keys \ -H "Authorization: Bearer <your_session_token>"Response:
[ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "key_prefix": "arb_a1b2", "description": "data-pipeline-prod", "created_at": "2026-03-11T00:00:00Z", "last_used": "2026-03-11T08:30:00Z", "expires_at": "2026-06-09T00:00:00Z", "is_enabled": true }]last_used is updated each time the key successfully authenticates a request. Keys with a last_used value more than 30 days in the past are candidates for rotation or revocation.
Setting expiry
Section titled “Setting expiry”Pass expires_in_days at creation to set an expiry date. Once set, expiry cannot be changed — to modify the expiry of an existing key, revoke it and create a replacement.
# Expires in 30 dayscurl -X POST https://api.arbitex.ai/api/auth/api-keys \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"description": "short-lived-script", "expires_in_days": 30}'
# Non-expiring (omit expires_in_days)curl -X POST https://api.arbitex.ai/api/auth/api-keys \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"description": "long-running-service"}'A key with expires_at set will return 401 Unauthorized after that timestamp regardless of its is_enabled state.
Disabling vs. revoking
Section titled “Disabling vs. revoking”Disabling (PATCH with is_enabled: false) prevents the key from authenticating without deleting it. The key can be re-enabled. Use this to temporarily block access while investigating a suspected compromise, before deciding whether to revoke.
# Disablecurl -X PATCH https://api.arbitex.ai/api/auth/api-keys/{key_id} \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"is_enabled": false}'
# Re-enablecurl -X PATCH https://api.arbitex.ai/api/auth/api-keys/{key_id} \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"is_enabled": true}'Revoking (DELETE) permanently removes the key record. The key is immediately invalid. Deletion is not reversible and has no soft-delete state.
curl -X DELETE https://api.arbitex.ai/api/auth/api-keys/{key_id} \ -H "Authorization: Bearer <token>"Returns 204 No Content on success.
| Action | Reversible | Removes from DB | When to use |
|---|---|---|---|
| Disable | Yes | No | Temporary suspension, active investigation |
| Revoke (DELETE) | No | Yes | Confirmed compromise, decommissioning |
Key rotation
Section titled “Key rotation”Rotate on a fixed schedule (quarterly minimum) or immediately after any suspected exposure. The procedure below avoids downtime by running the old and new keys in parallel briefly.
-
Generate the replacement key under the same service account, with a description that identifies it as the new key:
Terminal window curl -X POST https://api.arbitex.ai/api/auth/api-keys \-H "Authorization: Bearer <session_token>" \-H "Content-Type: application/json" \-d '{"description": "data-pipeline-prod-2026-06","expires_in_days": 90}' -
Copy the
api_keyvalue from the response and store it in your secrets manager. -
Update all consumers — environment variables, CI/CD secrets, Kubernetes secrets — to use the new key. Verify that each service authenticates successfully before proceeding.
-
Revoke the old key:
Terminal window curl -X DELETE https://api.arbitex.ai/api/auth/api-keys/{old_key_id} \-H "Authorization: Bearer <session_token>"
Do not revoke the old key until all clients are confirmed to be using the new one. Running both keys briefly in parallel is safe — they are independent credentials.
Org-level key governance
Section titled “Org-level key governance”Scoping keys to teams via service accounts
Section titled “Scoping keys to teams via service accounts”API keys carry the permissions of the user account that created them. There is no mechanism to scope a key to a subset of the creator’s permissions. To achieve least-privilege access across teams:
-
Create a dedicated service account for each team or service (e.g.,
svc-data-pipeline,svc-ci-prod). Assign that account the minimum required role (userfor most integrations,adminonly if admin endpoints are required). -
Generate keys under the service account rather than personal user accounts. This ties the key’s lifecycle to the service account, not to an individual’s employment status.
-
Provision one key per deployment environment (
staging,prod) with distinct descriptions. This makes it possible to rotate the staging key without affecting production.
Example: per-team key structure
Section titled “Example: per-team key structure”| Service Account | Keys | Purpose |
|---|---|---|
svc-pipeline-prod | pipeline-prod-2026-06 | Production data pipeline |
svc-pipeline-staging | pipeline-staging-2026-06 | Staging data pipeline |
svc-ci | ci-prod-2026-06 | CI/CD integration tests |
svc-analytics | analytics-2026-06 | Read-only analytics queries |
Revoking a service account
Section titled “Revoking a service account”When a service account is decommissioned or a team member leaves, an admin can revoke all keys owned by that account via the admin endpoint:
# List all keys across all userscurl https://api.arbitex.ai/api/admin/api-keys \ -H "Authorization: Bearer <admin_token>"
# Revoke a specific key (admin can revoke any user's key)curl -X DELETE https://api.arbitex.ai/api/admin/api-keys/{key_id} \ -H "Authorization: Bearer <admin_token>"Admin operations
Section titled “Admin operations”Admins (users with the admin role) can list and revoke API keys across all user accounts.
List all keys
Section titled “List all keys”curl https://api.arbitex.ai/api/admin/api-keys \ -H "Authorization: Bearer <admin_token>"Returns metadata for all keys across all user accounts. Use this for periodic audits: identify stale keys (no last_used in 30+ days), keys missing descriptions, or keys without expiry dates on accounts that should have them.
Revoke any key
Section titled “Revoke any key”curl -X DELETE https://api.arbitex.ai/api/admin/api-keys/{key_id} \ -H "Authorization: Bearer <admin_token>"Used during incident response to immediately invalidate a compromised credential without requiring access to the key owner’s account. Returns 204 No Content on success.
Security practices
Section titled “Security practices”Store keys in a secrets manager. Do not embed API keys in source code, committed .env files, or CI/CD configuration in plaintext. Use Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, or your platform’s native secrets store. Inject the value at runtime.
Set expiry on all keys. Reserve non-expiring keys for cases where automated rotation is not feasible. For most use cases, 30–90 days is appropriate.
Use service accounts, not personal accounts. Keys generated under personal accounts lose access when the user’s account is deprovisioned. Service accounts have an independent lifecycle.
Monitor last_used. Keys unused for 30 or more days are candidates for revocation. Run a monthly audit via the admin list endpoint to clean up stale credentials.
Revoke immediately on exposure. If a key appears in a log, a public repository, or a compromised system, revoke it immediately using DELETE. Do not rely on disabling alone — a disabled key can be re-enabled. After revoking, review audit logs to assess unauthorized use.
Rotate on a fixed schedule. Quarterly rotation is the minimum. Automate rotation where possible: generate a replacement, update consumers, revoke the old key.
Endpoint reference
Section titled “Endpoint reference”| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST | /api/auth/api-keys | Session token | Create a key for the authenticated user |
GET | /api/auth/api-keys | Session token | List the authenticated user’s keys |
PATCH | /api/auth/api-keys/{key_id} | Session token | Enable or disable a key |
DELETE | /api/auth/api-keys/{key_id} | Session token | Revoke a key owned by the authenticated user |
GET | /api/admin/api-keys | Admin session token | List all keys across all users |
DELETE | /api/admin/api-keys/{key_id} | Admin session token | Revoke any user’s key |
See also
Section titled “See also”- API Keys admin reference — UI-focused operations for admins
- Rate limiting — Rate limits applied to API key requests
- Audit log export — Track key usage in audit logs
- Security overview — Authentication architecture