Security built into the hiring workflow.

Scoreboad is designed to keep hiring information controlled, reviewable, and connected to the people responsible for hiring decisions. Everything on this page is a mechanism in the product today — described precisely, with the gaps named rather than left out.

  1. Candidate dataApplications, resumes, screening answers
  2. ScoreboadSession, role and workspace decide what opens
  3. Human reviewA named person makes the decision

Overview

Security across the hiring lifecycle.

Five areas, each one backed by a mechanism in the product rather than a posture.

  • Access

    Who can interact with hiring information?

    A session identifies the person, a role decides what they may do, and both are checked again in the database. Four roles: Owner, Admin, Recruiter and Viewer.

  • Data

    How is information kept in the right workspace?

    Every table carries an organization and a row-level policy. A record addressed by an id from another workspace comes back as not found.

  • AI

    How is AI-generated information handled?

    A model returns a structured result that is checked in code before anyone sees it. It holds no database handle and no tools.

  • Review

    Where do people inspect what was produced?

    AI output is shown beside the material it came from, on a screen built for correcting it. What the model said is kept alongside the correction.

  • Audit

    What activity can be traced afterwards?

    Eighty-six catalogued event types record who did what, to which record, and when. Access-changing events are restricted to Owners and Admins.

Architecture

What a request passes through.

Eight layers, in order. Each one names the mechanism that performs it.

  1. User or team memberEdge
  2. AuthenticationEdge
  3. AuthorizationServer
  4. WorkspaceServer
  5. Access policyDatabase
  6. DataDatabase
  7. AI workflowServer
  8. Human reviewPerson

User or team member

Signs in with email and password or Google, through Supabase Auth.

The architecture in full

User or team member
Signs in with email and password or Google, through Supabase Auth.
Authentication
An HTTP-only session cookie, refreshed at the edge on every request. Routes are protected by default: anything not on the public allowlist requires a session.
Authorization
The route resolves the workspace and the role from that session — never from the URL, the body or a header.
Workspace
The active-workspace cookie is only a hint. It is re-checked against real membership rows on every request, so a forged value yields the default workspace rather than access.
Access policy
Row-level security is the real boundary, not the route handler — the browser holds an authenticated database client, so a rule that exists only in application code is not a rule.
Data
Jobs, candidates, applications, interviews and evaluations, each row owned by one workspace and reachable only from it.
AI workflow
Structured input in, a validated structure out. No tools, no database handle, and no write to a candidate's record.
Human review
A person reads the result beside its source and decides. The decision is recorded against them.

Access control

Access should follow responsibility.

Hiding a button is cosmetic — a request made with curl never runs your interface. So each access rule is written in three places, and the database is the one that decides.

  1. Interface

    Controls a role may not use are not rendered. This is for clarity, and it is treated as carrying no security weight at all.

  2. API

    Every route handler resolves membership and role from the session before it does anything else. Five routes are public by design — the application form, three candidate coding-session routes and one webhook — and each is authorised by a signed token or an HMAC signature instead.

  3. Database

    Row-level security policies and role-checking functions, plus triggers for the rules a policy cannot express: only an Owner may grant or revoke Owner, nobody may change their own role, and a workspace cannot be left without an Owner.

The four roles

  • Owner
  • Admin
  • Recruiter
  • Viewer

Data isolation

One workspace cannot reach another.

Every table that holds hiring information carries the workspace that owns it, and row-level security decides what a query returns — including a query the application never wrote.

Workspace A

  • Jobs
  • Candidates
  • Applications
  • Interviews
  • Evaluations

Workspace B

  • Jobs
  • Candidates
  • Applications
  • Interviews
  • Evaluations
  • Not found, not forbidden

    An id belonging to another workspace returns 404. Answering 403 would confirm the record exists, which is an oracle worth nothing to a legitimate user and a great deal to anyone enumerating ids.

  • The session decides the tenant

    Never a request body, a query parameter or a header. Those are attacker-controlled by definition.

  • Cross-workspace parents blocked

    Around twenty triggers stop a correctly-owned row from pointing at another workspace's parent record — the shape of isolation bug that a per-table policy on its own will not catch.

Data handling

Treat hiring information as sensitive workflow data.

Resumes, applications, screening answers and interview feedback are all written by people who did not ask to be processed by software. What follows is what the product enforces at each edge.

  • Files

    • Storage buckets are private. No uploaded file is served from a public URL.
    • A 10 MB cap, set on the bucket and checked again in the route.
    • The bucket's own type allowlist is the real gate; the route's extension check exists to give a usable error at the file picker.
    • Reads go through a short-lived signed URL — five minutes for a resume, one minute for an onboarding document — issued only after the caller's workspace is checked.
  • Input

    • Ids are shape-checked before they reach a query, and updates run against a field allowlist rather than trusting the body's keys.
    • Database CHECK constraints carry the rules that are about the data rather than the request — ranges, ordering, currency and key formats.
    • Queries are parameter-bound; there is no raw SQL in application code, and no HTML is ever injected into the page.
  • Webhooks and credentials

    • The one inbound webhook verifies an HMAC signature over the raw body and refuses anything else.
    • Integration credentials are stored as AES-GCM ciphertext behind a column-level revoke, so they cannot be read through an ordinary query at all.
    • The public application form is rate-limited per source and per form.
  • What is written down

    • Message recipients are masked when the log row is written, not when it is displayed.
    • IP addresses are never stored raw — only a keyed HMAC, which cannot be read back.
    • No password, token or credential is written to a log anywhere in the codebase.

AI and human review

AI supports the workflow. People stay in control.

Every AI feature returns a structured result that is checked in code and then shown to a person beside whatever it was derived from. No model writes to a candidate's record, and when the provider is unavailable the manual workflow still works.

  1. InputResume text, an application, a call transcriptInput
  2. AI processingA named function with structured input — never a free-form prompt boxAI
  3. Structured resultA typed shape, or a failure that is handledAI
  4. ValidationChecked in code before anyone sees it; generated prose cannot contradict a displayed figureCode
  5. ReviewOn screen, beside the source, on a page built for correcting itPerson
  6. DecisionMade by a person and recorded against themPerson
  • The model holds nothing

    No tool access and no database handle. It receives structured input and returns text.

  • What it said is kept

    A screening report stores the AI's original fields and the correction separately, so what the model produced and what a person changed it to are both visible afterwards.

  • Consent is not a setting

    The screening call opens by saying it is automated and may be recorded. That disclosure cannot be reordered or switched off.

Nothing here claims the AI is unbiased, accurate or objective. It is not audited for bias, and no part of the product treats its output as a finding — which is why a person reads it before it counts for anything.

Auditability

Important activity stays traceable.

The activity log is a closed catalogue of eighty-six event types, so every row renders as a sentence rather than a raw slug — and so a summary of it can be checked against it.

Who
The person, recorded as an actor on the row
What
One of eighty-six catalogued event types
Which
The entity it happened to, and its workspace
When
A timestamp, in the workspace's own timezone
  • Events that change who can do what — role grants, invitations, removals — are marked sensitive and restricted to Owners and Admins by the same row-level policy that protects everything else.
  • A role change records both the old value and the new one.
  • An event type the catalogue does not know still stores and still renders, as its raw name. Losing an audit row to a missing label would be worse than an ugly one.

This is an activity record, not a tamper-evident ledger. It is not claimed that every action in the product is logged permanently.

Privacy

Privacy belongs in the workflow.

Candidate information is handled where hiring happens rather than in a separate compliance surface. These are the controls that exist in the product today.

  • In-product privacy controls

    An organisation's administrators have a privacy screen in the product — retention settings and candidate data handling live there, beside the workspace they apply to.

  • Candidates are told, and can leave

    The screening call discloses that it is automated and may be recorded. Outbound messages carry an unsubscribe link that is a signature rather than a stored token, so it cannot be leaked from a database copy.

  • Contact details are minimised in logs

    A recipient is masked in the log row itself, and the full address stays on the candidate's record where it belongs.

How this information is handled end to end — what is collected, what AI does with it, and what is not in place yet — is set out in full on the privacy page. Read the Scoreboad privacy page

Principles

Six things this product does.

Each one restates a mechanism described above, so no principle here can be true on this page and unsupported further up it.

  • Controlled access

    Four roles, checked in the interface, the API and the database. The database check is the one that counts.

  • Data boundaries

    Every row belongs to a workspace, and row-level security decides what a query returns rather than the code that wrote it.

  • Human review

    AI proposes, a person applies. There is no path through the product that turns model output into a decision on its own.

  • Validated workflows

    Uploads, ids, webhook payloads and AI output are all narrowed before use, with database constraints as the backstop.

  • Auditability

    A closed catalogue of events records who did what and when, with access-changing events restricted to Owners and Admins.

  • Minimised by default

    Recipients masked at write time, IP addresses stored only as a keyed hash, credentials encrypted behind a column-level revoke.

Status

What Scoreboad does not have.

A security page that lists only strengths is an advertisement. These are the gaps, named because finding them out later is worse than reading them now.

  • No certifications

    No SOC 2, ISO 27001, HIPAA, PCI DSS or CCPA attestation. None is held, none is in progress, and no badge appears anywhere on this site.

  • No third-party audit

    No penetration test and no external security review has been carried out.

  • No Content-Security-Policy

    Five security headers are set — framing, sniffing, referrer, transport and permissions. A CSP is not among them, because a policy loose enough to ship quickly would be theatre.

  • No multi-factor authentication

    No MFA, no session-revocation screen and no login-attempt lockout of our own.

  • No malware scanning

    Uploads are type-checked and size-capped, and they are never executed or served from our origin — but their contents are not scanned.

  • No published security contact

    There is no security address to report an issue to yet, and inventing one would be worse than the gap: a report sent into nowhere is a vulnerability nobody is working on.

Where the rest of this is written down

See the workflow these controls are built around.

The walkthrough covers the whole flow, end to end, including where a person has to sign off.