Normal human approval assumes the approver is on your team and enrolled ahead of time, with a key HESO already knows. A customer is neither: there are potentially millions of them, they come and go, and you would never want to register each one with us. The client-approval model is built so the customer can still produce a real co-signature — without ever becoming a HESO account.
Three parties, three jobs
- You vouch. For a single action, you delegate the authority to approve it to a one-time key, by signing a delegation envelopewith your operator key. The envelope says “for this exact action, under this rule, this one key may co-sign.” You hold the operator private key; only its public half is registered with HESO.
- The customer co-signs. Inside the gate, the customer’s browser mints a fresh key
Kand signs the action’s exact bytes with it. That key is born and dies on their device; it never leaves the browser, and HESO never sees the private half. - HESO verifies.The cloud checks two things: that your delegation envelope verifies against your registered operator public key, and that the customer’s co-signature was made by the key
Kthe envelope named. If both hold, the action clears. HESO signs nothing.
A cleared gate proves that you authorized this exact action under a client-clearable rule, and that the holder of the gate co-signed those same bytes. It does not prove a legal identity — it proves that whoever you handed the gate to actually approved this action and nothing else. The delegation binds the co-signature to one action and one rule, so it can’t be lifted onto anything else.
Delegation, not enrollment
The customer is never enrolled. Instead, you delegate— for one action only — the right to co-sign. The delegation envelope names the action’s digest, the rule’s scope, the authorized key K, and a short expiry, and it is signed by your operator key. Because the envelope is bound to one action hash and one scope, it is good for exactly that gate and nothing more.
This is why the order matters: the envelope must name K, but Kis minted inside the customer’s browser at approve-time. So you sign the envelope after the gate tells you which key will co-sign — a two-step handshake, covered in the guide. An envelope minted for any other key fails closed.
No customer base is stored
HESO holds no directory of your customers. There is no per-customer account, no stored profile, no contact list. What HESO holds is small and public:
- Your operator public key and its allowed embed origins — registered once, public by nature.
- Per gate, a single-use bearer that lives a few minutes and is consumed on resolve.
- The resulting receipt— the action, your delegation, and the customer’s co-signature — which is exactly the evidence of what happened.
The customer’s signing key is generated and destroyed in their browser. We never receive it, store it, or link it to a person on our side. The co-signature lands in the receipt as cryptographic evidence, not as a customer record.
The floors still hold
Delegation never widens what an action is allowed to do. On submit, the backend re-derives the pinned floor from your operator-signed verb — not from anything the customer or the iframe claims — and runs verify_delegation against it. A customer can co-sign an action up to a floor you set, never past it. The dangerous-lane floors a policy can tighten but never bypass apply here exactly as everywhere else.
Re-derived on every verify
Like every HESO verdict, a client co-signature is not taken on faith. Trust level is re-computed from the signatures that actually pass: a receipt that claims L1 without a valid delegation-and-co-sign pair fails with trust_mismatch. The same Rust core runs the check on your server and in any reviewer’s browser, so the answer is byte-identical wherever it’s run.
- The action’s bytes hash to the receipt’s action_hash.
- Your delegation envelope verifies against your registered operator public key.
- The customer’s co-signature verifies against the key the envelope authorized.
Only when all three hold does the receipt stand as a co-signed, L1 action.
