API tokens

Two token kinds decide execution (ADR 0027 §1); the client — CLI, MCP, raw HTTP — is irrelevant.

kindTRexecution
agentAjanpropose-only: every live mutation is recorded into a proposal; bound to exactly one workspace (writing main is refused with agent_workspace_only); can never apply, publish, or hold secret/token-admin scopes
developerGeliştiricidirect: executes with rev-guarded CAS semantics (409 on drift, never merged)

Scope model

scope_registry.grantable_to ∈ {any, developer, session}; GET /v1/scopes serves the registry with TR labels and sensitivity. A token holds at most 10 scopes.

Session-only — never mintable on ANY token (the admin wildcard included):

scope
admin
agents:admin
proposals:approve
checkout

Ajan-forbidden — an agent token can never be minted with these:

scope
admin
agents:admin
proposals:approve
checkout
secrets:write
design:publish

Defaults at mint: Ajan = catalog:read, design:read, catalog:write, design:write, proposals:write, sandbox:use; Geliştirici = catalog:read, design:read, catalog:write, design:write. orders:* is opt-in on both (sensitive).

Owner-policy commands a developer token may still run with an explicit opt-in grant (never in defaults; the mint dialog warns):

commandrequired scope
design.publishdesign:publish
design.rollbackdesign:publish
secret.setsecrets:write
secret.deletesecrets:write

Secrets can NEVER be set by agents. secret.set/secret.delete are owner-policy commands; secrets:write is developer-grantable only, and Ajan tokens can never hold it — extensions.ops.get reports missing_secret:<key> until the owner (or a secrets:write developer) enters the value.

Lifecycle

Generated from the live platform registries at build time — reference pages cannot go stale. Markdown variant: /reference/tokens.md