The short version
Warrant holds a payment until the thing it was promised for has been checked. Doing that honestly means keeping a record of what was checked and what was found, because that record is what a person reads when they decide whether to pay.
Three things are worth knowing before the detail:
- Warrant does not store the deliverable. The check runs against the response, and what is kept is a SHA-256 hash of it plus one line per clause saying whether that clause passed. The body itself is not written to our database.
- A settled warrant gets a public receipt. Anyone with the link can read it, without an account. It is designed to be anchored on a public chain, and once that is live the record cannot be withdrawn by us or by you.
- Evidence is not yet expired on a schedule. The column exists and nothing populates it. See Retention, which says plainly what that means today.
Who we are
Warrant is the controller for the data described here. Contact legal@gowarrant.xyz. A postal address and the registered entity go in this section before this document is finalised; that is a gap in this draft, not an omission in the product.
What we collect
Your account
You sign in through Privy, using an email address, a wallet, or a passkey. We store:
- your user id, the email address Privy returns, and a display name if you set one
- the Privy identifier that links the two, so signing in with the same email twice reaches the same account
- your role in each organisation you belong to, and when you joined it
We never receive or store a password. If you sign in with a passkey we store the credential's public key, its identifier, its signature counter and a label you choose. Biometrics never leave your device and are never transmitted to us.
Your session
A browser session is an opaque 32-byte random token. We store only its SHA-256, so a copy of our database does not hand anyone a live session. The row also holds the organisation, the user agent string, and an expiry. Sessions last 12 hours and end early when you sign out.
Your organisation
Name, slug, environment, whether the kill switch is on, and the amount above which a settlement requires a passkey confirmation.
Agents and API keys
An agent record holds the name you gave it, the identity string you registered (a DID or handle), an optional public key, and its failure budget and current failure count. An API key is stored as a SHA-256 hash with its prefix and last four characters — enough to recognise a key in a list, never enough to use one.
Warrants
The amount, the asset, the payee, the deadline, the specification of what had to be true, a hash of that specification, the current state, and the timestamps for each transition. Plus the double-entry ledger rows behind every movement.
Evidence
This is the part worth reading closely.
When a check runs, the deliverable is fetched and evaluated. What we write to the database is:
- the source URL that was fetched
- a SHA-256 hash of exactly what was observed
- the size in bytes
- a preview, which is one line per clause in the form
data.freshness: stale_evidence— the clause kind and its verdict - an optional attestation reference from the confidential compute environment
The preview is generated from the verdicts, not from the payload. It is not a truncation of the response and not a redaction of it: the response body is never a source for that field. This matters because a deliverable often belongs to a third party — an invoice, a customer record, a dataset you bought — and Warrant is not a copy of it.
The hash is one-way. It lets a receipt prove that a particular set of bytes was checked; it cannot be reversed into those bytes.
Activity and logs
Every action that changes state writes an audit row before it executes: the action, the entity, who did it (a user id, an agent key id, or the system), and a small metadata object holding state transitions, amounts and reason codes. It is not a place we put message content or personal data.
Our hosting and database providers keep their own operational logs, which include IP addresses. Those are theirs, retained on their schedules, and listed under Processors.
Warrant does not currently record a per-request log of its own. The console says so on its Request logs screen rather than showing an empty table.
Cookies and local storage
One cookie: warrant_session, on the console's own origin. It is httpOnly, SameSite=Lax, and Secure in production. It carries the session token and nothing else. It is strictly necessary for signing in, so it does not require consent, and there is no consent banner because there is nothing else to consent to.
Two local-storage keys, both preferences and neither an identifier: warrant.theme and warrant.tour.seen.
There is no analytics on any Warrant surface. No Google Analytics, no Segment, no product analytics SDK, no third-party pixels, no session recording. If that changes this document changes first.
The trace is public and permanent
When a warrant settles, Warrant writes a trace: a record of what was checked, what was found, what was decided, and the amount. Every settled warrant has a permalink at gowarrant.xyz/t/<warrant id> which anyone can open without an account.
The receipt shows the amount, how much was paid, the payee, the clauses that were checked, and the settlement record itself. It does not name your organisation and it does not name any person: the actor's user id is stripped before publication, and the response says which fields were withheld.
Two limits you should understand before you use this in production:
- The payee is on the receipt. If a payee string is itself sensitive — a person's name rather than a service hostname — that is published. Use a service identifier, not a person.
- Anchoring is not live yet, and when it is, it is permanent. Today the receipt is served from our database, so we can still change or remove one. The design anchors the trace hash on Rialo, a public chain. Once that ships, the anchor cannot be deleted, edited or withdrawn — not by you, not by us, not in response to a legal request. Deleting your account will not remove it.
Unsettled warrants are never published. A request for a warrant that is still held, still verifying, or that does not exist returns the same "not found", so the endpoint cannot be used to discover which warrants are real.
Lawful basis
Where the UK GDPR and EU GDPR apply:
- Performance of a contract for your account, your organisation, your warrants, and the evidence and traces that make conditional release work. You cannot have a payment released on proof without a record of the proof.
- Legitimate interests for security, abuse prevention, rate limiting and service operation. Our interest is running a payments system that does not lose money or leak; we have kept collection to what that requires.
- Legal obligation where financial or accounting record-keeping applies.
We do not rely on consent for anything currently collected, because nothing currently collected is optional. We do not sell personal data and we do not use it for advertising.
Processors
| Processor | What it handles | Where |
|---|---|---|
| Vercel | Hosting for the site, console and API; edge and function logs | US / global edge |
| Neon | The Postgres database: accounts, warrants, evidence, ledger, audit | Region chosen at provisioning |
| Upstash | Redis for rate limiting, QStash for the verification and webhook queues | Region chosen at provisioning |
| Privy | Sign-in with email, wallet or passkey; holds the identity, not our session | US |
| Rialo | The public chain the trace is anchored to. Not yet live | Public and permanent |
RESEND_API_KEY is present in our configuration for transactional email. No code currently sends email, so Resend processes nothing today. It is listed here so this table does not become wrong the day it does.
Each processor is bound by its own terms; a data processing agreement with each is part of finalising this document.
Retention
Being exact about this matters more than sounding tidy.
| Data | How long |
|---|---|
| Account and membership | While the account exists |
| Session rows | Expire after 12 hours; rows are not yet purged after expiry |
| WebAuthn challenges | 5 minutes, consumed on use |
| Evidence hash and preview | Not currently expired. See below |
| Warrants, ledger, decisions, audit log | Kept as the financial record |
| Traces | Kept, and permanent once anchored |
| Idempotency keys | Kept; not yet pruned |
The evidence gap, stated plainly. The evidence table has an expires_at column, and the schema comment says the hash should outlive the body. No job populates that column and no job deletes on it. So today an evidence row — source URL, hash, size, and the per-clause verdict preview — persists for as long as its warrant does.
That is a smaller exposure than it sounds, because the row never contained the deliverable. It is still not what the schema intends, and a retention job is required before this document is finalised. It is called out here rather than papered over with a number that nothing enforces.
Warrants, ledger entries, decisions and the audit log are deliberately not deleted on request. They are the record of money moving, and a payments system that can be asked to forget a settlement is not one anyone should use.
Your rights
Where the UK or EU GDPR applies you can ask for access, correction, deletion, restriction, portability, or object to processing based on legitimate interests. Write to legal@gowarrant.xyz and we will respond within one month.
Two honest limits:
- Deletion does not reach the financial record or an anchored trace. We will delete your account, your profile and your credentials. Warrants, ledger entries and traces stay, for the reason above; once a trace is anchored on chain, it is beyond anyone's reach including ours.
- We may not be able to identify you beyond the account you signed in with, which is by design — we hold very little about you.
You can complain to the ICO in the UK, or your local supervisory authority in the EU.
International transfers
Our processors are largely US-based. Transfers out of the UK and EEA rely on the UK International Data Transfer Addendum and the EU Standard Contractual Clauses, together with each processor's own safeguards. Naming the specific mechanism per processor is part of the legal review this draft is waiting on.
A chain anchor is not a transfer to a country. It is publication to everyone, everywhere, permanently. It is covered in The trace is public and permanent because that is the more useful framing.
Children
Warrant is a tool for businesses and developers. It is not for anyone under 18 and we do not knowingly collect their data.
Changes
Material changes will be announced to account holders before they take effect, and the Last updated line at the top of this page always reflects the current version.