Credentials API
API reference for the encrypted credential vault — store, manage, and control access to secrets.
Overview
The Credentials API provides a secure, encrypted vault for managing API keys, OAuth tokens, database passwords, and other secrets. All secrets are encrypted at rest using AES-256-GCM. Access is controlled per-integration with a full audit trail.
Credential Types
| Type | Description |
|---|---|
api_key | API key for external services |
oauth2 | OAuth 2.0 client credentials and tokens |
basic_auth | Username and password pair |
bearer_token | Bearer token for API authentication |
database | Database connection credentials |
ssh | SSH key pair or password |
smtp | SMTP server credentials |
custom | Custom credential structure |
Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /v1/credentials | List credentials |
POST | /v1/credentials | Create credential |
GET | /v1/credentials/:id | Get credential (secrets hidden) |
PUT | /v1/credentials/:id | Update credential |
DELETE | /v1/credentials/:id | Delete credential |
GET | /v1/credentials/:id/reveal | Reveal secrets (requires permission) |
PUT | /v1/credentials/:id/secrets | Update only secrets |
POST | /v1/credentials/:id/test | Test credential connection |
GET | /v1/credentials/types | List credential types |
GET | /v1/credentials/audit | Global audit log |
GET | /v1/credentials/:id/audit | Credential audit log |
GET | /v1/credentials/:id/access | List access rules |
POST | /v1/credentials/:id/access | Grant access |
DELETE | /v1/credentials/:id/access/:access_id | Revoke access |
List Credentials
GET /v1/credentials
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 20 | Items per page (max 100) |
type | string | - | Filter by credential type |
search | string | - | Search by name |
sort | string | -created_at | Sort field (- for descending) |
Response
json{ "data": [ { "id": "cred_abc123", "name": "Production OpenAI Key", "type": "api_key", "description": "OpenAI API key for production agents", "is_valid": true, "last_tested_at": "2025-12-07T14:00:00Z", "last_used_at": "2025-12-07T15:30:00Z", "created_at": "2025-11-01T10:00:00Z", "updated_at": "2025-12-07T14:00:00Z" } ], "pagination": { "page": 1, "per_page": 20, "total": 8, "total_pages": 1 } }
Example
bashcurl "https://api.arcanflows.io/v1/credentials?type=api_key&per_page=10" \ -H "Authorization: Bearer your_api_key"
Create Credential
POST /v1/credentials
Request Body
json{ "name": "Production OpenAI Key", "type": "api_key", "description": "OpenAI API key for production agents", "secrets": { "api_key": "sk-proj-xxxxxxxxxxxx" }, "metadata": { "environment": "production", "provider": "openai" } }
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Credential name (max 100 chars) |
type | string | Yes | Credential type (see types table) |
description | string | No | Description |
secrets | object | Yes | Secret values (encrypted at rest) |
metadata | object | No | Non-sensitive metadata |
Secret Schemas by Type
api_key:
json{ "api_key": "your_api_key_here" }
oauth2:
json{ "client_id": "your_client_id", "client_secret": "your_client_secret", "access_token": "current_access_token", "refresh_token": "refresh_token", "token_url": "https://oauth.provider.com/token", "scopes": ["read", "write"] }
basic_auth:
json{ "username": "user", "password": "pass" }
bearer_token:
json{ "token": "your_bearer_token" }
database:
json{ "host": "db.example.com", "port": 5432, "database": "mydb", "username": "admin", "password": "secret", "ssl_mode": "require" }
ssh:
json{ "host": "server.example.com", "port": 22, "username": "deploy", "private_key": "-----BEGIN OPENSSH PRIVATE KEY-----\n..." }
smtp:
json{ "host": "smtp.gmail.com", "port": 587, "username": "[email protected]", "password": "app_password", "encryption": "tls" }
Response
json{ "data": { "id": "cred_abc123", "name": "Production OpenAI Key", "type": "api_key", "description": "OpenAI API key for production agents", "is_valid": null, "metadata": { "environment": "production", "provider": "openai" }, "created_at": "2025-12-07T10:00:00Z", "updated_at": "2025-12-07T10:00:00Z" } }
Note: Secrets are never returned in create or update responses. Use the reveal endpoint to view them.
Example
bashcurl -X POST "https://api.arcanflows.io/v1/credentials" \ -H "Authorization: Bearer your_api_key" \ -H "Content-Type: application/json" \ -d '{ "name": "Production OpenAI Key", "type": "api_key", "secrets": { "api_key": "sk-proj-xxxxxxxxxxxx" } }'
Get Credential
GET /v1/credentials/:id
Returns the credential metadata without secrets. Secret values are replaced with masked placeholders.
Response
json{ "data": { "id": "cred_abc123", "name": "Production OpenAI Key", "type": "api_key", "description": "OpenAI API key for production agents", "secrets": { "api_key": "sk-proj-****xxxx" }, "is_valid": true, "last_tested_at": "2025-12-07T14:00:00Z", "last_used_at": "2025-12-07T15:30:00Z", "metadata": { "environment": "production", "provider": "openai" }, "access_count": 3, "created_at": "2025-11-01T10:00:00Z", "updated_at": "2025-12-07T14:00:00Z" } }
Update Credential
PUT /v1/credentials/:id
Updates credential metadata. To update secrets, use the dedicated secrets endpoint.
Request Body
json{ "name": "Updated Credential Name", "description": "Updated description", "metadata": { "environment": "staging" } }
Response
Returns the updated credential object (secrets hidden).
Delete Credential
DELETE /v1/credentials/:id
Permanently deletes the credential and all associated access rules. Integrations using this credential will stop working.
Response
HTTP/1.1 204 No Content
Reveal Secrets
GET /v1/credentials/:id/reveal
Returns the full, unmasked secret values. Requires elevated permissions and is recorded in the audit log.
Response
json{ "data": { "id": "cred_abc123", "secrets": { "api_key": "sk-proj-abcdef1234567890" }, "revealed_at": "2025-12-07T16:00:00Z", "revealed_by": "user_xyz789" } }
Security: Every reveal action is logged in the audit trail. Limit access to admin roles.
Update Secrets
PUT /v1/credentials/:id/secrets
Updates only the secret values without changing metadata. The previous secrets are overwritten.
Request Body
json{ "secrets": { "api_key": "sk-proj-new-key-value" } }
Response
json{ "data": { "id": "cred_abc123", "secrets_updated": true, "updated_at": "2025-12-07T16:05:00Z" } }
Test Credential
POST /v1/credentials/:id/test
Tests the credential by performing a lightweight connectivity check against the target service.
Response (Success)
json{ "data": { "id": "cred_abc123", "test_result": "success", "message": "Successfully authenticated with OpenAI API", "response_time_ms": 230, "tested_at": "2025-12-07T16:10:00Z" } }
Response (Failure)
json{ "data": { "id": "cred_abc123", "test_result": "failed", "message": "Authentication failed: invalid API key", "error_code": "auth_invalid", "tested_at": "2025-12-07T16:10:00Z" } }
Example
bashcurl -X POST "https://api.arcanflows.io/v1/credentials/cred_abc123/test" \ -H "Authorization: Bearer your_api_key"
List Credential Types
GET /v1/credentials/types
Returns all available credential types and their required secret fields.
Response
json{ "data": [ { "type": "api_key", "label": "API Key", "description": "API key for external services", "secret_fields": [ { "key": "api_key", "label": "API Key", "required": true, "type": "password" } ] }, { "type": "oauth2", "label": "OAuth 2.0", "description": "OAuth 2.0 client credentials and tokens", "secret_fields": [ { "key": "client_id", "label": "Client ID", "required": true, "type": "text" }, { "key": "client_secret", "label": "Client Secret", "required": true, "type": "password" }, { "key": "access_token", "label": "Access Token", "required": false, "type": "password" }, { "key": "refresh_token", "label": "Refresh Token", "required": false, "type": "password" }, { "key": "token_url", "label": "Token URL", "required": false, "type": "url" }, { "key": "scopes", "label": "Scopes", "required": false, "type": "array" } ] }, { "type": "database", "label": "Database", "description": "Database connection credentials", "secret_fields": [ { "key": "host", "label": "Host", "required": true, "type": "text" }, { "key": "port", "label": "Port", "required": true, "type": "number" }, { "key": "database", "label": "Database", "required": true, "type": "text" }, { "key": "username", "label": "Username", "required": true, "type": "text" }, { "key": "password", "label": "Password", "required": true, "type": "password" }, { "key": "ssl_mode", "label": "SSL Mode", "required": false, "type": "select" } ] } ] }
Global Audit Log
GET /v1/credentials/audit
Returns the audit trail for all credential operations across the tenant.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 50 | Items per page |
action | string | - | Filter by action: created, updated, deleted, revealed, tested, access_granted, access_revoked |
credential_id | string | - | Filter by credential |
user_id | string | - | Filter by user |
after | string | - | Events after date (ISO 8601) |
before | string | - | Events before date (ISO 8601) |
Response
json{ "data": [ { "id": "audit_001", "credential_id": "cred_abc123", "credential_name": "Production OpenAI Key", "action": "revealed", "user_id": "user_xyz789", "user_email": "[email protected]", "ip_address": "192.168.1.100", "timestamp": "2025-12-07T16:00:00Z" }, { "id": "audit_002", "credential_id": "cred_abc123", "credential_name": "Production OpenAI Key", "action": "tested", "user_id": "user_xyz789", "user_email": "[email protected]", "details": { "result": "success" }, "ip_address": "192.168.1.100", "timestamp": "2025-12-07T16:10:00Z" } ], "pagination": { "page": 1, "per_page": 50, "total": 42, "total_pages": 1 } }
Credential Audit Log
GET /v1/credentials/:id/audit
Returns the audit trail for a specific credential. Same response format as the global audit log.
List Access Rules
GET /v1/credentials/:id/access
Returns all access rules for a credential, showing which integrations and users can use it.
Response
json{ "data": [ { "id": "access_001", "credential_id": "cred_abc123", "integration_type": "agent", "integration_id": "agent_def456", "integration_name": "Support Bot", "permission": "read", "granted_by": "user_xyz789", "granted_at": "2025-12-01T10:00:00Z" }, { "id": "access_002", "credential_id": "cred_abc123", "integration_type": "workflow", "integration_id": "wf_ghi789", "integration_name": "Lead Processing", "permission": "read", "granted_by": "user_xyz789", "granted_at": "2025-12-03T14:00:00Z" } ] }
Grant Access
POST /v1/credentials/:id/access
Grants an integration (agent, workflow, tool, or backend) permission to use this credential.
Request Body
json{ "integration_type": "agent", "integration_id": "agent_def456", "permission": "read" }
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
integration_type | string | Yes | Type: agent, workflow, tool, backend |
integration_id | string | Yes | ID of the integration |
permission | string | No | Permission level: read (default), admin |
Response
json{ "data": { "id": "access_003", "credential_id": "cred_abc123", "integration_type": "agent", "integration_id": "agent_def456", "permission": "read", "granted_by": "user_xyz789", "granted_at": "2025-12-07T16:30:00Z" } }
Example
bashcurl -X POST "https://api.arcanflows.io/v1/credentials/cred_abc123/access" \ -H "Authorization: Bearer your_api_key" \ -H "Content-Type: application/json" \ -d '{ "integration_type": "agent", "integration_id": "agent_def456", "permission": "read" }'
Revoke Access
DELETE /v1/credentials/:id/access/:access_id
Revokes an integration's access to this credential. The integration will no longer be able to use the secret values.
Response
HTTP/1.1 204 No Content
Security Notes
- All secrets are encrypted at rest using AES-256-GCM encryption
- Secrets are never logged or included in error messages
- The
revealendpoint requires explicit permission and is audited - Credential access is scoped per-integration — agents can only read credentials granted to them
- Deleting a credential immediately invalidates all access rules
- Rotate secrets regularly using the
PUT /v1/credentials/:id/secretsendpoint
Code Examples
Python SDK
pythonfrom arcanflows import Arcanflows client = Arcanflows(api_key='your_api_key') # Create a credential cred = client.credentials.create( name='Stripe API Key', type='api_key', secrets={'api_key': 'sk_live_xxxx'}, metadata={'provider': 'stripe'} ) # Grant an agent access client.credentials.grant_access( credential_id=cred.id, integration_type='agent', integration_id='agent_abc123' ) # Test the credential result = client.credentials.test(cred.id) print(f"Test result: {result.test_result}") # Reveal secrets (admin only) revealed = client.credentials.reveal(cred.id) print(f"API Key: {revealed.secrets['api_key']}")
JavaScript SDK
javascriptimport { ArcanFlows } from '@arcanflows/sdk'; const client = new Arcanflows({ apiKey: 'your_api_key' }); // Create a credential const cred = await client.credentials.create({ name: 'Stripe API Key', type: 'api_key', secrets: { api_key: 'sk_live_xxxx' }, metadata: { provider: 'stripe' }, }); // Grant an agent access await client.credentials.grantAccess(cred.id, { integrationType: 'agent', integrationId: 'agent_abc123', }); // Test the credential const result = await client.credentials.test(cred.id); console.log('Test result:', result.testResult); // View audit log const audit = await client.credentials.audit(cred.id); console.log('Audit entries:', audit.data.length);