Skip to main content

REST API Reference

All endpoints are served over HTTPS at /api/v1/. Authenticated endpoints require Authorization: Bearer <token>.

Token types: API tokens (arc_ prefix, persistent), JWT tokens (24h, from login), SSO tokens (from OIDC/SAML/LDAP callback).

Quick Example

Store and retrieve a secret (Python)

import urllib.request, json, ssl

ARCAN = "https://localhost:8443"
TOKEN = "arc_your_token_here"
ctx = ssl._create_unverified_context() # self-signed cert

# Store a secret
data = json.dumps({"key": "DATABASE_URL", "value": "postgres://prod:5432/app", "environment": "prod"}).encode()
req = urllib.request.Request(f"{ARCAN}/api/v1/realms/default/secrets", data=data,
headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"})
resp = urllib.request.urlopen(req, context=ctx)
print("Stored:", json.load(resp)["key"])

# Retrieve it
req = urllib.request.Request(f"{ARCAN}/api/v1/realms/default/secrets/DATABASE_URL?env=prod",
headers={"Authorization": f"Bearer {TOKEN}"})
resp = urllib.request.urlopen(req, context=ctx)
secret = json.load(resp)
print("Value:", secret["value"])

Store and retrieve a secret (Go)

package main

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
)

func main() {
arcan := "https://localhost:8443"
token := "arc_your_token_here"
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}

// Store a secret
body, _ := json.Marshal(map[string]string{
"key": "DATABASE_URL", "value": "postgres://prod:5432/app", "environment": "prod",
})
req, _ := http.NewRequest("POST", arcan+"/api/v1/realms/default/secrets", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
fmt.Println("Stored, status:", resp.Status)

// Retrieve it
req, _ = http.NewRequest("GET", arcan+"/api/v1/realms/default/secrets/DATABASE_URL?env=prod", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, _ = client.Do(req)
defer resp.Body.Close()
var secret map[string]interface{}
json.NewDecoder(resp.Body).Decode(&secret)
fmt.Println("Value:", secret["value"])
}

Generate dynamic credentials (curl)

# Generate a short-lived PostgreSQL credential
curl -sk -X POST https://localhost:8443/api/v1/realms/myapp/engines/postgres/generate \
-H "Authorization: Bearer arc_your_token" \
-H "Content-Type: application/json" \
-d '{"ttl": "1h", "config": {"host": "db.internal", "port": 5432, "admin_user": "arcan"}}'

Response:

{
"username": "arcan-a7f3b2c1",
"password": "xK9m2pL4qR...",
"ttl": "1h",
"expires_at": "2026-04-06T13:00:00Z"
}

The generated credentials are temporary — they expire automatically after the TTL and are revoked from the database.


Error Format

{
"error": {
"code": "not_found",
"message": "realm not found -- list realms with: arcan realm list",
"status": 404
}
}

Endpoints

Health

MethodPathAuthDescription
GET/api/v1/healthNoServer status, version, component health

Auth

MethodPathAuthDescription
POST/api/v1/auth/registerNoCreate user account (email, password, name)
POST/api/v1/auth/loginNoLogin with email/password, returns JWT
GET/api/v1/auth/providersNoList configured SSO providers

SSO

MethodPathAuthDescription
GET/api/v1/auth/oidc/{provider}/loginNoInitiate OIDC login (302 redirect)
GET/api/v1/auth/oidc/{provider}/callbackNoOIDC callback, returns JWT
GET/api/v1/auth/saml/{provider}/loginNoInitiate SAML login (302 redirect)
POST/api/v1/auth/saml/{provider}/acsNoSAML assertion consumer service
GET/api/v1/auth/saml/{provider}/metadataNoSAML SP metadata XML
POST/api/v1/auth/ldap/{provider}/loginNoLDAP login (username/password)

Tokens

MethodPathAuthDescription
POST/api/v1/auth/tokensYesCreate API token (name, scopes)
GET/api/v1/auth/tokensYesList API tokens
DELETE/api/v1/auth/tokens/{id}YesRevoke a token

Realms

MethodPathAuthDescription
POST/api/v1/realmsYesCreate realm (slug, name)
GET/api/v1/realmsYesList all realms
GET/api/v1/realms/{slug}YesGet realm details
DELETE/api/v1/realms/{slug}Yes (admin)Soft-delete realm

Secrets

MethodPathAuthDescription
POST/api/v1/realms/{slug}/secretsYesStore a secret (key, value, environment)
GET/api/v1/realms/{slug}/secretsYesList secrets (filter by ?env=)
GET/api/v1/realms/{slug}/secrets/{key}YesGet a secret (filter by ?env=)
DELETE/api/v1/realms/{slug}/secrets/{key}YesDelete a secret (filter by ?env=)
POST/api/v1/encryptYesEncrypt a plaintext value

Store a secret

curl -sk -X POST https://localhost:8443/api/v1/realms/myapp/secrets \
-H "Authorization: Bearer arc_your_token" \
-H "Content-Type: application/json" \
-d '{"key": "API_KEY", "value": "sk-abc123", "environment": "prod"}'

Response:

{
"id": "550e8400-e29b-41d4-a716-446655440000",
"key": "API_KEY",
"value": "sk-abc123",
"environment": "prod",
"version": 1,
"created_at": "2026-04-06T12:00:00Z"
}

Get a secret

curl -sk https://localhost:8443/api/v1/realms/myapp/secrets/API_KEY?env=prod \
-H "Authorization: Bearer arc_your_token"

List all secrets

curl -sk https://localhost:8443/api/v1/realms/myapp/secrets?env=prod \
-H "Authorization: Bearer arc_your_token"

Response:

{
"secrets": [
{"key": "API_KEY", "value": "sk-abc123", "environment": "prod", "version": 1},
{"key": "DATABASE_URL", "value": "postgres://...", "environment": "prod", "version": 3}
]
}

Engines

MethodPathAuthDescription
GET/api/v1/enginesYesList registered engine types
POST/api/v1/realms/{slug}/engines/{type}/generateYesGenerate dynamic credentials
POST/api/v1/realms/{slug}/engines/{type}/validateYesValidate credentials via engine

Policy

MethodPathAuthDescription
GET/api/v1/policy/rolesYesList roles and capabilities
POST/api/v1/realms/{slug}/policy/bindingsYes (admin)Assign role to user
GET/api/v1/realms/{slug}/policy/bindingsYesList role bindings
DELETE/api/v1/realms/{slug}/policy/bindings/{userID}Yes (admin)Remove role binding

ESO (External Secrets Operator)

Simplified endpoints for the Kubernetes External Secrets Operator webhook provider. Returns only secret values (not full secret objects) so ESO can extract them with jsonPath: $.value.

Default environment is prod (not dev) since ESO typically targets production clusters.

MethodPathAuthDescription
GET/api/v1/eso/{realm}/{key}YesGet a single secret value
GET/api/v1/eso/{realm}YesBulk fetch all secrets in realm

Query parameters: ?env= (default prod)

Get single secret

curl -sk https://localhost:8443/api/v1/eso/myapp/DATABASE_URL?env=prod \
-H "Authorization: Bearer arc_your_token"

Response:

{"value": "postgres://user:pass@db:5432/myapp"}

Bulk fetch

curl -sk https://localhost:8443/api/v1/eso/myapp?env=prod \
-H "Authorization: Bearer arc_your_token"

Response:

{
"data": {
"DATABASE_URL": "postgres://user:pass@db:5432/myapp",
"API_KEY": "sk-abc123",
"REDIS_URL": "redis://cache:6379"
}
}

See External Secrets Operator Integration for Kubernetes setup.

Audit

MethodPathAuthDescription
GET/api/v1/audit/eventsYesQuery audit log

Query parameters: ?realm=, ?type=, ?actor=, ?limit= (default 50)

curl -sk "https://localhost:8443/api/v1/audit/events?realm=myapp&type=secret.set&limit=10" \
-H "Authorization: Bearer arc_your_token"

Metrics

MethodPathAuthDescription
GET/metricsNoPrometheus metrics

Available metrics: arcan_http_requests_total, arcan_secrets_total, arcan_auth_attempts_total.