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:
- For you as a subscriber: what protects your data, described accurately.
- 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.
- 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:
- You authorise a Xero connection through OAuth. Xero issues us a token set, which we encrypt before storing.
- A scheduled synchronisation reads your accounting data from the Xero API and stores it, scoped to your tenant.
- 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.
- 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.
- 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:
- your Xero token set, and
- the bank access token, where a bank connection exists.
The implementation, stated so it can be assessed rather than assumed:
| Algorithm | AES-256-GCM |
| Library | Node's built-in crypto module. No third-party cryptography |
| Key | 32 bytes, held only in platform environment configuration (TOKEN_ENC_KEY). Never in source control, never in the database, never in a log |
| IV | 12 random bytes, generated fresh for every record |
| Authentication | GCM 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:
- IP addresses in log tables are stored as salted SHA-256 hashes, not in the clear.
- Certain email addresses in log tables are treated the same way.
- The salt is held in environment configuration, separate from the data.
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:
- First open with a valid signature: we mint a random device identifier, record the binding, set an
HttpOnlycookie, and redirect to a clean path with the token removed from the URL. - Every later request: the cookie signature is verified, the binding is checked, and the request is served.
- Any other device is refused, and the refusal is logged.
- 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
- Every query, cache, index and snapshot is scoped to a single tenant. There is no shared cache, no shared index, no cross-tenant lookup path.
- We do not pool data across customers. No benchmarks, no industry averages, no product analytics built from ledger contents. This is a contractual commitment in the Data Processing Terms, not just a design choice.
- We do not use customer data to train, fine-tune, adapt or enhance any AI model, and no provider of ours does either. Also contractual.
- Administrative access is limited to named individuals, with multi-factor authentication on every platform account.
- Service credentials are scoped to their function and held in platform environment configuration only.
- Secrets never appear in source control, in a log, or in a chat message. Anything that ever appeared in a chat is treated as compromised and rotated.
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
| Obligation | Window | Owed to |
|---|---|---|
| Notify you of a breach affecting your data | 48 hours from our awareness | You, under our Data Processing Terms |
| Notify the ICO of a breach we control | 72 hours from awareness, where the breach is likely to result in a risk to individuals | The ICO, under Article 33(1) |
| Report a security incident to Xero | 24 hours | Xero, 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
- Contain — revoke credentials, revoke device bindings, disable the affected path.
- Assess — what happened, what data, how many people, what the likely consequences are.
- 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.
- 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.
- 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 will acknowledge your report within two working days.
- We will tell you our assessment and our intended fix within ten working days.
- We will keep you updated until it is closed, and credit you if you would like to be credited.
- We will not take legal action against anyone who reports a vulnerability to us in good faith, who does not access, modify or delete data belonging to anyone else, who does not degrade the service, and who gives us reasonable time to fix it before publishing.
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.
- No independent penetration test has been carried out yet. One is planned. When it is done, a summary will be available to subscribers under the audit provisions in our Data Processing Terms. We are not going to imply one exists.
- No formal certification. We do not hold ISO 27001 or SOC 2, and we do not claim to. We are a small company and those are expensive; if we get them, we will say so and you will be able to check.
- Authentication is by signed device-bound link, not user accounts. Section 4 sets out what that does and does not achieve. Sign In with Xero is the intended replacement.
- Retention periods are published policy but are not yet enforced by an automated purge. The periods are in our Data Processing Terms and we hold to them operationally; the job that enforces them automatically is on the backlog and has not shipped. We would rather say that plainly here than let you assume it is running.
- Application-level encryption covers two fields. Complaint text and bank transaction descriptions are not yet field-encrypted. Section 2 covers this.
Everything in this section is tracked and has an owner. Nothing in it is a surprise to us.
10. Contact
| Security reports | security@pocketdocket.co.uk |
| Data protection | privacy@pocketdocket.co.uk |
| General support | support@pocketdocket.co.uk |
| Post | Pocket 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