Whitepaper
Security whitepaper
By Caleb. Last updated 2026-05-11.
1. Why this exists
Pelicart is a stranger asking for your Woolworths login. That is a real request, and it deserves a real explanation. Most companies answer with a logo wall of compliance badges. We are too small for that to mean anything yet, so this document answers in plain English instead.
I have written this for two readers. The first is my mom, who wants to know whether her shopping is safe. The second is the technical reader who wants to know what could go wrong, and what I am doing about it. The sections below try to satisfy both, starting with how Pelicart works and ending with how you can verify any of it.
2. What Pelicart actually does
Pelicart is a small program that reads the WhatsApp messages you send it, asks a language model what you want, and uses your saved Woolworths login to add things to your cart. Once the cart is ready, it tells you to open the Woolworths app and pay there. That is the whole loop.
The language model is Claude, made by Anthropic. I picked it because it is good at understanding ordinary South African English and the kinds of casual lists people actually send friends. When Claude decides what to do, it can only do one of a handful of things: search the Woolies catalogue, add an item to your cart, remove an item, change the delivery address, or show you the cart so far. It cannot place an order. The system prompt that guides Claude says so in writing, and there is no code in Pelicart that would let it do so anyway.
Everything below is a more careful look at each part of that loop.
3. Your Woolworths login
When you link your Woolworths account, you click a one-time link we send you on WhatsApp and type your Woolworths email and password into a page on our website. That page sends your password directly to the Woolworths login service (it runs on AWS Cognito, the same kind of login service many large companies use). Woolworths checks your password and sends back a session token. A session token is a long string of letters and numbers that says “the holder of this string is logged in as so and so for the next hour or so.”
We keep the session token. We never keep your password.
Before the session token reaches our database, we scramble it using AES-256-GCM encryption. That is the same kind of encryption banks use to store sensitive data. A separate secret key, which lives only on our hosting platform and not inside the database, is needed to unscramble the token again. When the token gets close to expiring, we silently swap it for a fresh one and re-encrypt it.
The one-time linking link is single-use. Once you have logged in, the link is deleted, so even if someone found the URL afterwards they could not use it.
4. Checkout, and why we never see your card
Pelicart has no code that finalises an order. The assistant can put things into your basket, and it can remove them, but when you say you are ready to check out, the only thing it can do is tell you to open the Woolworths app on your phone. You then review the cart we built, choose your delivery slot, and pay on the card you have already saved with Woolworths.
Your card never reaches our servers. Woolworths charges you on its own payment system. We do not see the card number, we do not see the transaction, and we do not move money anywhere. If the cart is wrong, you remove the wrong thing inside the Woolies app before paying. The assistant is explicitly told, in its instructions, that it cannot claim to check out or pay for you.
5. Your messages, end to end
Here is the path a single WhatsApp message travels through Pelicart, in order.
- You type a message on WhatsApp and send it. WhatsApp belongs to Meta, so Meta receives it first.
- Meta forwards the message to our server at a special address called a webhook. Before we accept the message, we check a cryptographic signature Meta attaches to every request. The signature uses a secret only Meta and we know, so if anyone else tried to send a fake message pretending to be Meta, the signature would not match and we would throw it away.
- We save the message in our database, alongside your previous messages, so the assistant remembers context.
- We hand the recent conversation to Claude, the language model from Anthropic, by calling Anthropic’s API directly.
- Claude reads the conversation and picks a single action to take: search the catalogue, add an item, remove an item, set the address, or open the cart. Pelicart runs that action against Woolworths and feeds the result back to Claude. Claude can run a few of these actions in a row before it has something to say back to you.
- When Claude is ready with a reply, Pelicart sends it back through Meta’s WhatsApp Business API to your phone.
We keep a rolling memory of about a hundred recent messages so the assistant feels continuous, and we expire it after seven days. A longer audit log of every message exists during beta so we can debug failures. Section 10 explains what we plan to do with that audit log as we grow.
6. In theory, what Pelicart staff can do
I want to be straight with you about what the people running Pelicart can see. Right now there is one of us, and that is me, Caleb.
Through the admin dashboard, I can read your conversation with the assistant. I use this during onboarding to make sure the link works, and I use it when you ask me for help. I see your first name, your phone number, the messages you have sent, and the cart Pelicart loaded for you.
I also hold the secret key that unscrambles your stored Woolies session token. That key sits on our hosting platform as an environment variable. If I wanted to, I could take your encrypted token out of the database, unscramble it with that key, paste it into a browser, and be logged in as you on Woolworths until the token expires. From there I could browse the catalogue and change what is in your cart. I have no reason to do that, and the rest of this document explains the limits that would still apply to me even if I tried.
The point of this section is that you should know I could in theory be a bad actor, the same way the person who runs your corner shop could in theory water down the milk. The protection against that is the same as it has always been: reputation, the law, and the next section, which explains what I still could not do.
7. What Pelicart cannot do, even if it wanted to
The things in this section are not promises. They are architectural facts about how Pelicart and Woolworths are built. Even if I went rogue tomorrow, none of the following are available to me.
- I cannot see your bank account. Pelicart never connects to a bank.
- I cannot see your card. Your card sits inside the Woolworths app on your phone. Pelicart talks to Woolworths the way a logged-in browser does, and a logged-in browser cannot read a saved card.
- I cannot place an order. The Pelicart codebase has no checkout step. The agent is instructed to refuse to claim it can.
- I cannot pay anyone with your money. Pelicart has no payment integration. There is no Stripe, no PayPal, no bank API. There is nothing in our system that can move funds.
- I cannot change your Woolworths password. The session token Woolworths gives us cannot reset credentials. That requires your password, which we do not have.
- I cannot read other Woolworths shoppers’ baskets. Your session token only authorises me to act on your account. Other accounts are sealed off from each other by Woolworths.
8. Third parties, in detail
Pelicart sends some of your data to a small list of other services so that the product can actually work. Here is who, what they see, why they need it, and how long they keep it.
Meta, via the WhatsApp Business API
Meta receives every message you send Pelicart, and every reply we send back. They have to, because they are the company that runs WhatsApp. Meta’s own privacy policy governs that traffic. Pelicart does not have any extra agreement with Meta beyond signing up for their Business API.
Anthropic
Anthropic runs Claude, the language model that decides what to put in your cart. Each time a message arrives, we send Claude the recent conversation as context. We talk to Anthropic’s API directly. By default Anthropic keeps API traffic for around thirty days so they can investigate abuse. We do not currently have a Zero Data Retention agreement with them, which would shrink that window to zero. I plan to ask for one as the user base grows.
PostHog
PostHog is our observability tool. It captures detailed traces of the assistant as it runs, including the text of your messages and the tool calls Claude made. We use those traces to find and fix bugs during beta. This is the most data-sensitive third party in our stack today, and I want to be honest that the traces are not redacted yet. I plan to redact message content in production traces after beta. If this matters to you and you want it switched off for your account in the meantime, email me.
Convex
Convex is the database where your account, your messages, your saved addresses, and your encrypted Woolies token live. Convex encrypts data at rest on its own infrastructure as a baseline, and we add a second layer of AES-256-GCM encryption on top of the Woolies token specifically, using a key Convex does not hold.
Vercel
Vercel hosts the website you are reading right now and runs the Pelicart server code. It sees request metadata (which page was requested, when, from what country) the same way any web host does.
Google Maps
If you ask Pelicart to deliver to a new address that Woolworths has not seen before, we ask Google Maps to convert your description into coordinates Woolworths can understand. Google Maps sees only that address, and only when you give us a new one.
Woolworths
Woolworths sees the cart Pelicart loads on your account, the same way it would see any cart you built yourself in their app. From Woolworths’ point of view, Pelicart is indistinguishable from you logging in on a different device.
9. What I do to prevent it
Most of this is unglamorous and small-team appropriate.
- Every critical account uses a long random password from a password manager, plus a hardware second factor.
- Your Woolies session token is encrypted at rest with AES-256-GCM using a key that is separate from the database.
- Incoming WhatsApp webhooks are checked against a cryptographic signature, so we reject any request that is not really from Meta.
- The one-time linking link is single-use and expires quickly.
- Code changes are reviewed before each deploy, and the shopping agent has no code path that places an order, so a bug cannot accidentally check out for you.
- Pelicart has no payment system, no card storage, and no money movement. There is nothing to steal beyond your shopping list.
10. How to verify any of this
You do not have to take my word for any of this. Book a half hour with me and I will share my screen, open the source code, and walk you through the parts of this document you are most worried about. I am happy to do this on a Google Meet, or in person at workshop17,Kloof Street, Cape Town, most weekdays.
11. Changelog
- 2026-05-11 Initial publication.