# Admins and changes

Admin keys sign every change to your tenant. Changes that widen access wait in public first, so a bad one can be caught and cancelled.

Source: https://seal.zone/docs/changes

Your tenant's rules live in one signed document. Only your admins can sign it, not the console or Seal.

## Admin keys

An admin key signs changes. There are two kinds:

- **Passkey.** On your device or password manager. You sign in the console. Seal accepts passkey signatures made only on `seal.zone` or `console.seal.zone`.
- **Key file.** An Ed25519 key on disk, used from the CLI. Guard it like a root SSH key.

```shell
seal key create --out admin.key
seal key public admin.key
```

Add a second key now. If you lose your only one, nobody can change your tenant again, Seal included. The fix is a new tenant and resealed keys.

```shell
seal settings admins add <public key>
seal settings admins threshold 2
```

The threshold is how many keys each change needs. For production, keep two keys on different devices and set it to 2.

## Your tenant's state

The state is what every replica obeys. It holds your apps with their identities and network rules, deployments, platforms, both windows below, integrity policy, telemetry readers and tenant key versions. Admin keys and the threshold live in a second document, the root.

Every version goes into the [transparency log](https://seal.zone/docs/releases). Replicas fetch the latest about every 30 seconds.

## Making a change

A change starts as a proposal. Once enough admins sign, it goes to the log. CLI commands show the difference, then open the console for passkey signing.

```shell
seal grant app checkout azure --object-id OID --entra-tenant TID --audience api://seal-acme
```

Add `--key-file admin.key` to sign locally. `seal changes` lists open proposals.

## Narrowing and widening

Narrowing changes apply once logged and reach replicas within about 30 seconds. Widening changes wait out your pending window. Anything not provably narrowing counts as widening, and a mixed change waits as a whole.

| Narrowing (applies now) | Widening (waits) |
|---|---|
| Remove an app or identity | Add an app or identity |
| Remove a deployment or platform | Add a deployment or platform |
| Retire old tenant key versions | Add a telemetry reader |
| Raise the threshold | Add or remove an admin key, or lower the threshold |
| Add an app's first network rule | Add a network to a rule, or remove the rule |
| A harsher integrity action | A softer integrity action, or clearing a suspension |
| Lengthen the pending window, or shorten the freshness window | Shorten the pending window, or lengthen the freshness window |

## The pending window

The pending window is how long a widening change waits in public, from 0 to 24 hours. The console calls it "Risky changes". New Developer tenants start at 0, so set one before production.

```shell
seal settings window 6h
```

The log's witnessed clock times it, so Seal can't end it early. It can end up to about 90 seconds late.

Any admin can cancel a pending change with **Cancel pending** on the Changes page, or with any narrowing change from the CLI. Cancelling also needs your threshold.

`seal changes --watch` on a machine you control checks pending changes against the log itself. `--once` exits with code 3 if something is pending. Console emails aren't proof.

## Freshness

A replica only acts on a state the log recently confirmed is the newest. That stops anyone, Seal included, replaying old rules. An old state stops working 24 hours after a newer one exists, or as little as 5 minutes if you shorten the window.

```shell
seal settings freshness window 1h
```

If the log or control plane is unreachable for longer, every call fails with `Unavailable`.
