Cremind
Cremind Connect

Privacy and trust

What Cremind Connect can momentarily observe, what it provably never keeps, and why being stateless at rest and fully open source makes it auditable.

The defining property of Cremind Connect is restraint: it is engineered to relay events without holding your tokens or your content. This page is the trust model — what the relay can momentarily see, what it provably never keeps, and how you can verify all of it yourself.

What the relay never holds

  • No OAuth access or refresh tokens. For Google, the relay is never in the token path. For Atlassian, the relay performs the confidential exchange and hands the tokens straight back to your app — it stores none of them.
  • No email, calendar, or issue content. The relay forwards content-free "resync" nudges. Your app always fetches the actual changes itself, locally, with its own token.
  • No durable user data or account mapping. Routing keys are derived from each event's payload, not stored. There is no user table to leak.

What the relay can momentarily see (and immediately discards)

Being honest about the threat model matters more than claiming the relay sees nothing. Here is what passes through it and how each item is handled:

DataSourceHow it's handled
Account emailGmail push payload; bootstrap ID tokenHashed into a routing key, then discarded — never stored or logged
Change cursor hintProvider push payloadUsed at most as a transient hint; never forwarded to clients
Calendar channel headersCalendar webhookRouting key parsed from the channel id; not stored
OAuth access / refresh tokensNever seen

The account email is observed only long enough to hash it into a routing key, and the routing key is itself a hash. Logging uses a field allowlist, so logs contain only the derived (already hashed) routing key and counts — never email addresses, cursor hints, tokens, or JWTs.

Stateless at rest

Cremind Connect is stateless at rest. Subscriber WebSocket connections live only in memory for the lifetime of the connection, and routing keys are derived per event rather than persisted.

The only persistent storage the relay uses is a small key-value store for:

  • Google's public JWKS cache — the public keys used to verify Google's signed pushes. This is public data, not user data.
  • A single-use nonce store — used to prevent replay of the bootstrap ID token during subscription. Nonces are consumed and expire.

There are no tokens, no user records, and no content anywhere in the relay's storage.

Dropped nudges are by design

If your app is offline when an event arrives, the nudge is simply dropped. On reconnect, your app re-establishes its watch and does a catch-up sync directly with the provider. Connect is a real-time accelerator, not a durable queue — so there is no backlog of your activity sitting on a server.

How subscriptions stay private

Because routing keys come from a hash of the account, the relay enforces proof of control before letting an app join an account's hub. Your app presents a Google ID token; the relay verifies its signature, audience, expiry, the email_verified claim, and a single-use nonce, then confirms the derived key matches the requested account. An ID token proves who you are but grants no API access — so even at the moment of subscription, the relay sees only a verifiable identity assertion, never a usable token. A subscriber can only ever join the hub whose key matches its own verified account, so one account's nudges can't leak to another.

Why you can trust it: open and auditable

Cremind Connect is MIT-licensed and fully open source, running on Cloudflare's platform. It is intentionally small, so you don't have to take these claims on faith — you can read the entire service, including its infrastructure definitions, and confirm exactly what it does and does not do.

Cremind is version 0.0.1 — early and community-driven. The privacy posture described here reflects the current design; the best source of truth is always the source itself.

On this page