API keys¶
chronicle.api_keys mints and manages the sk_... keys that automation and agents authenticate with, and pins each one to exactly the authority it should carry. This page is the minting/management reference — for token formats and methodic auth login, see the auth guide.
Minting a key¶
create returns the full record including the secret (key). key_type is "agent" (automation, the default) or "user" (a researcher). With no restriction, the key inherits your full owner authority.
from methodic import Chronicle
chronicle = Chronicle.from_env()
minted = chronicle.api_keys.create(
"ci-runner",
key_type="agent",
expires_at="2026-12-31T00:00:00Z", # optional; omit for the default lifetime
)
print(minted["id"], minted["key"]) # sk_agent_... — store it now
The secret is shown exactly once
create and rotate are the only calls that return the key field. It is never retrievable again — copy it into a secret manager immediately. Lose it and you rotate.
Restrictions — the authority ceiling¶
A restriction narrows a key below the owner's authority (never above), mapping each privilege verb to the targets that verb is limited to; None means full owner authority. A restricted calling key can only mint or edit keys within its own restriction — the server enforces the subset rule.
Two module-level helpers build the common ceilings. Both pin every mutating verb — create, write, discuss, delete, trigger, stop — to a single object, deny administer, and leave read/audit unrestricted so the key still reads broadly:
| Helper | Mutating verbs pinned to | Use |
|---|---|---|
org_ceiling_restriction(organization_id) |
[organization:<id>] |
The UI's org-context key — mutate only inside one org |
experiment_ceiling_restriction(experiment_id) |
[experiment:<id>] |
The dispatched-agent shape — mutate only one experiment |
from methodic import api_keys
restriction = api_keys.experiment_ceiling_restriction("exp_7Qk")
scoped = chronicle.api_keys.create("agent-exp7Qk", restriction=restriction)
For anything else, pass the restriction dict yourself: {verb: [{"object_type": ..., "object_id": ...}, ...]}. See reference/client.md for the full shape.
Org-bound keys¶
create_org_bound is the convenience over create + org_ceiling_restriction — a key that can only mutate inside organization_id, while reads stay broad:
Listing¶
list returns every key you own — each {id, name, key_type, created_at, expires_at, restriction?}, no secrets. The id is the handle for rotate, set_restriction, and revoke:
Rotating¶
rotate is single-step: same key row (id, name, restriction), fresh secret. The old secret stops validating immediately and the new key is returned once. Reach for it when a key leaks or its setup snippet is lost — identity and grants are unchanged.
Editing a restriction¶
set_restriction replaces a key's restriction in place (Cloudflare-style permission editing). Passing None clears it to full owner authority — only allowed when your calling credential is itself unrestricted.
chronicle.api_keys.set_restriction("key_abc123", api_keys.org_ceiling_restriction("org_4f2a"))
chronicle.api_keys.set_restriction("key_abc123", None) # clear → full owner authority
Revoking¶
revoke is immediate — any agent using the key is locked out at once.