Skip to main content
Arcanflows

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

TypeDescription
api_keyAPI key for external services
oauth2OAuth 2.0 client credentials and tokens
basic_authUsername and password pair
bearer_tokenBearer token for API authentication
databaseDatabase connection credentials
sshSSH key pair or password
smtpSMTP server credentials
customCustom credential structure

Endpoints

MethodEndpointDescription
GET/v1/credentialsList credentials
POST/v1/credentialsCreate credential
GET/v1/credentials/:idGet credential (secrets hidden)
PUT/v1/credentials/:idUpdate credential
DELETE/v1/credentials/:idDelete credential
GET/v1/credentials/:id/revealReveal secrets (requires permission)
PUT/v1/credentials/:id/secretsUpdate only secrets
POST/v1/credentials/:id/testTest credential connection
GET/v1/credentials/typesList credential types
GET/v1/credentials/auditGlobal audit log
GET/v1/credentials/:id/auditCredential audit log
GET/v1/credentials/:id/accessList access rules
POST/v1/credentials/:id/accessGrant access
DELETE/v1/credentials/:id/access/:access_idRevoke access

List Credentials

GET /v1/credentials

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Items per page (max 100)
typestring-Filter by credential type
searchstring-Search by name
sortstring-created_atSort 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

bash
curl "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

FieldTypeRequiredDescription
namestringYesCredential name (max 100 chars)
typestringYesCredential type (see types table)
descriptionstringNoDescription
secretsobjectYesSecret values (encrypted at rest)
metadataobjectNoNon-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

bash
curl -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

bash
curl -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

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger50Items per page
actionstring-Filter by action: created, updated, deleted, revealed, tested, access_granted, access_revoked
credential_idstring-Filter by credential
user_idstring-Filter by user
afterstring-Events after date (ISO 8601)
beforestring-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

FieldTypeRequiredDescription
integration_typestringYesType: agent, workflow, tool, backend
integration_idstringYesID of the integration
permissionstringNoPermission 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

bash
curl -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 reveal endpoint 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/secrets endpoint

Code Examples

Python SDK

python
from 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

javascript
import { 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);