FR EN

The consent lifecycle

A consent in Agreely moves through five stages, each a distinct artifact. The company issues an offer, the person approves it with a passkey, that answer becomes a receipt, the receipt updates a single enforcement record, and your code reads that record on every use. The whole point is that each stage leaves proof, so the final check is not a bare boolean but the tip of a verifiable chain.

1. Offer

The company issues a signed consent request for a set of catalog cells, delivered to the person as a secure deep link. The offer is signed by the company's DID key and commits to a Merkle root over the exact (category, purpose) cells being requested, so the person approves precisely what was offered and nothing can be swapped in afterward.

2. Passkey approval

The person approves per-cell in the citizen portal with a WebAuthn passkey. The passkey signs a challenge bound to the offer's Merkle root, which is what ties a specific human's authenticator to a specific set of cells at a specific moment. Approval is granular: a person can approve some cells of an offer and decline others.

The passkey signs the root, not the plaintext

The challenge the passkey signs is bound to the offer's Merkle root. That is enough to prove the person approved exactly those cells, and it means the citizen side never has to hold the company's plaintext customer identifier to produce a valid approval.

3. ConsentReceipt

The approval becomes a ConsentReceipt, a W3C Verifiable Credential that carries both the company signature and the citizen's passkey assertion. This is the portable, independently verifiable record of what happened. Anyone holding it can verify the receipt without trusting Agreely.

A manual or offline consent, where a person signs on paper rather than in the portal, instead yields a company-attested receipt. It carries the company signature alone: the company attests that it holds a hand-signed document whose hash matches. It does not carry a passkey assertion, and it does not prove a human signed. A verbal consent, given by telephone, yields a weaker receipt still, documented by the company: it names the version of the script read and carries no document digest, because there is no document. See assurance tiers below.

4. Enforcement record

The receipt updates a single authoritative enforcement record, keyed per cell and carrying a consent_ref, a status, and an assurance_tier. This is the row a check reads. It is keyed by the company's own plaintext customer_id, and no citizen DID is ever written here. That separation is what keeps the company side and the citizen side from being trivially joined; see unlinkability.

5. The /v1 check

Your code calls the synchronous /v1 check, a default-deny read of exactly that enforcement status. A withdrawal flips the record to revoked, and the very next call denies, with no chain wait. The chain is never read on this path; the enforcement record is authoritative the instant a grant or withdrawal commits.

The response carries the consent's end, validUntil, and, after a withdrawal, revokedAt, the instant from which Agreely treats the consent as withdrawn. For a box left blank on a signed paper it is the signature date; for a withdrawal recorded through /withdrawal or /revoke it is the moment it was recorded, not necessarily when the person expressed it: stop the use as soon as the person asks, and record the withdrawal without delay. validUntil is an upper bound: a withdrawal ends the consent earlier, and only a system that checks again learns it. So never cache a check.

A consent is never rewritten. When it is renewed or confirmed, a new consent takes over for the same purpose, and the check follows it at once; the old one stays recorded as it was. Three cases form such a chain:

  • a new sheet signed on paper takes over a sheet or a call still in force for the same purpose;
  • the signed paper that comes back after a call confirms the verbal consent: its ticked purposes move into a new company-attested consent, dated from the call;
  • a call may renew a sheet whose end falls within 30 calendar days. Those 30 days are an Agreely product rule, not a period set by law.

A link may not end before the one it takes over: Agreely treats a shorter consent as a withdrawal, recorded as such. A passkey-signed consent is never renewed by telephone; it is renewed with a new online request.

A withdrawal attaches to the purpose

A withdrawal does not target one isolated record, it targets the purpose. Withdrawing through any reference in the chain (the renewal or the sheet it renews, the call or the sheet that confirmed it) withdraws the running consent at the same instant, and the check denies from the next call. A consent dated before a withdrawal recorded for the same purpose never reopens it.

A withdrawal always remains possible:

  • after the relationship ended, because the right to withdraw outlives the relationship;
  • during a billing lapse: the /v1 withdrawal route is the only one that never answers 402, because honoring a withdrawal is a duty, not a paid service. Every other route refuses until billing is restored.

A withdrawal the organization records on the person's behalf is the organization's attestation, never the person's signature: its response says so (recordedOnBehalf: true, assurance: "company_attested").

Assurance tiers

Two vocabularies describe how a consent was obtained. Map them, do not mix them. /v1/check returns both: tier and assurance.

  • full maps to citizen_signed: the consent was approved by passkey in the portal.
  • manual maps to company_attested: it was signed by hand on a sheet, recorded by the company.
  • verbal maps to company_documented: it was given by telephone and documented by the company, with no document at all.

The order of strength is full > manual > verbal. A client that only knows the first two assurance values must treat an unknown value as not acceptable.

All three tiers enforce identically

A citizen_signed consent carries the person's passkey assertion. A company_attested consent is the company's attestation that it holds a hand-signed document whose hash matches, and it does not prove a human signed. A company_documented consent records the company's statement that a call took place, and does not prove the call. At check time all three enforce exactly the same way: only the tier differs, so your system judges how strong the proof is and decides what each tier unlocks.

Next