Canopy
Security & Transparency

How Canopy handles your data

This page documents what we encrypt, what we don't, where your data is stored, and what our limitations are.

Architecture

How your data flows through Canopy

Sensitive content (article bodies, feed URLs, summaries) passes through the same pipeline: fetch, encrypt, store. Article titles and URLs remain in plaintext for search and display. The encryption key is loaded as an environment variable at startup and held in process memory — it is never stored in the database.

BrowserTLS in transit
Canopy ServerKey in env, not in DB
encrypt()AES-256-GCM
PostgreSQLEncrypted fields
Encryption Details

What's encrypted — and what isn't

We encrypt content fields like article bodies, feed URLs, and summaries. Article titles, URLs, and functional flags (read/starred states) are stored in plaintext so the app can search, filter, and sort without decrypting the database.

Encrypted (AES-256-GCM)

  • Feed URLs & feed names
  • Site URLs
  • Article content & summaries
  • Newsletter content & summaries

Not Encrypted

  • Account ID (random, not PII)
  • Article titles & article URLs
  • Read / starred / saved states
  • Timestamps (created, updated)
  • Feed type (rss, newsletter, podcast)
  • Podcast enclosure URLs & duration

Article titles and URLs are stored unencrypted so the app can display and search your article list without decrypting the full database. They contain public information (headlines from public websites), not private data you created.

What a database record looks like

ida7f3e2b1-...
titleHow Privacy-First RSS Readers Work
urlhttps://example.com/article/123
contentQw4pBn9C==:Ht8YrM6x==:PGRpdiBjbGFzcz0i...
is_readtrue
created_at2026-02-21T10:30:00Z

Encrypted field format

Each encrypted value is three base64-encoded segments separated by colons:

IV12 bytesRandom initialization vector — ensures identical plaintext produces different ciphertext
:
AuthTag16 bytesAuthentication tag — detects tampering or corruption
:
CiphertextVariableThe encrypted content — unreadable without the key
Threat Model

What we protect against — and what we don't

No system is perfect. Here are the specific threats we address and the ones we don't.

Protected

Mass surveillance

Feed URLs and article content are encrypted. Article titles and URLs are stored in plaintext but are public information from public websites, not private data.

Third-party tracking

No analytics, no tracking pixels, no third-party JavaScript except Stripe on the checkout page.

Data breach exposure

If our database were stolen, attackers would get encrypted content and feed URLs. Article titles and URLs would be readable, but these are public headlines from public websites.

Casual subpoenas

We cannot produce readable feed data without the encryption key. We operate under EU (Finnish) jurisdiction.

Payment correlation

Stripe processes payments via a random token that maps to your account. After 20 days the token is deleted and the link between your payment and your account no longer exists. We never see or store your card number.

Honest Limitations

Server compromise with key access

If an attacker gains access to the running server process, they could read the encryption key from memory and decrypt stored data.

Traffic analysis of feed fetching

When Canopy fetches your feeds, the source servers see our server's IP. An observer with access to those logs could infer that someone on Canopy follows a given feed — but not who.

Compromised TLS

If TLS is broken or a certificate authority is compromised, data in transit could be intercepted. We use Let's Encrypt with automatic renewal.

Trusting us to run described code

Canopy is not open-source. You are trusting that we run the code we describe. We publish this page as a commitment, but we cannot cryptographically prove it.

Infrastructure

Where your data lives

The server and database are in one location. Here's what we use and what we don't.

Server & Database

  • Hetzner Cloud, Helsinki, Finland
  • PostgreSQL with encrypted fields
  • GDPR jurisdiction (EU)
  • No US cloud providers in the data path

What We Don't Use

  • No analytics (no Google Analytics, no Plausible, nothing)
  • No CDN tracking or edge logging
  • No third-party JavaScript (except Stripe on the checkout page)
  • No tracking cookies (session-only auth cookie)
  • No error tracking (no Sentry, no LogRocket)
  • No A/B testing

Each of these is a trade-off. We have no visibility into bugs, performance, or user behavior.

Newsletter Privacy

How we strip newsletters clean

Most newsletters contain invisible tracking pixels and click-tracking URLs. Canopy removes them during processing.