01 Three principles that guide our decisions
Good security is not a list of technologies; it is a handful of decisions repeated with discipline. Ours are these:
- The rule lives on the server, not on the screen. Hiding a button protects nothing: whoever calls our programming interface directly bypasses the screen. Every decision that matters — who sees what, who is a subscriber, how much has been used — is made on the server.
- Fail closed. When the system cannot confirm a permission, it denies. Granting access in the dark is the most expensive mistake a service holding health data can make.
- Do not keep what is not needed. The safest data is the data that does not exist. The document photo is the central example: it does its job and is discarded.
02 Protecting your account
- Passwords are stored only as a cryptographic hash — we have no way to read your password, not even to help with support.
- Sign-up is confirmed by a code sent to your e-mail, which prevents creating an account with someone else's address.
- Password reset uses a link or code with short validity and single use.
- The app session uses short-lived access tokens with automatic renewal: a captured token has a small window of usefulness.
- When you sign out, the session is also ended in connected services, such as the subscription service.
03 Per-account isolation, enforced in the database
Every Boopet table has row-level security enabled. In practice: the query the app makes arrives at the database already tied to the identity of the signed-in user, and the database returns only rows that belong to that user.
A concrete example of the "rule lives on the server" principle: the user has read permission on their own subscription row and no write permission on it. Without that, "I am a subscriber" would be one row edit away. The only thing that writes that information is the service that receives the store's confirmation.
04 Encryption
- In transit: all communication between the app, the website and our servers uses HTTPS/TLS. There is no plaintext path.
- At rest: the database and file storage are encrypted at the infrastructure provider.
- On the device: we store locally only preferences and the session token, in the operating system's protected storage. No sensitive data sits in an open file.
05 Pet photos and files
Photos live in a private bucket, not a public one. The difference matters: a public bucket means an address guessable by anyone who knows the path format.
- Each file is written to a folder identified by its owner, and the access policy checks that match on every read, upload, replacement or deletion.
- Access to the image happens through a temporary signed link, generated on demand and with an expiry. We never store permanent URLs.
- Changing the pet's photo deletes the previous one — orphan files do not pile up in storage.
- There is a limit on accepted file size and type, checked on the server.
06 Document photos: what happens and what does not stay
This is the point that raises the most questions, so it is worth the detail:
| Step | What happens | Is it kept? |
|---|---|---|
| 1. Capture | The image is downsized on the device itself before sending | No |
| 2. Upload | It travels over an encrypted connection to our server | No |
| 3. Reading | The server sends it to the AI provider and receives the extracted fields | No |
| 4. Review | The fields come back to the app for you to check and confirm | Only what you confirm |
| 5. Record | We log date, document type, outcome and the model used | Yes — without the image |
The extraction is sent to the app in a pending review state. Nothing becomes a medication alarm without your approval — a security decision as much as a product one.
07 Secrets never sit inside the app
An app installed on a phone can be taken apart by anyone. Everything embedded in it must be considered public. Therefore:
- The AI providers' keys live only on the server, as environment secrets, and are never embedded in the app.
- Photo scanning is performed by a function on the server. The app only asks — it does not know which provider answers or with which credential.
- The only keys present in the app are public by definition (project identifier, the database's anonymous key protected by row-level security, the subscription store's public key).
- Operational settings such as provider, model and limits are changed on the server, without republishing the app.
08 The plan is verified on the server
The screen decides what to draw; the server decides what to execute. The photo- scanning function checks the subscription on its own and refuses calls from anyone without an active plan, even if the request carries a legitimate user credential.
Without that server-side check, both the cost and the quota would, in practice, be optional for anyone who knew how to call the interface directly.
09 Quotas and abuse protection
- Every scan is counted before the call to the model, including the ones that fail — so nobody gets around the limit by forcing errors.
- The quota is monthly, anchored to the subscription cycle, and separate per document type.
- There is a limit on accepted image size, checked on the server.
- Usage records cannot be altered or deleted by the user.
10 Image moderation
Before extracting any information, the image is assessed for inappropriate content. The order is deliberate: the first thing the system does is decide whether to proceed at all.
When an image is rejected, we record only the category and the number of occurrences on the account. We keep neither the image nor any description of what it contained — a description would itself be a record of the content we decided not to keep.
11 Receiving subscription confirmations
Purchase confirmations arrive at a dedicated endpoint on the server, which is the only path able to write an account's subscription status. It is protected by several layers:
- Mandatory authentication: without the configured secret, the endpoint refuses everything. Failing closed beats accepting any request that claims "this person is a subscriber".
- Cryptographic signature (HMAC) of the delivery, including the sending time, which prevents replaying an old request.
- Time window: deliveries that are too old are refused.
- Idempotency: each event has a unique identifier and is recorded before being processed. Redeliveries do not duplicate effects, and a failure midway is safely redone.
12 What we log — and what we do not
| We log | We do not log |
|---|---|
| Date, type and outcome of photo scans | The submitted image |
| Rejection category for inappropriate content | Description of the rejected content |
| Technical errors and route failures | Medical-record content in diagnostic logs |
| Access logs required by law | Advertising identifiers |
| Subscription events received from the store | Card or payment data |
13 Backup and continuity
The database is hosted on managed infrastructure, with periodic automatic backups maintained by the provider and storage redundancy. Database schema changes are versioned and applied in a controlled way, which makes it possible to audit exactly what changed, when and why.
Backups exist for disaster recovery. They are not used to look up data from deleted accounts, and they expire within the provider's normal retention cycle.
14 Incident response
No system is impregnable, and promising otherwise would be dishonest. Should a security incident occur that may cause relevant risk or harm to data subjects:
- we contain the incident and preserve evidence;
- we assess which data and which accounts were affected;
- we notify the affected data subjects and Brazil's National Data Protection Authority (ANPD) within a reasonable time, as per article 48 of the LGPD;
- we report the corrective measures adopted and what you can do to protect yourself;
- we review what allowed the incident and fix the cause, not just the symptom.
15 Found a vulnerability?
We are grateful for responsible reports. Write to contact@boopet.app with the subject "Security", describing the problem and the steps to reproduce it.
16 Your part
Part of security is on your side, and it is worth saying plainly:
- use a unique password for Boopet, not reused from other services;
- keep a screen lock active on the device — whoever unlocks the phone unlocks the app;
- do not share the account, even with someone who also cares for the animal;
- keep the app and the device's operating system up to date;
- when replacing or selling the device, sign out first;
- keep your animals' original documents — the app organizes, but does not replace the paper file.
Any questions about security?
Technical questions, vulnerability reports or requests for clarification about data protection.
Oakboo · Brazil · Security reports have priority in the support queue.