Security
Last updated: 2026-05-12
Authentication & sessions
Two sign-in paths: a one-time 6-digit code emailed via Resend, or GitHub OAuth (read-only scopes read:user + user:email). Email codes have a 15-minute TTL and lock after 5 wrong attempts. Session tokens are HttpOnly + Secure + SameSite=Lax cookies with a 30-day rolling lifetime. GitHub access tokens are stored AES-GCM-256 encrypted with the user id as Additional Authenticated Data — only the rightful owner can decrypt.
Encryption in transit
HTTPS-only, HSTS preloaded. Our edge runs on Cloudflare with TLS 1.2+. Outbound deliveries (sign-in code, status alerts, digest emails, webhooks) are HTTPS-only. Webhook URLs that resolve to http:// are rejected at save time.
Encryption at rest
Account data + preferences live in Cloudflare KV, which encrypts data at rest. On top of Cloudflare's encryption we apply application-level AES-GCM-256 for anything truly sensitive (currently: GitHub OAuth tokens), keyed with the user id as AAD so a stolen blob cannot be decrypted in isolation.
Email destination verification
Adding a non-account email to your alert destinations sends a one-click confirmation link signed with HMAC-SHA256. Until the recipient confirms ownership, the address is marked "pending" and the dispatcher refuses to send to it. The same HMAC pattern powers the one-click unsubscribe link in every marketing-shaped email (RFC 8058 compatible).
Webhook signing
Generic webhook payloads carry an X-Prismix-Signature header (HMAC-SHA256 over the body, keyed with your account's signing secret) so the receiver can verify the payload originated from us.
Rate limiting
Public endpoints (sign-in code request, contact form, star toggle, read APIs) are rate-limited per IP in a KV-backed token bucket. Abusive traffic returns 429 with a Retry-After header. The public REST API publishes its cap at /api-docs.
Idempotency & abuse defence
Alert dispatch carries per-transition idempotency markers so a flapping service cannot carpet-bomb a recipient. Digest sends carry per-week / per-day markers so a retried cron tick cannot double-send. Ko-fi webhook retries are deduplicated by transaction id with a 90-day marker.
Subprocessor list
See the Privacy Policy → Subprocessors section.
Reporting a vulnerability
Use the contact form with the "Security report" topic. Please include reproduction steps and your preferred contact for follow-up. We respond within 72 hours and aim to ship a fix within 14 days for high-severity issues.
We credit reporters in the changelog (with their consent).
What's out of scope
- Reports requiring physical access to a victim's device.
- Self-XSS that requires the user to paste attacker-controlled content into DevTools.
- Missing best-practice headers without a demonstrated impact.
- Rate-limit bypass on read-only cached public endpoints — we accept some abuse on cached read paths as cost of doing business.
- Email spoofing of
prismix.devwithout exploiting our DKIM / SPF setup.