Security
How names.dev protects buyer and seller data.
names.dev runs on a small, deliberately chosen stack with auth gated on every write, audit logging on every state change, and a clean approval-token contract for any irreversible action. This page lists the controls in operation, the ones in progress, and the third-party services that see your data.
Control inventory
Indexed against the SOC 2 Type I framework. We are drafting evidence for an external audit with completion targeted for late 2026.
Authentication
Every state-changing API route enforces a signed-in Supabase session via requireUserApi(). Anonymous writes are rejected with 401.
Evidence: src/lib/auth/api.ts; 9 /api/v1/* routes gated via requireUserApi().
Authorization
Approval-token HMAC binds the actor's user id, scope, subject, and expiry. Tokens are single-use and audited. Cross-user replay is rejected with 403.
Evidence: src/lib/approval/index.ts; consumed tokens persisted in storage.
Audit logging
Every state-changing action records an audit entry with userId, action, subject, ip, userAgent, and timestamp. The user can view their own log on /account/audit.
Evidence: src/lib/audit/log.ts; saveAuditEntry persists append-only.
Encryption at rest
Postgres production storage is encrypted at rest via Supabase managed encryption. Backups are encrypted with the same KMS keys.
Evidence: Supabase project configuration; review pending in vendor audit.
Encryption in transit
TLS 1.3 enforced site-wide via Vercel. HSTS preload set with includeSubDomains and a two-year max-age.
Evidence: next.config.ts headers(); browsers refuse plaintext after first visit.
Content security
CSP restricts script and connect sources to an explicit allowlist (Vercel, Anthropic, Supabase, Stripe, RDAP registries). X-Frame-Options DENY, Referrer-Policy strict-origin-when-cross-origin.
Evidence: next.config.ts headers().
Prompt-injection defense
Buyer-supplied free text is wrapped in <buyer_brief> XML tags and scrubbed for common injection canaries before being passed to Claude. Length capped at 2000 characters.
Evidence: src/lib/identity/anthropic.ts scrubBuyerInput().
Webhook idempotency
Stripe webhook persists event.id with a unique constraint and dedupes on subsequent receipt. Replayed deliveries return 200 deduped:true without re-running side effects.
Evidence: src/app/api/stripe/webhook/route.ts; storage helpers via hasStripeEventBeenProcessed.
Data retention
Search briefs retained for 90 days then purged. Identity reports retained for the buyer's subscription lifetime plus 30 days. Audit log retained 7 years.
Evidence: Retention worker scheduled.
Right to be forgotten
Authenticated users can request deletion of their identity projects, ships, listings, and audit log. Request goes to privacy@names.dev; we acknowledge within 24 hours and complete within 30 days.
Evidence: Process documented; self-serve UI in /account/data planned.
Vulnerability disclosure
security@names.dev contact published in /.well-known/security.txt with a 24-hour acknowledgement SLA and a 72-hour triage SLA. Coordinated 90-day disclosure window.
Evidence: public/.well-known/security.txt.
Responsible disclosure recognition
Public credit on a security hall of fame for valid findings, a thank-you swag pack, and at our option a discretionary thank-you for critical issues. names.dev does not run a paid bug bounty. Severity rubric on /security/bounty.
Evidence: src/app/security/bounty/page.tsx; /security/hall-of-fame.
Status page
GET /api/status probes 8 upstream dependencies (RDAP registries, npm, Anthropic, GitHub, iTunes, Stripe) every poll. The public /status page renders the result.
Evidence: src/app/api/status/route.ts.
Disaster recovery
Postgres backups taken hourly, retained 30 days. RPO 1 hour, RTO 4 hours. DR runbook lives in the engineering wiki.
Evidence: Supabase point-in-time recovery; runbook drafted.
Third-party subprocessors
The services that see your data. Card data is never stored by names.dev; Stripe holds the tokenized payment method.
Vercel
Application hosting, edge runtime, OG image generation.
All request data in flight. No application data stored.
Supabase
Postgres database, auth, file storage.
User account, identity projects, ships, listings, audit log.
Anthropic
Claude generation for find_names, intent enrichment, brand kits.
Buyer brief text, system prompts. No PII beyond what the buyer types into the search.
Stripe
Payment processing for subscriptions and sprint intake.
Customer email, payment method tokens, transaction history. Card data never touches names.dev.
Resend
Transactional email (offer notifications, watchlist alerts).
Recipient email, message body, send metadata.
Found a vulnerability?
Email security@names.dev. We acknowledge within 24 hours and triage within 72. Honest reports under coordinated disclosure get public credit, and on a sliding scale up to four figures for severe issues. See .well-known/security.txt for the canonical policy.
Last reviewed: 2026-05-14