seal

Using Seal

Markdown

Rotating and revoking

How access ends: expiry, removing a grant, retiring key versions, and rotating the key itself.

There is no kill switch for one blob. Seal never stores blobs, and every copy opens the same way. You end access by changing what the enclave allows, or by killing the key at the provider.

The ways access ends#

An expiry sealed into the blob (--expires)
What it stopsThat blob, every copy of it
Who does itWhoever seals it, at seal time
Removing an app or identity from the grants (seal revoke app)
What it stopsEvery session that identity starts
Who does itYour admins
Removing a replica's deployment (seal revoke enclave)
What it stopsEverything that replica serves
Who does itYour admins
Retiring old tenant key versions (seal settings tenant-key bump --retire-older)
What it stopsEvery blob sealed under an older version
Who does itYour admins
Revoking the key at the provider
What it stopsThe key itself, everywhere
Who does itWhoever owns the upstream account
Ending a session (close())
What it stopsOne session
Who does itYour app, or the enclave on an integrity finding
An integrity suspension
What it stopsEverything one identity does
Who does itYour tenant's integrity policy
Terminal
# Give a blob an end date when you seal it. It can't be changed later.
$seal secret --to https://api.openai.com/v1 --app ci --expires 2026-12-31 < openai-key.txt > ci.blob
# Remove a whole app, or one of its identities
$seal revoke app checkout
$seal revoke app checkout azure --object-id 6f0c1a2e-0000-0000-0000-000000000000
# Remove a replica you run
$seal revoke enclave azure --object-id <the replica's managed identity object id>

Remove the grant even if you disable the identity at your cloud. A disabled Azure managed identity can work for up to 24 hours on tokens it already has.

How fast it takes effect#

The admin mechanisms narrow access, so they apply once logged. Within about 30 seconds, every replica cuts the affected sessions and connections, even mid-transaction.

Seal's servers can't forge your state. They could serve an older one until its freshness statement runs out, 24 hours by default. Shorten it:

Terminal
$seal settings freshness window 1h

Rotate a key#

  1. Create a new key at the provider, with the same permissions or fewer.
  2. Seal it and replace the old blob.
  3. Restart your apps, or let reload_with pick it up.
  4. Revoke the old key at the provider.

reload_with rereads the blob. On Expired, the SDK calls it and restarts the session. Go has neither this nor on_reseal yet.

Python
with seal.session(current_blob(), kind="http", reload_with=current_blob) as s:
    ...

Tenant key versions#

seal settings tenant-key bump starts a new version and breaks nothing. A session on an older blob hands your on_reseal callback a copy under the new version. Store it. Once they've moved, --retire-older makes every older blob fail with Expired. It ends good blobs too, so reseal those first.

After a suspected compromise#

An attacker on your server couldn't read the key, only use it through the enclave.

  1. Remove the server's grant with seal revoke app. If the identity is shared, remove it anyway and grant healthy servers a new one.
  2. Read what it did on the Telemetry page, or with seal telemetry --since <time>.
  3. Delete any keys, users or tokens at the provider you don't recognise.
  4. Rotate the key if the logs are unclear.
  5. Rebuild with a new identity. Tighten network rules, --deny paths and the key's permissions.

For a lost admin key, see Admins and changes.