Skip to main content
Docs navigation

Rotate and revoke credentials

emisar issues several kinds of secret, and they do not behave the same way. Find yours, rotate it without an avoidable outage, and prove the old one no longer carries the authority you thought it did.

Before you start, you need:
  • Owner or admin in the account. Minting an MCP key needs operator or above; rotating and revoking need admin or owner.
  • Access to whatever holds the current value — the client config, the SIEM, the provisioning template, your IdP.
  • A window in which you can watch the consumer. Every rotation below ends with proving the new path works, not with pasting a value.

Which credential is this?#

The prefix alone will not tell you. Both MCP keys and audit-export tokens carry the emk- prefix; what separates them is their kind, and the kinds do not overlap. Start here, then read the section for your row.

Credential Where it is used and stored Authority Routine rotation Immediate containment Overlap Effect on sessions and runners Owner page
MCP API key The LLM client or bridge config on a workstation; held by the client after an OAuth consent Calls MCP tools with its owner's runner scope and role Rotate the key — the successor inherits its name, kind, and scope Revoke — terminal, and it takes the rotation chain with it Yes — until the successor's first successful call No sign-in ends; revoking also stops the OAuth access and refresh tokens backed by that key API keys
Audit-export token Your SIEM or poller config Reads GET /api/audit for this account, and nothing else Mint a second token, move the collector to it, revoke the first Revoke Yes, but you create it — two live tokens until you revoke None — it has no session and reaches no runner Audit & SIEM
Runner enrollment key The provisioning template that sets EMISAR_ENROLLMENT_KEY, and /etc/emisar/runner.env on the host Registers new runners into the account Mint new, update the template, boot one host, revoke old Revoke — stops new registrations only Yes — both keys register until you revoke the old one Connected runners are unaffected; they run on their own tokens Runner fleet
Per-runner token Cached on the host by the runner, issued at registration That one runner's control connection Re-enroll the host under a different enrollment key Delete the runner — terminal. Disable is the reversible lever None — the new token replaces the cached one That runner disconnects: disabled, the service stays up retrying; deleted, it exits Runner fleet
OIDC client secret The SSO connection here, and the app registration at your IdP Authenticates emisar to your identity provider during sign-in Create at the IdP, save here, complete a real sign-in, drop the old Disable or delete the connection Yes, if your IdP can hold two client secrets at once Replacing the secret signs no one out; disabling or deleting the connection revokes sessions authenticated through it Single sign-on
SCIM bearer Your IdP's provisioning connector Directory reads and writes on that connection Rotate token — it takes effect immediately Rotate token, or disable the connection None — provisioning fails until the IdP holds the new value No session ends; provisioning stops until the connector is updated Directory sync
Signed-dispatch leaf The operator's machine, beside the MCP client, as the signing key and its certificate Signs an action a runner that trusts the CA will accept Mint a new certificate under the CA the fleet already trusts None per leaf — rotate the CA across the fleet Yes — every unexpired certificate under a trusted CA keeps working No runner is touched and no run is dropped Signed dispatch
Signed-dispatch CA The trusted_cas list on every runner; the CA private key stays offline Vouches for every leaf a runner will accept Add the new CA, reissue leaves, remove the old, reload every runner The same operation, done urgently Yes — while both CAs are in the list Each step applies on reload without dropping a run; a host you miss still trusts the old CA Signed dispatch
Pack or provider credential /etc/emisar/runner.env on the host, read at process start Whatever the provider grants that value — emisar never holds it Rotate at the provider, update runner.env, restart the service Revoke at the provider The provider's own, if it issues overlapping credentials The restart interrupts actions in flight on that host; nothing else changes Runner fleet

The rotation sequence#

Every credential below follows the same seven steps. Where a credential has no overlap window, its section says so and names the interruption you should expect.

  1. Inventory: find every consumer that holds the current value.
  2. Create the successor.
  3. Update the consumer.
  4. Verify the new path — a real call, a real sign-in, a real registration.
  5. Revoke the predecessor.
  6. Verify the old value now fails.
  7. Read the audit trail: the mint, the revoke, and the actor behind each.
Never paste a secret value into anything that keeps it.

Not a support ticket, not a run's reason field, not an action argument, not a shell example someone will copy. Every credential here is shown once at creation; if you lose it before the consumer takes it, create another one rather than storing it somewhere it does not belong.

MCP API keys#

Rotate from the agent's row on Agents. The successor inherits the old key's name, scope, and kind and gets a new secret and a fresh expiry. Both work during the overlap: the predecessor keeps authenticating until the successor's first successful call retires it. Put the new secret in the client config any time in that window, then confirm one tool call goes through.

  • Revocation is terminal and it cascades. Revoking a key also revokes every key downstream of it in the rotation chain, and any OAuth access or refresh token backed by it stops exchanging and refreshing. That is what makes revoke — not rotate — the containment lever for a leak.
  • OAuth-backed keys do not rotate. A Claude.ai or ChatGPT connection's key is minted by consent with no expiry, because OAuth owns its lifecycle through the refresh token — a fresh emk- secret has no way to reach the client. Reconnect the client to replace it, or revoke it to end it.
  • Proving the old key is dead. A revoked key returns 401 on the client's very next call. A predecessor retired by a successful rotation is spent, not revoked — if you need it provably dead rather than merely superseded, revoke it by hand.

Scope, inheritance, expiry, and the bridge's own automatic rotation of a nearly-expired key live in API keys.

Audit-export tokens#

An audit-export token is a different kind of credential that happens to share the emk- prefix. It reads your account's events and does nothing else: present it to the MCP endpoint and emisar rejects it as the wrong kind, and an MCP key presented to the export API is rejected the same way. That separation is the point — a credential sitting in a SIEM config can never dispatch an action.

There is no successor mechanism here, so make the overlap yourself. Mint a second token on the account's audit export page and give it to the collector without resetting its position: the cursor is the collector's own state, not the token's, so the new credential resumes from exactly the cursor the old one left behind. Let it complete at least one poll on the new token and persist the cursor that poll returns.

That is the check worth doing — it proves the token authenticates and the collector is still writing its position forward, which is what a cutover usually gets wrong. It is not a guarantee of exactly-once delivery: a collector that later restarts from since instead of its saved cursor, or that persists after processing rather than before, can still re-read or skip. Then revoke the old token and confirm it returns 401. The export contract itself — cursors, paging, rate limits — is in Audit & SIEM.

Runner enrollment keys#

An enrollment key registers new runners. It is not what keeps existing runners connected — each host traded its key for its own long-lived token on first connect.

  • Rotating a reusable provisioning key. Mint a new one under Runners → Enrollment keys, update the template that injects EMISAR_ENROLLMENT_KEY — cloud-init, Packer, the autoscaling group's startup script — boot one host to prove the new key enrolls, then revoke the old key.
  • Revocation blocks registrations, not connections. After revoking, a host presenting that key gets 401 from registration. Runners already enrolled under it keep running on their own tokens and are unaffected.
  • Re-enrolling a host you keep. A runner stamps its cached token with a fingerprint of the key that minted it. Set the new key in /etc/emisar/runner.env — or re-run the installer with the new EMISAR_ENROLLMENT_KEY, which writes it for you — and restart. On the next connect the fingerprint no longer matches, so the runner registers again under its configured runner.id (or the hostname, when none is set) and replaces the cached token. No second runner identity appears.

Single-use and reusable keys, caps, and expiry are in Runner fleet; the autoscaling variant is in Autoscaling fleets.

Per-runner tokens#

There is no revoke-the-token-only action in the console. The two levers act on the runner identity, and they are not interchangeable.

  • Disable is reversible. The identity and its token are retained; the connection is refused while it lasts, and the host service stays up retrying. Enable brings it back with no host access at all. Use it to take a runner out of service.
  • Delete is terminal. The token stops working, the next connect gets 401, and the service exits rather than retrying forever. Run and audit history for that runner is preserved.
  • If the token itself may be exposed, replace the identity. Disabling and re-enabling hands the same token back. Delete the runner and enroll the host again under a fresh enrollment key instead.

OIDC client secrets and SCIM bearers#

Both live on an SSO connection, and they fail in opposite directions — one has an overlap, the other has none.

  • OIDC client secret. Create the replacement at your IdP, paste it into the connection, and save. The field is write-only, so leaving it blank keeps the value you already have. Complete a real sign-in through the saved connection before deleting the old secret at the IdP — a connection test proves discovery and reachability, not your client assignment or login policy. Replacing the secret does not sign anyone out.
  • SCIM bearer. Rotate token replaces it immediately with no overlap: the old bearer stops authenticating the moment you rotate, so your IdP connector fails until you paste the new value in. Plan for that gap — it is provisioning downtime, not an outage for anyone already signed in.
  • Disabling or deleting a connection is a different blast radius. It blocks new sign-ins and revokes sessions authenticated through identities on that connection. It does not touch API keys or OAuth credentials, and it does not suspend or delete members. Disabling SCIM also returns role and runner access to owner and admin control and discards the last group snapshot.

The provider-side steps are in Single sign-on and Directory sync; offboarding as a whole is in Authentication.

Signed-dispatch keys#

Rotating an operator's signing key touches no runner: mint a new leaf and certificate under the CA the fleet already trusts, switch the MCP client to it, and you are done. Keep the certificate's lifetime comfortably above your freshness window plus approval turnaround, so an approved run re-dispatched with its original signature is still inside both.

There is no per-certificate kill switch.

emisar publishes no revocation list for signing certificates. A leaked leaf key keeps working until its certificate expires — short lifetimes are what bound that exposure. To contain one before expiry you rotate the trust root: add the new CA alongside the old, reissue operator certificates under it, remove the old CA, and reload every runner. "Every runner reloaded" is the completion bar, and the control plane cannot do it for you.

The CA model, certificate scopes, and the reload mechanics are in Signed dispatch.

Pack and provider credentials#

A pack's credential — a Nomad token, a database password, a cloud key — is never an emisar credential. The runner reads it from its own environment, so the control plane never sees it and cannot rotate it for you.

  1. Rotate the value in the system that owns it — your secret manager, the provider's console.
  2. Update /etc/emisar/runner.env on each affected host, keeping it mode 0600.
  3. Restart the service. The environment is read at process start, so a reload of the pack catalog is not enough.
  4. Run one safe read-only action from that pack and confirm it succeeds.
  5. Revoke the old value at the provider, then run the same action again to confirm nothing still depends on it.

Which variables a pack reads, and how the runner's allowlist decides what reaches an action's process, are in Runner fleet.

Last reviewed August 3, 2026

Suggest a change