Privacy Policy
What we collect, why, how we store it, and what you can do about it. No dark patterns — same posture inside the product as on this page.
Last updated: 2026-05-15.
Who collects what
Brennan VanderLaan is the data controller for everything you upload (boxes, items, photos, tags, room layouts) and everything we observe about your account (sign-in email, IP, audit log, usage meters). The sub-processors we hand data to are listed at /about/sub-processors.
Data we hold
- Identity: the email from your OAuth provider (Google today; GitHub, Apple, and passwordless email are on the roadmap), tenant membership, role.
- Inventory content: box / item names, notes, tags, room positions, floorplan images, item photos.
- Audit log: structured records of every mutation in the system, attributed to the actor and tenant. Used for incident response + your own change-tracking.
-
Usage meters: AI call counts, upload byte
totals, daily AI-cost figures. Drives the quota system and
the cost-transparency block in
/usage. - Stripe customer + subscription IDs for paid tenants. Card details live entirely with Stripe.
How we secure it
- Encryption at rest. Item photos and thumbnails are encrypted with a per-tenant data-encryption key wrapped by a deployment-wide key-encryption key. DB columns (names, notes, tags) stay cleartext for searchability in v1.
- Transport. Everything in production rides over HTTPS; the bearer-auth surface refuses non-HTTPS requests for non-localhost.
-
Tenant isolation. Every database query
enforces a
tenant_idfilter; cross-tenant probes 404 by design (no information disclosure). - Auditability. Every mutation writes a row to the audit log with the actor, action, target, and a structured metadata blob.
Your rights (GDPR + similar)
-
Access (Article 15): the in-app
"Download my data" link on
/usagereturns a readable SQLite + decrypted-JPEG zip of everything in your tenant. - Portability (Article 20): same zip, same link. The format is standard SQLite + JPEG, so any tool that reads either format can consume it.
- Rectification (Article 16): edit any row in the app directly, or email us if you need help.
- Erasure (Article 17): account deletion via support@stash.swampcats.life or the operator-mediated tenant hard-delete. 30-day soft-delete grace, then permanent removal from primary storage + backups.
- Restriction (Article 18): suspend processing while a request is being investigated — contact support@stash.swampcats.life.
- Objection / withdrawal of consent: cancel your subscription and request deletion.
Cookies
We use a single cookie set by our OAuth identity proxy
(currently a Google sign-in session; will become a generic
OAuth-provider cookie as we add GitHub, Apple, and
passwordless email) plus an optional active_tenant
cookie for multi-tenant users. No third-party advertising or
analytics cookies. We do not sell or share data with
advertisers, period.
On the public marketing pages (this page, the landing, pricing, etc.) we collect aggregate page-view + dwell-time analytics with no cookies so we can see which pages get traffic and how long visitors stay. Instead of storing a persistent visitor id, we derive a short-lived pseudonymous bucket id from a one-way hash of your IP + User-Agent + our own server-side encryption key + a 30-minute time window. Properties of this approach:
- No cookie is set. Nothing is written to your browser.
- Your raw IP is hashed at request time and then dropped. We don't store IP addresses.
- The bucket id rotates every 30 minutes, so even within our own data the linkage is short-lived. Crossing the boundary makes you look like a fresh visitor.
- The hash uses a server-side secret you don't have access to. An external observer can't go from a stored bucket id back to an IP.
- We only store the path you visited and how long you stayed. Never form contents, never anything typed.
- The data is held in our own database, never sent to a third-party analytics vendor, never used for advertising.
GDPR posture: hashed-with-rotating-secret IPs sit in a grey zone of "is this still personal data?" under European law. We disclose the approach in full here so you can decide whether you're comfortable with the trade-off; if you'd rather not be measured at all, browser extensions that block JavaScript will stop the dwell-time beacon (the server-side pageview count still fires, since it's just an HTTP request — but it carries no more information than the request itself).
Retention
- Account + tenant data: kept while your account is active. Cancelling does not delete; explicit deletion does.
- Soft-deleted tenants: 30 days, then hard-deleted by an operator. Backups containing the tenant age out within the configured B2 retention window (default 90 days).
- Audit log: retained indefinitely while the account is active (incident-response usefulness). Cleared on tenant hard-delete.
Breach notification
If we experience a data breach affecting your personal data, we'll notify you within 72 hours of discovery, including what we know about the scope and our remediation status. This is a GDPR Article 33/34 obligation; we treat it as a hard commitment regardless of jurisdiction.
Contact
Privacy questions: support@stash.swampcats.life. For formal data-subject requests, include the relevant article number in the subject line so we route it correctly.