Service tokens
Long-lived API keys for headless agents and CI pipelines.
JWTs are user-bound and browser-issued. That's fine for your dev box
but awkward for a CI runner that has no browser. Service tokens are
the answer: an art_* bearer string scoped to a single workspace and
a single mode (rw / ro) with an explicit TTL.
Mint
artifacts key create \
--workspace cases \
--mode rw \
--ttl 30d \
--name panta-ci
The CLI prints the new key once:
Key created: art_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Save this. It will not be shown again.
Save it in your secret store (Fly secrets, GitHub Actions secrets, AWS SecretsManager, 1Password, etc.).
| Flag | Meaning |
|---|---|
--workspace <name> | Restrict the key to one workspace. Required for v0; unscoped keys are v1. |
--mode rw | ro | Caps the maximum mount-session mode this key can request. An ro key cannot mount rw. |
--ttl <duration> | 1h, 24h, 30d, etc. After expiry the key auto-revokes. |
--name <label> | Human label (shown in artifacts key list). |
Use
Pass via the standard Authorization: Bearer … header. Or wire as
the --token for artifacts login:
artifacts login --token "$PANTA_CI_KEY"
artifacts mount cases /mnt/work
The CLI doesn't care whether the bearer is a JWT or an art_* key;
the orchestrator accepts both shapes.
What service tokens cannot do
Service tokens are user-class minus a few high-risk operations. They specifically cannot:
- mint another service token (
artifacts key createrequires a user-class JWT); - create / delete workspaces (those are user-class operations too);
- escalate from
rotorwmode at mount time (the per-key cap is enforced server-side).
This means a leaked CI key can't bootstrap into something more dangerous than what it already had access to.
List + revoke
artifacts key list
# ID NAME WORKSPACE MODE EXPIRES
# 8f3a2c91-... panta-ci cases rw 2026-06-02T...
artifacts key revoke <id>
Revoke is immediate. The next request bearing that key gets a 401
unauthorized: api key has been revoked.
Revoking a key does NOT terminate any mount sessions that the key had
already issued. Mount sessions outlive their issuing token by design;
the per-mount Redis ACL holds independently. To force-tear an
in-flight mount, the customer has to artifacts unmount or you can
delete the workspace.
Rotation
Mint a new key, deploy it to your CI / secret store, then revoke the old one. There's no built-in rolling-rotation; the same pattern as AWS access keys works fine.