Skip to main content

SECURITY

How we protect your account and data

This covers the technical practices behind the product. For who can see a given report, how long data is kept, and where things stand on hiring-related regulation, see /trust. For what data is collected and why, see /privacy.

Practices in place today

Authentication

Accounts are authenticated through Supabase Auth, not custom password storage. Email verification is required before an account can start an assessment. The frontend never sees the Anthropic key, the Supabase service-role key, or the email-provider key -- only a publishable Supabase key safe for client use.

Two independent authorization layers

Every request is checked twice: the backend verifies a caller's role and organization before returning data, and Postgres row-level security enforces the same boundaries again at the database level. A bug in one layer does not, by itself, expose another person's data.

Rate limiting and abuse prevention

Registration and password reset are rate-limited per IP. Starting a new assessment is capped per user, per day and per month. A global daily spend ceiling stops the interview-processing engine outright if usage spikes unexpectedly, rather than letting cost run unbounded. Registration is gated behind Cloudflare Turnstile.

Uploaded documents

A resume or other document you upload is restricted to PDF, DOCX, or plain text, capped in size, and stored in a private location scoped to your account only. Text is extracted from it to add context to your interview; the file itself is never executed or rendered as anything but text to read.

Secrets handling

API keys and service credentials live only in environment variables on the hosting platform, never committed to source control and never returned in any API response.

Audit logging

A small set of sensitive actions is written to an append-only audit log that only a super administrator can read: administrator role changes, organization access to a participant report, and deletion requests and their completion. Logging is best effort: a failure to write an audit row is reported internally but does not block the action, and actions outside that list are not logged.

Deletion requests

You can request deletion of your account from your account page. The request is recorded with a status (requested, completed, or cancelled) that you can see, and an administrator completes it, which also removes your uploaded files from storage. Deletion is a manual, administrator-completed step today, with no guaranteed completion time.

Automated code and dependency checks

Every change runs a secret scan, a static security scan of the backend, and a dependency vulnerability check of the backend. The frontend dependency check is report-only, and Dependabot proposes dependency updates weekly.

Input handling

Every request the backend accepts is validated against a strict schema at the boundary. Your answers are sent to the AI model as text, never interpolated into a database query, and are escaped before being rendered back to you or into a PDF.

Where we’re still maturing

We would rather tell you what isn’t done yet than let a polished page imply otherwise:

  • We have not completed a formal third-party security audit or penetration test, and we hold no security certification.
  • Rate limiting currently runs in a single backend instance; a shared, multi-instance limiter is planned as usage grows.
  • The audit log covers a limited set of actions, not every administrator or data-access event.
  • Frontend dependency vulnerability findings are reported but do not yet block a release.
  • There is no account lockout after repeated failed logins. Rate limiting slows guessing but does not stop a distributed attempt.
  • There is no dedicated security email address yet. Report a vulnerability privately through the repository’s security advisory feature.