Privacy summary
What stays on your device
The original file never leaves the browser. SHA-256 hashing is performed locally using the Web Crypto API. Metadata extraction (EXIF, C2PA) also happens entirely client-side. The PDF certificate is generated in the browser.
What is transmitted
Only the 64-character SHA-256 hash (32 bytes) is transmitted through a server-side proxy to the CertiSigma API. No file content, no file name, and no metadata are sent to any server.
What is not stored
ExistBefore does not create user accounts, does not use cookies for tracking, does not store personal data, and does not log hash values on the proxy. The only data stored on CertiSigma servers is the attestation record: hash, timestamp, signature, and proof layer metadata.
Hash confidentiality
SHA-256 is a one-way function: the original content cannot be reconstructed from the hash. However, for short or predictable content (e.g., a single word, a serial number), the hash may be reversible through brute force. The PDF certificate includes a disclaimer about this limitation.
Sensitive metadata in the PDF
When attesting image files, ExistBefore may extract metadata such as GPS coordinates, device model, and camera settings. Before downloading the PDF, you can disable the inclusion of GPS and device information using the toggle controls. Excluded fields are replaced with "[Removed by user]" in the certificate.
API key security
The CertiSigma API key is stored on the server and injected by the proxy. It is never exposed to the browser, never included in JavaScript bundles, and never transmitted in client-side requests. The key is restricted by IP allowlist and limited to attestation-only scope.
No analytics tracking
ExistBefore does not use third-party analytics services that track individual users. No cookies, no fingerprinting, no advertising identifiers.
Server-side anonymous aggregates
For capacity planning and abuse detection, the production proxy keeps standard nginx access logs locally. Once a day a sandboxed script (scripts/aggregate-stats.mjs, source published in this repository) parses those logs and produces a single JSON file with per-day counters: total requests, attestation count, page views, browser families (Chrome / Firefox / Safari / Edge / Bot / Other), and top referer hostnames.
The aggregator strips every field that could identify an individual visitor, by design and verified by automated tests:
- No IPv4 or IPv6 addresses appear in the output;
- No raw User-Agent strings are kept (only the closed-allowlist family name);
- No referer query strings are kept (only the bare hostname);
- Timestamps are aggregated to per-day granularity (
YYYY-MM-DD); - Request paths fall through a closed allowlist; anything outside the allowlist collapses to
other.
Raw access logs are kept locally on the server with the standard nginx rotation and are never transmitted off-server. The anonymized JSON is the only artifact retained beyond log rotation.
Operational monitoring (Prometheus / Loki / Grafana)
An opt-in monitoring stack runs on the same server to alert the operator on outages, certificate expiry, and abuse spikes. It does not change what we log; it changes what we keep and where we look at it. The stack is composed of free, self-hosted open-source software and never sends data off-server except for outbound email alerts to the operator.
- Prometheus stores numeric counters (request rate, error rate, days-until-TLS-expiry) for 30 days. No log lines, no IPs.
- Loki stores the application logs of the proxy and stack containers for 30 days, after the same anonymization filter described above strips IPv4 / IPv6 addresses, User-Agent strings, and referer query strings.
- Grafana is the dashboard interface, accessible only to the operator over an authenticated channel. It is never exposed to the public internet.
- Uptime Kuma performs an HTTP probe against
/healthzevery 30 seconds. The probe response is a constantokstring and contains no per-request information.
For full transparency, the entire monitoring configuration (which lines are dropped, which fields are redacted, how long data is kept) is published in this repository under monitoring/ and docs/features/observability.md. Operator alerting policies and SLOs are public in docs/SLO.md and docs/RUNBOOK.md.
Security disclosure
If you believe you have found a security issue affecting ExistBefore, follow the procedure published at /.well-known/security.txt (RFC 9116). It lists the contact address, our preferred encryption key, the disclosure policy and the response window we commit to.