Authentication

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

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

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

Credential types

PrefixReachesUse for
ck_live_Everything in the tenantServer-side application code
ck_test_Everything, non-productionDevelopment
ck_eph_Everything, 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.

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.uni-flow.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.

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

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

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 hashed and matched, resolving to a tenant.

Sanitise

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

Enforce

Per-key rate limits and quotas are applied before anything 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