ZIFFER home

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

#WhatWhy
1.1The signed agreement.Nothing below is minted before it.
1.2Your 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.3The 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.4Your 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.5Your 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.6An 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.7The 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.8Optional: 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

#WhatHow it reaches you
2.1Three 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.2Your 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.3Your 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.4Your admin certificate, used only to invite approvers.Out of band, to the person in 1.3.
2.5The approval page address (https://approve.ziffer.io) and the API address.In the welcome note.
2.6The guides: install.md, after-install.md, sdk.md, policy-ci.md, approvers.md, policy-by-example.md, support.md.Same note.
2.7If 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 ziffer CLI; 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; --yes takes every default and asks nothing. By hand instead: install.md sections 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) or npm install @ziffer-io/client (TypeScript). Both are at 0.1.0; install.md section 4.
  • Put the API key in ZIFFER_API_KEY, the anchor file path in ZIFFER_TRUST_ANCHOR, and your minimum signature suite in ZIFFER_SUITE_FLOOR (hybrid-ed25519-mldsa65 unless 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.md section 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.md section 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.md section 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.md section 7).
  • An approver leaves: remove their entry and their assurance line from the registry, re-sign, publish. Two commands, and approvers.md section 3 has both. Check quorum_k against 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.md section 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.io with 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 renew job alongside publish-policy.yml: confirm the scheduled run passed. Without that job, renew it by hand from the machine where the CI secrets live (install.md section 6, after-install.md section 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 move ZIFFER_CLI_VERSION and ZIFFER_CLI_SHA256 in CI as a separate, deliberate commit (after-install.md sections 1 and 6).
  • Something refused and you do not know why: support.md has 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.

On this page