Security
What protects a workspace's data, enforced in the database rather than in a screen — and what is honestly still missing.
Last reviewed against the product on 2 October 2026
Draft. Accurate as of the date above and written from the code, but not yet reviewed by the team for publication.
One workspace cannot read another
Separation is enforced by row-level security in PostgreSQL — 62 policies — not by the application asking nicely. The product reads the database as the signed-in person, so the same rules apply whichever screen, script or API call is asking. A key that is not signed in reaches nothing at all.
A candidate record that a workspace paid for — a CV, or purchased enrichment — is visible only to that workspace.
Contact details are not a readable column
Email addresses and phone numbers cannot be selected from the candidate table by anyone. A single function returns them, and only after checking that the workspace owns the record and that the candidate has granted consent. This is why the product shows a consent notice where a phone number would normally be.
What a recruiter may do is decided in the database
- One recruiter owns a relationship. Taking a candidate past the shortlist claims them; a colleague is refused, and has to ask for a transfer, which the holder — or a lead, after three days — decides.
- Outreach passes a gate on every send. It sits on the table the message is written to, so no surface can bypass it: not the console, not a future sending service, not a script run by an administrator.
- A recruiter’s activity is visible to that recruiter and to talent-acquisition leads, not to the whole team. A claim is visible to everyone, because that is what stops two people approaching the same candidate.
Links sent to people without accounts
A hiring manager reviews a shortlist through a link rather than an account. The link lives seven days, and only a SHA-256 hash of it is stored, so it cannot be recovered and shown again by anyone — including us. Reading the shortlist and deciding on it are different rights: a decision additionally requires the address the shortlist was sent to and a six-digit code emailed to it, and the code’s hash is not readable by the workspace either. Twenty failed attempts burn the link.
Accounts
- Sessions are held in httpOnly cookies and verified on every request.
- A colleague joins a workspace by email domain only after the address is verified, so an unconfirmed address cannot read a company’s data.
- Sign-up is closed: accounts are created by us, or by invitation from the workspace.
- The administrative key that bypasses row-level security is used in seven places on the server, each one commented, and never reaches the browser.
Hosting
Data sits in ap-south-1 (Mumbai) on Supabase, which runs on AWS, with encryption in transit and at rest. A dedicated tenant is available so no two customers share a candidate store.
What is not built yet
Saying so is part of the security posture rather than an exception to it:
- no third-party penetration test has been carried out;
- no formal certification (ISO 27001, SOC 2) is held, and none is claimed anywhere in this product;
- retention and re-consent periods are configured but not yet enforced by a scheduled job — deletion is carried out on request;
- there is no automated alerting on unusual access.
Reporting something
To be filled in before publication: the security contact address, and how quickly we undertake to respond to a report.