Authentication¶
methodic authenticates to Chronicle using a Bearer token in Authorization: Bearer. The Chronicle constructor takes the token as api_key regardless of its actual format — the server's middleware figures out which kind it is.
Token formats¶
| Format | Holder | Lifetime |
|---|---|---|
| Auth0 access token (RS256 JWT) | Interactive researcher / web UI | Auth0 session lifetime |
sk_user_... |
Researcher API key, minted via POST /api-keys with an Auth0 token |
Configurable, default 90 days |
sk_agent_... |
An agent or developer | Configurable, default 90 days |
sk_worker_... |
A worker on a provisioned instance; minted by Chronicle during provisioning | Tied to the run |
Provisioning paths¶
Chronicle-managed runners (menlo-park)¶
The agent calls POST /experiments/{id}/variations/{n}/runs/{r}/provision. Chronicle spins up the instance, mints a sk_worker_ key scoped to that run, and injects it as CHRONICLE_API_KEY:
import os
from methodic import Chronicle
chronicle = Chronicle(
server_url=os.environ["CHRONICLE_SERVER_URL"],
api_key=os.environ["CHRONICLE_API_KEY"],
)
run = chronicle.run(
os.environ["CHRONICLE_EXPERIMENT_ID"],
int(os.environ["CHRONICLE_VARIATION"]),
int(os.environ["CHRONICLE_RUN"]),
)
Self-managed runners¶
The agent mints a long-lived sk_agent_ key once, then your runner uses it for any number of runs:
curl -X POST https://chronicle.example.com/api-keys \
-H "Authorization: Bearer $AUTH0_TOKEN" \
-d '{"description": "my custom runner", "scopes": [...]}'
The response includes the full key — Chronicle only ever returns it once. Store it somewhere safe (a secret manager).
Researcher (interactive)¶
Hand-paste an Auth0 access token from the web UI dev tools, or grab one programmatically via Auth0's password grant (CI accounts). Same constructor:
Revocation¶
API keys are revocable immediately via DELETE /api-keys/{id}. Chronicle's auth middleware uses an LRU cache for performance but reflects revocations within seconds. If methodic starts getting AuthenticationError (401), the key is no longer valid — there is no automatic refresh.