Skip to content

Authentication

API keys

The primary auth method is an API key issued from the portal.

  • Format: cloak_<base32> — 256 bits of entropy.
  • Header: Authorization: Bearer cloak_…

Get an API key (headless / no browser)

You do not need a browser to get a working key. A single unauthenticated POST returns a real, immediately-usable free-tier key for the SDK, the gateway API, and the MCP server — ideal for CI, containers, and scripts.

Terminal window
# Anonymous, on-device key (no email needed):
curl -sS -X POST https://api.cloakapi.io/api/v1/self-service/key \
-H 'Content-Type: application/json' -d '{}'
# …or attach an email so you can later verify it, claim a $2 trial credit,
# and manage the key in the portal:
curl -sS -X POST https://api.cloakapi.io/api/v1/self-service/key \
-H 'Content-Type: application/json' \
-d '{"email":"you@example.com","name":"my-ci-key"}'

Response (201):

{
"api_key": "cloak_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"key_prefix": "cloak_XXXXXX",
"tier": "free",
"limits": {
"rate_limit_rpm": 20,
"on_device": "SDK + MCP tokenise / detokenise / detect / device-receipts work immediately.",
"relay": "Content-blind LLM relay needs a positive wallet balance (402 at $0)."
},
"warning": "This key is shown ONCE and is not recoverable. Store it securely."
}

Then use it straight away:

Terminal window
export CLOAKAPI_API_KEY=cloak_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX # SDK + MCP read this
# API: Authorization: Bearer $CLOAKAPI_API_KEY

What the free tier gives you

  • On-device work is unlimited and freedetect_pii / tokenize / detokenize / device-receipts in the SDK and the MCP tokenise family run entirely on your machine; the key only authenticates and attributes usage.
  • Rate-limited to 20 requests/minute per key.
  • LLM relay is balance-gated. A fresh free-tier key has a $0 wallet, so the content-blind relay (POST /api/v1/chat/completions, /api/v1/messages) returns 402 insufficient_balance until you add credit. Verify your email for a $2 trial credit, or top up at app.cloakapi.io/billing.

Guard rails. The endpoint is IP-rate-limited (≤5/hour, ≤20/day per network) and refuses to mint a key onto an email that already has an account (409 account_exists — sign in at the portal instead). It never grants a paid tier or touches another account.

  • Scope: per-organisation. Sub-organisations (partner mode) get distinct keys with their own quotas, rate limits, and balances.
  • Rotation: rotate at any time from API keys → Rotate. The previous key is deactivated immediately — deploy the new key right away (see Key rotation).
  • Revocation: instant. Revoked keys return 401 with a structured error.code: "key_revoked" payload.

OIDC SSO

For human (portal) login, the gateway exposes a standard OIDC discovery surface:

EndpointPath
Discovery/.well-known/openid-configuration
JWKS/oauth/jwks
Userinfo/oauth/userinfo
Token/oauth/token (standard OAuth2)
Authorize/oauth/authorize

Today this is backed by Laravel Passport. An Authentik identity provider is live at auth.cloakapi.io for federated / enterprise SSO flows; portal password login remains Laravel-native.

Per-request scoping

Inside the gateway, requests are scoped by:

  • Tenant — derived from the API key.
  • Sub-organisation — for partner / white-label flows.
  • Capability — fine-grained allowlist (gpt-4o, claude-sonnet-4-6, …) enforced before provider routing.
  • Quota — monthly token budget per (tenant, capability).
  • Rate limit — sliding-window per (tenant, capability) at 60s and 3600s scales.

Per-key scope allowlist (permissions)

Each cloak_* API key carries a permissions array. The current enforced vocabulary is published at GET /api/v1/keys/scopes and contains:

ScopeWhat it grants
messagesPOST /api/v1/messages (Anthropic-format chat)
completionsPOST /api/v1/chat/completions (OpenAI-format chat)
bufferReserved for portal-side buffered-response reads (Sanctum-PAT)

Semantics:

  • An empty or null permissions array is treated as fully permissive (back-compat with keys minted before the allowlist was enforced).

  • When permissions is non-empty and does not contain the scope a route requires, the gateway returns HTTP 403 with the structured envelope:

    {
    "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "This API key is not authorised for the 'completions' capability.",
    "required": ["completions"],
    "granted": ["messages"]
    }
    }

Portal personal-access tokens (Sanctum PATs) are a separate axis used by the dashboard and /api/v1/keys, /api/v1/billing/*, /api/v1/webhooks* and the admin-session/* console. Their vocabulary is published in the UI and includes abilities:write, ability:keys.read, ability:keys.write, ability:billing.read, ability:billing.write, ability:byok.write, and ability:admin. A cloak_* gateway key is never valid for those portal routes, and a Sanctum PAT is never valid for /api/v1/messages or /api/v1/chat/completions.