Skip to content

API keys

API keys are the credentials your automation uses to call the Evershell control plane API. Sessions sign in humans; API keys sign in scripts, CI runners, agents, and the evershell CLI.

  1. Sign in to the console as Owner or Operator.
  2. Settings → API keys → New key.
  3. Pick a label and a permission template (see below).
  4. Click Create key. The next screen shows the full secret once — copy it into your secret manager or CI’s environment variables. There is no way to retrieve it later; if you lose it, revoke and create a new one.

Or via the API:

Terminal window
curl -X POST https://<your-slug>.evershell.ai/v1/api-keys \
-H "Authorization: Bearer <your-session-jwt>" \
-H "Content-Type: application/json" \
-d '{"label": "CI runner", "permission_set": "submit_observe"}'

The response carries value — the full sk_* secret. The same “only returned once” rule applies on the API path.

Keys can’t pick arbitrary scopes — they pick one of three closed-enum templates. The template determines which /v1/* routes the key can hit. Each scope below is explained in the permissions reference.

TemplatePermissionsWhen to use
full_accesscaps:write, workspace:read, workspace:write, tasks:write, audit:readAutomation that manages providers / agent roles / content packs and runs work
submit_observeworkspace:read, workspace:write, tasks:write, audit:readCI runners / agent runners that drive work but don’t change configuration
read_onlyworkspace:read, audit:readMonitoring, dashboards, audit shipping

Note that tasks:write (unscoped) is granted to keys even though no default member role holds it — keys have no user identity to attribute the per-user :own narrowing against, so they get the org-wide variant.

Things keys never get, regardless of template:

  • Member management (members:write) and billing (billing:write) — people-management and financial actions are human-only.
  • Issuing more keys (apikeys:write) — keys can’t create more keys. New keys come from a signed-in human so the audit trail stays meaningful.
  • Credential management (auth:write) — creating, rotating, or deleting the outbound credentials your agents use (OAuth connections, service accounts, third-party API keys, etc.) stays human-only.
  • Secret management (secrets:write) — Vault values that get injected into outbound calls (signing keys, API tokens, custom headers) are at least as sensitive as the credentials they often hold. Same rationale: human-only.

Pass the key as a bearer token in the Authorization header:

Terminal window
curl -H "Authorization: Bearer sk_..." https://<slug>.evershell.ai/v1/workspaces

For SSE consumers that can’t set headers (browser EventSource), keys may also be presented in the query string:

Terminal window
curl "https://<slug>.evershell.ai/v1/activity/stream?api_key=sk_..."

Session tokens (eyJ...) are never accepted in the query string — URLs leak through referrer headers and server logs. The query path only accepts sk_* keys.

A key bound to one org can’t be used against another — cross-org requests return 403.

From the console: Settings → API keys → the trash icon on the row. Confirm in the dialog.

From the API:

Terminal window
curl -X DELETE https://<slug>.evershell.ai/v1/api-keys/<key-id> \
-H "Authorization: Bearer <your-session-jwt>"

Revocation is eventually consistent. A revoked key may continue to authenticate for a short window (typically under a minute) due to permission caching on the control plane. If you’ve leaked a key and need immediate effect, revoke and treat the window as mitigation overlap — change any downstream secret that the leaked key would have had access to as well.

Every key create and revoke lands in your org’s audit log as api_key_created / api_key_revoked. The detail carries the label, prefix, and permission template — never the secret value. Actions performed with a key are attributed to the system actor on each row; we’re working on per-key attribution in a follow-up.