Pocket Docket — legal

Security statement

Pocket Docket Ltd · company number NI742827 · registered in Northern Ireland · registered office 137 York Road, Belfast, BT15 3GZ


What this document is

Pocket Docket reads your accounting data. That is a lot of trust to ask for from a £24-a-month product, so this page sets out what actually protects it — in enough detail that your IT person, your accountant or your solicitor can judge it rather than take our word for it.

It has three audiences and does three jobs:

  1. For you as a subscriber: what protects your data, described accurately.
  2. For your data protection file: this is the "information necessary to demonstrate compliance" that Article 28(3)(h) UK GDPR requires us to make available to you as your processor. You should not need to send us a questionnaire.
  3. For Xero and for prospects doing diligence: the security posture, stated once, in writing.

One rule governs this page: it describes what the product does today. Where something is planned but not built, it says so. A security page that overstates is worse than no security page — it is the first thing an investigator tests after an incident, and the first thing that gets found in diligence.


1. Architecture and hosting

Pocket Docket is a Next.js application running on Vercel, with a managed Supabase Postgres database. Billing runs through Stripe. Transactional email goes through Resend. The assistant runs on Anthropic's Claude API. The full list, with what each provider receives and where it sits, is on the sub-processors page.

The data path, end to end:

  1. You authorise a Xero connection through OAuth. Xero issues us a token set, which we encrypt before storing.
  2. A scheduled synchronisation reads your accounting data from the Xero API and stores it, scoped to your tenant.
  3. Figures are computed in our own code. Cash position, aged debt, margins, debtor days — all calculated by tested application code, not by a language model.
  4. When you ask Kipp a question, the computed figures relevant to that question and the question itself are sent to the Claude API. Your ledger is not sent. Your contact list is not sent.
  5. The answer comes back and is displayed to you. Nothing is sent onward.

The design point worth understanding: the model explains numbers, it does not produce them. That is primarily an accuracy decision — a language model should not be doing arithmetic on your VAT. But it also sharply limits how much personal data ever leaves our systems.


2. Encryption — precisely what, and precisely how

In transit

TLS 1.2 or higher on every connection: your browser to us, us to Xero, us to Anthropic, us to the database, us to every provider. No exceptions, no downgrade path.

At rest — the two fields we encrypt ourselves

Two fields are encrypted at application level, above whatever the database does:

The implementation, stated so it can be assessed rather than assumed:

AlgorithmAES-256-GCM
LibraryNode's built-in crypto module. No third-party cryptography
Key32 bytes, held only in platform environment configuration (TOKEN_ENC_KEY). Never in source control, never in the database, never in a log
IV12 random bytes, generated fresh for every record
AuthenticationGCM authentication tag, prepended to the ciphertext. Tampered ciphertext fails to decrypt rather than decrypting to garbage

These are the credentials that would let someone read your Xero organisation. They get the strongest treatment we apply.

At rest — everything else

Everything else in the database — your accounting snapshots, computed figures, contact records, enquiry details — relies on Supabase's disk encryption, including backups.

That is a real control and it is the same control most SaaS products rely on. But we want you to understand its limit: disk encryption protects against someone getting hold of the physical storage. It does not protect against an attacker who has valid database credentials, because to that attacker the data is already decrypted.

We are stating this plainly rather than writing "all data is encrypted at rest" and letting you assume more than is true.

What is planned

Application-level field encryption for two further categories: complaint and support text, and bank transaction descriptions, which are the two places where free-text personal detail is most likely to accumulate. Both are on the security backlog and neither is built. When they ship, this section will be updated and dated.


3. Hashing in logs — hash, don't store

Security logs create a data protection problem of their own: you build a log to protect people, and the log becomes another store of personal data about them.

Our approach is to log the fact and not the identifier:

This still does the job. We can tell that the same address appeared twice, that a request came from an address we have refused before, and that a pattern is a pattern. We cannot look up who a given entry belongs to, and neither can anyone who obtains the log.

Device identifiers are randomly generated 256-bit values that we mint. They are explicitly not device fingerprints. We do not fingerprint browsers. A random value is stronger than a fingerprint, does not break when a browser updates, and does not require us to profile your device to work.


4. Access control and the device-binding model

How dashboards are reached

Dashboards are reached through an HMAC-signed link. The signature proves the link was issued by us and has not been altered. Any tampering — a changed tenant identifier, a changed character — fails the signature check.

Why a signature is not enough on its own, and what we did about it

A signature proves the link is genuine. It does not prove who is holding it. Links get forwarded, screenshotted and left open on shared screens.

So the link binds to the first device that opens it:

  1. First open with a valid signature: we mint a random device identifier, record the binding, set an HttpOnly cookie, and redirect to a clean path with the token removed from the URL.
  2. Every later request: the cookie signature is verified, the binding is checked, and the request is served.
  3. Any other device is refused, and the refusal is logged.
  4. The binding can be revoked from the admin console — for a lost phone, a departing employee, or a client who needs to move device.

The token leaves the URL at first use. This matters: an access token in a query string on a page that returns HTML can leak through the Referer header. The redirect closes that. (Nothing in our application loads from a third-party origin in any event — see section 6 — so there is nowhere for a Referer to leak to. Both controls exist because one of them should not have to be relied on alone.)

The gate is the API, not the page

The device binding is re-checked server-side on every data API call, not just when the page renders. A page-only check is defeated by copying the API request and replaying it. Every route that returns your figures performs the check itself.

Refusals reveal nothing

Every refusal — invalid signature, expired link, already-used token, wrong device, revoked binding — renders the same generic page. No tenant name, no figures, no reason, no distinction between "this link is wrong" and "this link is right but you are the wrong device.

Anything that distinguishes those cases is an oracle: it lets someone probe for which links exist. One page, one message, nothing learned.

The honest limit

No web application can make a URL unforwardable. What this model achieves is that forwarding stops being silent and becomes a refused, logged, revocable event — which is the control that actually matters.

The full answer is proper authentication (Sign In with Xero), which is on the roadmap and is a larger build with a certification dependency. We are not going to describe the current model as something it is not while that work is outstanding.


5. Least privilege and tenant isolation


6. Standing engineering rules

These are constraints we hold to across the codebase, not preferences. They exist because each one removes a class of problem rather than handling it case by case.

Access controls fail closed. Instrumentation fails open. If an access check errors — the binding lookup fails, the database is unreachable — the request is refused and the error is logged. If a usage counter or a rate-limit tracker errors, it is allowed through. Getting these two the wrong way round is how outages become breaches, and how monitoring failures become outages.

Nothing loads from a CDN. No third-party fonts, scripts, styles, images or pixels. Everything is served from our own origin. This means: no third-party can see your traffic, there is no supply-chain path through a compromised CDN asset, and there are no third-party cookies to disclose because there are no third-party requests to set them.

Card details never touch Pocket Docket. Payment is by Stripe's hosted checkout. Card numbers are entered on Stripe's page, not ours. We never see, transmit or store a card number. We see that a payment succeeded, the last four digits, the brand and the expiry — enough to show your billing history and chase a failed payment.

The assistant drafts; a human sends. Kipp produces drafts only — draft invoices, draft chasing emails. Nothing is approved, sent, paid or posted without a person acting. There is no autonomous write-back path and no "send automatically" setting. This is a hard gate.

One write permission, and one only. At your request, the Service can create a draft invoice in your Xero organisation. It cannot approve, send, edit or delete anything, and it cannot move money. You can verify this yourself in Xero's connected-apps screen in about fifteen seconds, which is exactly why the claim has to be accurate.

You can cut us off without asking us. Xero → Settings → Connected Apps → disconnect. Immediate, unilateral, no support ticket. We think an access model you can end yourself is worth more than a promise that we would end it if asked.


7. If something goes wrong

The clocks

ObligationWindowOwed to
Notify you of a breach affecting your data48 hours from our awarenessYou, under our Data Processing Terms
Notify the ICO of a breach we control72 hours from awareness, where the breach is likely to result in a risk to individualsThe ICO, under Article 33(1)
Report a security incident to Xero24 hoursXero, under its developer terms

The 48-hour commitment exists to make your own 72 hours workable. Article 33(2) gives a processor no fixed window — the duty is simply "without undue delay" — which in practice means the controller can be told at hour 71 and have no time left. We have committed to a fixed 48 hours instead.

What we do

  1. Contain — revoke credentials, revoke device bindings, disable the affected path.
  2. Assess — what happened, what data, how many people, what the likely consequences are.
  3. Notify — you within 48 hours, with what we know at the time and follow-ups as we learn more. We would rather send an incomplete notification on time than a complete one late.
  4. Where we are your processor, we do not notify the ICO or your customers on your behalf. That decision is yours, and we will give you what you need to make it.
  5. Remediate and record — fix, and write it down.

Awareness

We treat ourselves as aware of a breach when someone with security responsibility has reasonable confidence one has occurred — not when the investigation concludes. Waiting for certainty is how 72-hour duties get missed.


8. Reporting a vulnerability

If you find a security problem in Pocket Docket, please tell us.

security@pocketdocket.co.uk

Please include what you found, how to reproduce it, and how we can contact you. If you would like a PGP key, ask and we will provide one.

What we commit to:

We do not run a paid bug bounty. We would still rather hear from you.


9. What is not yet in place

Every security page should have this section, and most do not.

Everything in this section is tracked and has an owner. Nothing in it is a surprise to us.


10. Contact

Security reportssecurity@pocketdocket.co.uk
Data protectionprivacy@pocketdocket.co.uk
General supportsupport@pocketdocket.co.uk
PostPocket Docket Ltd, 137 York Road, Belfast, BT15 3GZ

Version 1.0 · in force from 21 August 2026

© 2026 Pocket Docket Ltd · Registered in Northern Ireland, company number NI742827 · Registered office: 137 York Road, Belfast, BT15 3GZ · ICO registration ZC223982