docs
/
AppEngine API

API keys

Long-lived credentials for server-to-server access, and how they resolve to a user.

An API key is a stand-in for a bearer token on server-to-server calls. It is not a separate identity: every key belongs to a user and inherits that user's roles and permissions.

Using a key

apiKey: <key>
orgid: acme

x-api-key is accepted as well.

CurrentUserMiddleware calls authenticateApiKey(orgId, apiKey, {}), which resolves the key to its owning user, and then injects Authorization: Bearer <token> for the rest of the pipeline. Everything downstream sees an ordinary authenticated user.

Role side effects applied at that point:

  • ConfigAdmin or ContentAdmin on the owner sets data.admin = true.
  • System on the owner sets data.system = true — which also means repository writes will then require x-client-authorization.

Managing keys

POST/api-key/createJWT
GET/api-key/listJWT
GET/api-key/:keyIdJWT
PUT/api-key/:keyIdJWT
DELETE/api-key/:keyIdJWT
POST/api-key/regenerate/:keyIdJWT
GET/api-key/usage/:keyIdJWT

Keys are apikey records. regenerate issues a new secret against the same key record, so you can rotate without re-pointing whatever references it.

Administration

GET/api-key/admin/listJWT
POST/api-key/admin/revoke/:keyIdJWT

Both require RootAdmin or ConfigAdmin.

Org users

GET/api-key/org/:orgidJWT
POST/api-key/org/:orgid/createJWT
POST/api-key/org/:orgid/deleteJWT

Create and delete require RootSystem, RootAdmin or RootPowerUser. These manage the service users that keys are issued against.

Direct authentication

POST/api-key/authNo auth

Public. Exchanges a key for a token explicitly, rather than relying on the middleware's implicit resolution — useful when a client wants to hold a short-lived bearer token instead of sending the key on every call.

Blocking a key

POST/profile/blacklist/apikey/addJWT
DELETE/profile/blacklist/apikey/delete/:apiKeyJWT

BlacklistMiddleware rejects blocklisted keys before the request reaches a controller — the fast path for cutting off a leaked key without waiting for a rotation to propagate.

A key is as privileged as its owner

There is no per-key scope. A key issued against an Owner or ConfigAdmin user can do everything that user can. Create a dedicated low-privilege user per integration and issue the key against it.