Security

Last updated: 27 August 2026

CultureFitr holds personal data about people who never signed up for anything: candidates invited to take an assessment by an agency. This page describes how the product is built to protect it, and says what is not in place yet.

Accounts and sessions

Sign-in is password or Google, and a workspace cannot be created without proving control of the email address first. The account and its password come into existence only when the emailed confirmation link is opened.

  • Passwords are hashed with Argon2id. They are never stored, logged, or recoverable. A reset replaces the hash; it does not reveal anything.
  • Sign-in is rate-limited before the hash is computed, and an unknown address costs the same time as a known one, so response timing cannot be used to discover which addresses have accounts.
  • Sessions are httpOnly cookies, SameSite=Lax, and Secure over HTTPS. Browser JavaScript cannot read them. The refresh cookie is restricted to the authentication endpoints and is not sent anywhere else.
  • Refresh tokens rotate on every use. Replaying one that has already been rotated ends every session for that user, which is what makes a stolen token detectable rather than merely time-limited.
  • Disabling a member or suspending a workspace takes effect on their next request, not when their current token happens to expire.

Keeping workspaces apart

Every query is scoped to the workspace that made the request, and a request for a record belonging to another workspace returns “not found” rather than “forbidden”, so the response does not confirm that the record exists.

  • This is enforced in the application, not by database row-level security. If your questionnaire asks specifically about database-layer isolation, the honest answer is that we do not use it.
  • Candidates have no account and no access to a workspace. A candidate link opens exactly one assessment and nothing else.

What we hold about a candidate

A candidate is asked for a first name, last name and email address, and answers a ranking exercise. We store those, the scores computed from them, and, where the recruiter emailed the invitation from CultureFitr, the address it was sent to.

  • No CVs, no documents, no uploads. There is nowhere in the product to attach a file.
  • We do not record a candidate’s IP address or set any cookie in their browser beyond the assessment they are taking.
  • A candidate who is refused a closed assessment is told only that it is closed, never the agency’s plan, usage, or billing state.

Assessment and report links

A link is the credential: whoever holds it can take the assessment or read the report. They are treated accordingly.

  • Links carry 32 bytes from a cryptographic random source. They are not guessable and not enumerable.
  • Links expire after 30 days by default, and a recruiter can revoke or regenerate one at any time. Revoking a link also closes the reports it produced.
  • No usable token is stored anywhere. Confirmation, reset, refresh and invite tokens are kept only as a SHA-256 hash. Assessment and report links, which a recruiter has to be able to copy again, are additionally encrypted with AES-256-GCM under a key held outside the database, so a copy of the database on its own yields hashes that cannot be reversed and ciphertext that cannot be read.
  • The service refuses to start in production without that key rather than falling back to storing links in the clear.
  • These pages are excluded from search indexing at two independent layers.

What the AI model receives

The written insights are generated from the computed profile, and that is all the model is given: four percentages, the same four per dimension, the client’s industry label, and one number the API calculated. No name, no email address, no answer text, and none of the recruiter’s private notes are ever sent.

  • This is a property of the request’s shape rather than a filter applied to it. The payload has no field capable of carrying a name, so there is no path by which one could be added by accident.
  • The scores are computed by us and are the authoritative output. The model writes prose about a result it cannot change.

There is no file store

CultureFitr writes no files. PDF reports are rendered on demand and streamed straight to the person who asked for them; nothing is saved to a disk or an object store, and there is no bucket to misconfigure or leak. Agency logos are held inline in the database rather than uploaded anywhere.

Rate limiting

Every endpoint is rate-limited, and the ones worth attacking are limited far more tightly than the default: signing in, registering, resending a confirmation, requesting a password reset, sending an invitation, and generating a PDF each have their own budget. Candidate-facing endpoints are limited separately so that one link cannot be used to hammer the service.

Logs

Application logs record the route pattern, never the URL, because an assessment or report URL is a credential and a log stream is read by more systems and more people than a database is.

  • Every response carries a request id that ties the log lines for that request together, so support can trace an incident without anyone quoting personal data.
  • Candidate answers, report contents and access tokens are never written to logs.

In the browser

The site sends a Content-Security-Policy, refuses to be framed, sends HSTS over HTTPS, and uses a referrer policy that keeps a tokenised URL out of the Referer header when a page makes a cross-origin request.

  • Every page that renders your data runs under a per-request script nonce, so the browser refuses any script that was not put there by us. Inline script is not allowed to run at all on those pages.
  • There are no analytics, session recorders, advertising pixels or tag managers anywhere in the product. Fonts are served from our own origin, so your browser makes no request to anyone else for them.
  • One third-party script exists, and only one: our payment provider’s checkout. It is loaded on the billing page in your workspace settings, only at the moment you choose to start or change a subscription, and nowhere else. No marketing page, no assessment and no report loads any code we did not write.
  • Three cookies of our own exist in total, all strictly functional: two for your session and one short-lived value that makes Google sign-in safe against cross-site request forgery. None of them track anything, which is why you are not asked to accept cookies. Opening the payment provider’s checkout involves their own cookies, which are necessary to take a payment you asked us to take.

Payments

We never see a card. Our payment provider is the merchant of record, which means it is the seller on your invoice, and it handles payment details and tax rather than us.

  • Card and bank details are entered on the provider’s own checkout and are never sent to us, never pass through our servers and are never stored by us. We hold no payment instrument of any kind.
  • What we store is a subscription identifier, a customer identifier, the plan, its status and the date the current period ends. That is what decides your allowance; none of it can be used to charge anyone.
  • Invoices, receipts and VAT are issued by the provider. As merchant of record it registers for and remits the applicable sales tax itself, so no tax logic lives in our code.
  • Because a subscription’s state reaches us as a signed notification, each one is verified, recorded once, and ignored if it arrives out of order, so a replayed or reordered message cannot change what your workspace is entitled to.

Deleting data

Deletion is real deletion, not a hidden flag.

  • Deleting a result also removes the written insights generated from it and any comparisons that used it.
  • Deleting a client company removes the results belonging to it.
  • Deleting a workspace removes its members, its links, its results, and the invitation records, which is where a candidate’s email address is held and is exactly the material an erasure request concerns.
  • Expired confirmation, reset and session credentials are swept automatically rather than accumulating.
  • Records of what a workspace was charged for deliberately outlive the workspace. They contain no candidate data.

What we do not have yet

Stated plainly, because a security questionnaire will ask and finding out later is worse for both of us.

  • No SOC 2, ISO 27001, or other third-party certification.
  • No independent penetration test has been carried out.
  • No multi-factor authentication for administrators. Access is password-based today.
  • Workspace isolation is enforced in the application, not by database row-level security.
  • There is no self-service data export or self-service workspace deletion; both are handled on request.
  • There is no automatic maximum retention period for completed results. They remain until a workspace deletes them.

Infrastructure, sub-processors and data processing

CultureFitr is in early access. Where the service is hosted, how it is backed up, and the full list of sub-processors, including which model provider generates the written insights, are covered by our data processing agreement, which we provide on request. Write to hello@culturefitr.com and we will send it along with answers to any questionnaire you need completed.

  • The categories of sub-processor are these: hosting, transactional email, the language-model provider that writes the insights, and our payment provider, which acts as merchant of record. The named entities and their locations are in the agreement rather than on this page, so that it stays accurate when one of them changes.

Reporting a vulnerability

If you believe you have found a security problem, email hello@culturefitr.com with enough detail to reproduce it. We will confirm receipt, keep you updated while we investigate, and will not pursue anyone who reports a genuine issue in good faith and does not access or alter data belonging to others.