Security

How perseus handles your data.

perseus exists to be a witness others can trust. That starts with being straightforward about our own security posture, including the parts that aren't finished yet.

Last reviewed 2026-07-17 · see also /trust for subprocessors and uptime.

Status, honestly

Live

Password hashing: scrypt, versioned parameters

Passwords are never stored in plaintext or reversibly encrypted. We use scrypt (memory-hard, GPU/ASIC-resistant) with explicit, versioned cost parameters, so we can raise them later without breaking old hashes.

Live

Session & CSRF protection

Sessions use an HttpOnly, Secure, SameSite=Lax cookie, inaccessible to page JavaScript. State-changing requests are protected with a double-submit CSRF token. Login uses a constant-cost check on both valid and invalid emails, so a timing difference can't be used to enumerate accounts.

Live

Transport encryption

TLS is terminated at the edge proxy in front of the app; session cookies are marked Secure in every production deployment, so they're never sent over plain HTTP.

Live

Security headers on every response

Content-Security-Policy, X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: strict-origin-when-cross-origin, and HSTS in production.

Live

Rate limiting on auth and ingest

Login/signup/password-reset and log-ingest endpoints are rate-limited per IP, independent of the general API limit, to blunt credential stuffing and abusive ingest.

Live

Non-root runtime

The application container runs as an unprivileged user, not root.

In progress

SOC 2 Type II

We have not started a formal audit and do not claim SOC 2 compliance today. It's on our near-term roadmap. This page will say exactly where we are, including the auditor and report date, once that clock starts. We won't claim a certification we don't have.

In progress

Fine-grained RBAC & audit log

A baseline audit trail exists for account and billing actions; per-org role separation (Owner/Admin/Billing/Member/Viewer) and an exportable audit log are Enterprise-tier work in progress. See pricing.

Not started

SSO / SCIM, third-party penetration test, ISO 27001

Planned, not scheduled. We'd rather list these honestly than pad this page with "coming soon" for things that aren't yet on a calendar.

Data we ingest, and why

perseus ingests the access-log lines you send us: uploaded log files, a forwarding worker, or a CDN log-drain (Cloudflare Logpush, Vercel). Because that's your raw server log, a batch can include requests from human visitors as well as AI crawlers. We don't run analytics or advertising on top of it, and we don't sell or share it.

What we do with each line: match the user-agent and source IP against the crawler's own published IP ranges (or a reverse-DNS confirmation, where configured), record the verdict (verified / spoofed / declared), and hash-chain the record. See how the Evidence Record works.

Retention, honestly: there is no automatic deletion job today. Ingested event rows persist for the life of your account on our single database volume until you close the account and ask us to delete it. Per-plan trend windows shown on the dashboard (7/90-day) control what the UI displays; storage duration is separate. A configurable retention/purge policy is on the roadmap. Until it ships, treat your data as retained indefinitely.

Tenant isolation

Every site is scoped by a site_key enforced at the query layer; every ingest/read path checks the requesting session against site ownership before touching data. Today all tenants share one SQLite database file on one host. There is no per-tenant database or hard filesystem boundary yet. That's a documented, deliberate trade-off, not an oversight: SQLite in WAL mode comfortably handles our current write volume, and row-level site_key scoping is enforced in every query. The trigger for moving to per-tenant isolation (or a Postgres + row-level-security model) is a specific enterprise requirement or a measured concurrency ceiling. See /trust for the infrastructure this runs on.

The Evidence Record's own integrity guarantees

This is the part perseus is actually built around, so it gets the most scrutiny, including scrutiny of ourselves:

None of this makes perseus a court, a notary, or a certification body. It makes the record checkable by someone other than us, which is the property that actually matters for a neutral witness.

Report a vulnerability

See /.well-known/security.txt for contact and disclosure policy. We don't run a bug-bounty program yet; we do commit to acknowledging a good-faith report and working with you on a fix.