How we protect your receipts, account, and financial data — from the device to our servers.
Last updated: May 25, 2026
Overview
Receipt data is inherently personal — it reveals where you shop, what you buy, and how much you spend. We take this responsibility seriously and have built security into every layer of Invoisor, from the device to our backend infrastructure.
This page describes the specific technical controls we have in place. If you are a security researcher who has found a vulnerability, please jump to Responsible disclosure.
Data in transit
Every request between the Invoisor app and our backend servers travels over an encrypted connection:
TLS / HTTPS on all endpoints
All API endpoints are served exclusively over HTTPS with TLS 1.2 or higher. HTTP requests are rejected or redirected. There is no fallback to plaintext communication.
Certificate validation
The mobile app validates the server's TLS certificate and does not connect to endpoints presenting invalid or self-signed certificates. Development URLs that start with “http://” are automatically blocked by the app and cleared from storage.
Receipt image uploads
Receipt images are uploaded as multipart form data over the same HTTPS connection. Images are never sent unencrypted, even on local networks.
HTTP security headers
Every API response is hardened with industry-standard security headers (HSTS, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and more) to enforce HTTPS and reduce the risk of common web attacks.
Data at rest
Your data is stored across two primary systems, both with encryption at rest enabled:
PostgreSQL database
Account profiles, receipt records, line items, categories, canonical items, job records, push tokens, and subscription state are all stored in a PostgreSQL database. The database volume is encrypted at rest and is not publicly accessible.
Cloudflare R2 — receipt images
Receipt images are stored in Cloudflare R2 object storage. Access is controlled by Cloudflare's infrastructure, and image URLs are scoped so that only authenticated requests can retrieve them. Images are never publicly indexed.
No local plaintext storage on device
The mobile app does not write your receipt data to unencrypted local storage. The only values stored locally are authentication tokens (in the OS secure enclave — see below), lightweight preferences (theme, currency), and a small job-state cache in AsyncStorage. AsyncStorage values do not include receipt content.
Authentication
Invoisor uses a dual-token JWT authentication system designed to minimise the impact of any single token being compromised:
Short-lived access tokens (15 minutes)
Every authenticated API request is accompanied by a JWT access token. Access tokens expire after 15 minutes. A short expiry limits the window of opportunity if an access token is intercepted.
Rotating refresh tokens (30 days)
When an access token expires, the app automatically uses a refresh token to obtain a new pair. Refresh tokens are single-use — each use rotates the token, invalidating the previous one. A stolen refresh token used by an attacker will immediately invalidate the legitimate session.
Secure storage on device
Refresh tokens are stored in the device's OS-level secure storage: iOS Keychain (via Expo SecureStore) and Android Keystore. These storage areas are hardware-backed and inaccessible to other apps.
Password hashing
Passwords are never stored in plaintext. We use a modern adaptive hashing algorithm with per-account salts. If you forget your password, a 6-digit OTP reset code is sent to your registered email; the code expires within minutes and cannot be reused.
Apple & Google Sign-In
Social sign-in is handled entirely through the provider's identity framework. We receive and verify a signed identity token, then create or authenticate the account. We never receive or store your Apple ID or Google password. Social accounts can later add an email/password without losing access to social sign-in.
Rate limiting & brute-force protection
Authentication endpoints (sign-in, sign-up, password reset, OTP verification) are rate-limited per IP address, so password-guessing and credential-stuffing attempts are throttled. A separate per-IP limit protects the wider API against request floods. Password reset never reveals whether an email is registered, preventing account enumeration.
Session revocation
Resetting or changing an existing password immediately revokes all active refresh tokens, signing you out of all devices. This limits the impact of a compromised password. (Adding a password for the first time on a social account does not sign you out.)
AI pipeline
Receipt content processed by our AI system is handled with the following controls:
Server-side only processing
Receipt images and raw text are sent to our backend servers for AI extraction. Processing does not happen on-device or through third-party browser-side APIs. This keeps your financial data within our controlled environment.
No training data use
Your receipt content is never used as training data for any AI model — ours or a third party's. We do not share receipt images or text with model providers in a way that would associate them with your identity or contribute to model training.
Duplicate detection is account-scoped
Duplicate receipt detection compares fingerprints derived from receipt content within your own account only. No cross-account comparison or data sharing occurs.
Async job isolation
When you submit a scan as an async job, the job is processed in isolation. Job records contain only the metadata needed to resume the result retrieval flow, not raw receipt content beyond what is needed to re-submit on force-save.
Device security
The mobile app is built with the following device-level protections:
No clipboard sensitive data
The app does not write receipt amounts, merchant names, or account credentials to the system clipboard except where you explicitly trigger a copy action.
Screen content protection
Sensitive screens are not captured in app-switcher screenshots on supported OS versions.
No background data sync
The app does not run background processes that transmit receipt data. Syncing happens only when the app is in the foreground or when handling an incoming push notification.
Push notifications
Push notifications are an optional feature that requires explicit permission from you:
Opt-in only
The app requests notification permission at a natural point in the onboarding flow. If you deny permission, the app works fully without push notifications and falls back to polling.
Token lifecycle
When you grant permission, your Expo push token is registered with our backend. When you log out, the token is deregistered and deleted from our servers. Reinstalling the app generates a new token.
No sensitive data in payloads
Push notification payloads contain only a notification ID and a destination screen name. Receipt amounts, merchant names, and item details are never included in the payload. The app fetches the full notification content from the API after the tap.
Access controls
Access to production systems is tightly controlled:
API authentication on all protected endpoints
Every endpoint that accesses user data requires a valid, non-expired JWT access token. Public endpoints (health check, forgot-password, OTP verification, password reset) are rate-limited to prevent abuse.
Per-user data isolation
Database queries are scoped to the authenticated user's ID. It is not possible to access another user's receipts, categories, or analytics through the API, even with a valid token.
Plan enforcement
AI feature usage is enforced server-side against your plan limits. Client-side checks in the app are a convenience only — the backend rejects requests that exceed limits regardless of the client state.
Responsible disclosure
We welcome reports from security researchers. If you have discovered a potential vulnerability in the Invoisor app, website, or API, please let us know responsibly:
Describe the vulnerability, affected component, and reproduction steps
Include the potential impact and any proof-of-concept (screenshots, curl commands)
Do not publicly disclose the issue until we have confirmed and addressed it
We commit to acknowledging your report within 3 business days, investigating promptly, and keeping you informed of our progress. We will not take legal action against researchers who report in good faith and follow this process. We currently do not operate a formal bug bounty programme, but we deeply appreciate responsible disclosures.
Contact security
For all security-related communications — vulnerability reports, account compromise concerns, or questions about our security practices — contact us at: