Security
Opangle holds CVs, interview notes and salary data. Here is what protects them, described specifically enough to be checked.
Customers are separated in the database
Every table carries the workspace it belongs to, and row-level security is enforced by PostgreSQL rather than by application code. Each request runs under the identity of the person making it, so a query cannot return another customer's rows even if the application asks for them.
This is verified by an automated test suite that signs in as one customer and attempts to read and write another's data. Those tests run on every change.
And within a customer
An interviewer sees only candidates on the jobs they are assigned to. Salary and offer terms are withheld from roles that should not see them — not hidden in the interface, but absent from the response. Both are enforced at the query layer and both are tested.
Voluntary diversity answers are stored in a table with no read access for any role, including the workspace owner. Only aggregate reports can reach it, and any group of fewer than five people is suppressed.
Files
CVs and signed documents are stored privately and served through links that expire. There is no permanently public URL for a candidate's CV. Uploads are checked by content rather than by filename, so a file claiming to be a PDF is rejected if it is not one.
AI
We use the paid tier of Google's Gemini API, which under Google's terms does not train on submitted content. The application refuses to start if it is configured against the free tier, because the free tier does train on what is sent to it.
Our AI schemas contain no field for age, gender, ethnicity, religion, disability or marital status. A model cannot record what there is nowhere to put.
Every AI call is logged with the model, the prompt version, the cost and the outcome. That record is what makes a score reproducible months later.
Audit
Stage changes, rejections, offers and AI-influenced actions append to a log that cannot be edited or deleted — no application role holds the permission to do so, and a database trigger refuses it independently. Where a decision followed AI output, the log records which output was on screen.
Sub-processors
- Supabase — Database, authentication and file storage (United States)
- Vercel — Application hosting (United States / global edge)
- Google (Gemini API) — AI processing of CVs and hiring records — paid tier, not used for model training (United States)
- Cloudflare — Scheduled background processing (Global edge)
- Resend — Transactional email delivery (United States)
- Polar — Payments and invoicing (merchant of record) (United States / EU)
Reporting something
If you believe you have found a vulnerability, write to hello@opangle.com. We will acknowledge within two working days. Please give us a reasonable chance to fix it before publishing.