Onboarding checklist — what we need from you, what you receive, what you do
For the customer, in plain words.
For the customer, in plain words. Every item here maps to a step in our operator's
how-to and to one of the guides beside this
file: install.md, after-install.md, sdk.md, approvers.md, policy-ci.md,
policy-by-example.md, sandbox.md, support.md. Updated 2026-09-15.
ZIFFER is a gate in front of the actions your AI agent takes. Your agent proposes an action; the gate grades it against your signed policy; low-risk actions get a signed receipt at once, high-risk ones wait for a named person to approve on a page that only their passkey opens. Your code executes only what carries a receipt it verified itself. We never hold a key that can act on your systems.
Onboarding is three exchanges. Most of it is done once.
1. Before we start — send us these
| # | What | Why |
|---|---|---|
| 1.1 | The signed agreement. | Nothing below is minted before it. |
| 1.2 | Your organisation's short name: lowercase letters, digits and hyphens, e.g. acme. | It becomes your tenant id, and it is in every receipt. It cannot be renamed later. |
| 1.3 | The one person who will hold your policy signing key. Name and email. | Your policy is signed by you, on a key we never see. This person generates and keeps it. |
| 1.4 | Your approvers: for each, name, email, and whether they will approve on a phone or laptop passkey (assurance AS1) or on a hardware key (AS2). Send at least one more per role than you require to approve — if two must approve, enrol three. | Each approver registers a passkey on their own device, and only that device can approve. There is no delegation and no out-of-office: a holiday is covered by having a spare, and by nothing else (approvers.md section 3). |
| 1.5 | Your notification channel: email (we send to the addresses in 1.4), or Slack (create an Incoming Webhook in your workspace for one channel and send us its URL, plus each approver's Slack handle). | One channel per organisation. A Slack message carries a link to the approval page, never an approve button. |
| 1.6 | An on-call address for critical notices (a shared mailbox or the same Slack channel). | Some actions run without approval but must be announced to someone. An action with no addressee is refused, not executed. |
| 1.7 | The first actions to gate, in a sentence each, and the language your agent is written in (Python or TypeScript). | We draft your first policy with you from worked examples. |
| 1.8 | Optional: whether you want a sandbox tenant first (auto-approved, clearly marked, separate key). | Useful for integrating before any person is enrolled. |
2. What you receive from us
| # | What | How it reaches you |
|---|---|---|
| 2.1 | Three signed files to place beside your policy: your receipt identity, the door identities, and the attester registry to fill with your approvers. | A signed archive, out of band. |
| 2.2 | Your API key (zfr_…, 90 days by default; ask for another lifetime). The key is your tenant. | Out of band, once. Treat it like a production credential. |
| 2.3 | Your trust anchor file (anchor.json): the public half of the identity that signs your receipts. | Out of band, never over the API it verifies. |
| 2.4 | Your admin certificate, used only to invite approvers. | Out of band, to the person in 1.3. |
| 2.5 | The approval page address (https://approve.ziffer.io) and the API address. | In the welcome note. |
| 2.6 | The guides: install.md, after-install.md, sdk.md, policy-ci.md, approvers.md, policy-by-example.md, support.md. | Same note. |
| 2.7 | If requested, a sandbox tenant with its own key and anchor. | Same as 2.2 and 2.3, clearly labelled -sandbox. |
3. What you do — in this order
A. Sign your policy (the person from 1.3, about an hour the first time).
-
One command, on the machine that will hold your key (the person from 1.3, their own laptop, not a shared runner):
curl -fsSL https://github.com/ziffer-hq/ziffer-spec/releases/latest/download/install.sh | sh
It checks the prerequisites and names the missing one; verifies the release signature before it downloads any binary; installs the
zifferCLI; generates your policy signing key; installs the SDK for your language; writes the two certificate signing requests; and prints three blocks — what to send us, what to keep, and what to do every fortnight. One question per step, with the default shown;--yestakes every default and asks nothing. By hand instead:install.mdsections 1–3 are the same steps as individual commands, and its section 0 is what has to be on the machine first. Neither path is the lesser one. -
Keep the key where you keep signing keys. Never send it to us or to anyone. The installer refuses to overwrite one that already exists, and never deletes one.
-
Write your policy folder from the examples we drafted with you: which actions exist, how each is graded, which are reversible, who is told when something irreversible runs, who is woken by an alert.
-
Put our three files (2.1) beside it, unchanged.
-
Sign the folder:
ziffer sign <policy-folder> --key <your-key>. -
Send us the signed folder. We verify it, place it, and activate it. Nothing runs under a policy you did not sign.
B. Wire the SDK into your agent (a developer, an afternoon).
-
pip install ziffer(Python) ornpm install @ziffer-io/client(TypeScript). Both are at 0.1.0;install.mdsection 4. - Put the API key in
ZIFFER_API_KEY, the anchor file path inZIFFER_TRUST_ANCHOR, and your minimum signature suite inZIFFER_SUITE_FLOOR(hybrid-ed25519-mldsa65unless you have a reason). None of these belongs in your source tree. - Before every gated action, submit the proposal and verify the receipt yourself, then branch on the result. An action without a verified receipt does not run.
sdk.mdsection 4 shows the shape; section 5 lists every refusal and what it means. - Make your execution idempotent on your own key: a receipt is single-use, and a retry must not act twice.
- Keep every receipt somewhere you can produce it later.
C. Enrol your approvers (the person from 1.3, five minutes per approver; the approver, thirty seconds).
- For each approver, run the invitation command with your admin certificate (
approvers.mdsection 2). It prints one link, single use, valid 24 hours. - Send the link yourself, on a channel you trust. We do not send invitations.
- The approver opens the link on the device they will approve with, presses Register this device, unlocks it. The page shows the line their key produced.
- Add that line to your attester registry, re-sign the policy (step A), send it to us. An approver is not an approver until your signed policy names them.
D. First gated action, together (thirty minutes, on a call).
- Your agent proposes a low-risk action: a receipt comes back at once and your code verifies it.
- Your agent proposes a high-risk action: the approver receives the notice (email or Slack), opens the link, unlocks with their passkey, reads the summary, approves. Your agent receives the release and executes.
- Your agent proposes something your policy forbids: it is refused by name, and nothing runs.
4. Ongoing
after-install.md is this list with the commands in it — upgrades, the renewal, both rotations, backups, uninstall, and how to re-verify at any time that the binary on your machine is the one we published. The items below are what to put in a calendar; that chapter is what to run.
- Key rotation, before the expiry date the API tells you on every call: ask for the successor, deploy it, confirm traffic, then ask us to revoke the old one. Never the other way round.
- Policy signing key lost, replaced or exposed: generate a new key, send us its public document on the channel you were onboarded on, and re-sign your current policy with it at a higher epoch. We enrol the new key and confirm; then you publish. Nothing you already published stops being valid and your epoch does not reset.
policy-ci.mdsection 6 has the four steps, and tell us first if the key was stolen rather than lost. - Policy changes: edit, re-sign, publish from your own CI. Every change is a new signed bundle, and it is in force when your workflow prints
active— seconds, not an operator's working hours (policy-ci.mdsection 7). - An approver leaves: remove their entry and their assurance line from the registry, re-sign, publish. Two commands, and
approvers.mdsection 3 has both. Checkquorum_kagainst who is left before you publish. - Lost or replaced approver device: remove their line from the registry and re-sign; invite them again on the new device (
approvers.mdsection 5). - Tell us when an approver's email address or your Slack channel changes. The recipients book is ours, not part of your signed bundle: you cannot change it yourself, and a notice sent to an address nobody reads is an approval request nobody answers. Write to
hello@ziffer.iowith the person's name and the new address, or the new webhook URL, and we re-place it. There is nothing to publish and no epoch to spend. - The CI certificate renews itself every fortnight, if you copied in the
renewjob alongsidepublish-policy.yml: confirm the scheduled run passed. Without that job, renew it by hand from the machine where the CI secrets live (install.mdsection 6,after-install.mdsection 3). A leaf that expires cannot be renewed at all, and the fix is a new certificate signing request. - Upgrade the CLI when a release notice says to, with
install.sh --upgrade, then moveZIFFER_CLI_VERSIONandZIFFER_CLI_SHA256in CI as a separate, deliberate commit (after-install.mdsections 1 and 6). - Something refused and you do not know why:
support.mdhas the two addresses, the severities, and a row for every refusal.
5. What this does not do — read once
- It does not execute anything. Your code does, only with a receipt it verified.
- It does not filter or judge your model's output. The policy grades actions, not text.
- It does not send invitations, hold your signing key, or hold your approvers' passkeys.
- A stolen API key can propose actions as you and read your decisions. It cannot approve, release, change policy, or act on your systems.
Synced from ziffer docs/onboarding/customer-checklist.md at 32bc4db; edit the source, never this page.