Authentication

Key types, scoping, rotation and revocation — and choosing the right credential.

Every public Platform API request carries a credential in the x-api-key header.

curl https://api.chordian.ai/api/v1/workspaces \
  -H "x-api-key: ck_live_..."

Credential types

PrefixReachesUse for
ck_live_Control plane, Search API and Memory API (subject to KeyScope)Server-side application code
ck_test_Same surface, non-productionDevelopment
ck_eph_Same surface, for 24 hoursCI and short-lived automation
mk_Exactly one memoryAgents, edge deployments, third parties
OAuth 2 tokenWhat its scopes allowMachine-to-machine integrations

Pick the narrowest that works. A tenant-wide key inside a distributed agent is a blast radius nobody chose deliberately — it is what happens when the first key minted is the key that ships.

What a platform key can do

A ck_ key authenticates as the tenant (not a human user). On control-plane routes it has tenant-admin permissions, then KeyScope may narrow that further (modules, memories, read/write, IP allowlist). An empty KeyScope means unrestricted.

Mint, rotate and revoke keys in the console under Settings → API Keys. Those management routes are not on the public gateway — you cannot create or revoke a key by calling /api/v1/api-keys with another ck_ key.

Per-memory keys

An mk_ key is bound to one memory and rejected everywhere else. Pair it with the memory's own hostname:

curl https://acme-1045.api.chordian.ai/api/v1/memory/search \
  -H "x-api-key: mk_..." \
  -H "content-type: application/json" \
  -d '{"query": "..."}'

A leaked mk_ key exposes one memory. A leaked ck_live_ key exposes everything the KeyScope still allows.

Restricting a key

At creation you can set:

app_permissionsobject

Per-app allow-list. Empty means unrestricted, which is the legacy default — set it explicitly for new keys.

ip_allowliststring[]

CIDR ranges the key may be used from.

expires_atstring (date-time)

Automatic expiry. Ephemeral keys get 24 hours by default.

Rotation

Rotate in the console (Settings → API Keys), or via the signed-in portal session against POST /api/v1/api-keys/{key_id}/rotate.

The replacement is minted before the original is revoked, so a rotating client has an overlap window rather than an outage. Deploy the new key, confirm traffic has moved, then revoke.

The plaintext key is returned only in the rotation response. There is no way to read it afterwards.

Revocation

Revoke in the console, or via the signed-in portal session against DELETE /api/v1/api-keys/{key_id}.

Revocation hits the gateway first and the database second. There is no window in which a revoked key still authenticates.

What the gateway does

Resolve

The key is verified at the gateway and resolved to a tenant.

Sanitise

Client-supplied trust headers are stripped, and verified identity is injected in their place.

Enforce

Per-key rate limits, quotas and KeyScope are applied before the request reaches a service.

You never send a tenant id, and there is no parameter that would let you claim one. Cross-tenant access is not blocked so much as unavailable.

Storage

Keys are stored as SHA-256 hashes and compared in constant time. The plaintext is shown exactly once, at creation.

If a key is lost, rotate it. There is no recovery path, and a system that offered one would be storing your key in a form an attacker could steal.

Was this page helpful?
Report an issue

On this page