seal

Security

Markdown

Telemetry

Every seal, session and request leaves a signed record your browser checks. Seal can't edit it, and can't drop it without leaving a gap.

The enclave writes this record itself, signs it and ships it every few seconds. Seal stores it but can't change it.

What the enclave records#

Each entry has the enclave's time, your tenant and the identity that acted.

Seal
Written whenA blob was sealed, with its id, destination and apps
Session
Written whenAn app started a session, with its address
Extend
Written whenThe SDK renewed a session (every 5 minutes)
End
Written whenA session ended early
Refused
Written whenThe enclave turned something down, with the full reason
Request
Written whenA request finished: HTTP method, path and status, or Postgres command kind and SQLSTATE
Integrity
Written whenAn integrity signal arrived, and what your policy did
Dropped
Written whenAn overloaded replica discarded entries, with counts

It never records your key, bodies, query strings or upstream error text. Only the enclave writes entries, so an attacker on your server can't add, change or erase one.

Callers get a short code like NotAllowed, and the full reason goes here. Common reasons are no grant, outside networks, an expired blob and stale state. The console shows each in plain words.

Signed batches and streams#

A replica signs a batch at least every 5 seconds, with a key the key guardian certified. Each start begins a new stream numbered 1, 2, 3, and a clean shutdown marks the last batch. Seal can't edit a batch without breaking its signature, or drop one without leaving a gap.

Stream started at boot
#1sig ✓
#2sig ✓
#3sig ✓
#4sig ✓
#5sig ✓
#6sig ✓
#7sig ✓
#8sig ✓

checked in this browser: 8 batches

all signatures valid · no gaps

FigureOnly the enclave holds the signing key, and it numbers every batch. Anyone in between, Seal included, can withhold batches but can't do it quietly.

Checking it#

The console's Telemetry page checks every signature in your browser and shows invalid batches and gaps. A stream that ends without a last batch when a replica restarted is normal. A gap mid-stream isn't.

Summary charts and the Usage page are counted by Seal's servers and marked unverified. Press Verify to recount from checked batches.

For a check that doesn't rely on Seal's page, use the CLI:

Terminal
$seal telemetry --since 24h --receipts receipts.jsonl --reader-key reader.key

Receipts#

A receipt proves the enclave recorded a seal or session. Keep them, and you can later prove Seal held back an entry or a whole stream.

Terminal
$seal secret --to https://api.openai.com/v1 --app checkout --receipt-file receipts.jsonl
Python
import os, seal

with seal.session(os.environ["OPENAI_API_BLOB"]) as s:
    ...
    seal.receipts.append("receipts.jsonl", s.receipts())

In Node, seal with withReceipt: true and use receipts.append.

Encrypting to your own keys#

By default Seal's servers can read your telemetry. Add a telemetry reader to encrypt entries to your own key:

Terminal
$seal settings telemetry-readers add --generate reader.key

Seal then sees only the stream, batch number, entry count and time range. Load the key in the console, or pass --reader-key to the CLI. Adding a reader is widening, so it waits out your pending window. Server-side charts can't count encrypted entries, so use Verify.

Overload#

A replica never blocks requests to write telemetry. It holds up to 10,000 unsent entries. Past that, it drops the oldest Request entries first and records the count in a Dropped entry.