Docs / Security and data

Personal data

Where personal data lives, who can read it, what is masked, exported or logged, and the rules new code follows.

Applications, references and profiles hold names, emails, phone numbers, tax ids, bank summaries, signatures, documents and free text. This page states what the services do today (see .claude/rules/data-access.md for the direction).

Who reads what#

ReaderSees
Applicanttheir own applications, documents and profile; never reference responses on application-linked references
Supplier role with applications.viewapplications and references of their own organization only (tenant scope in every query)
Supplier role without applications.decide over MCPtax id masked to the last four digits, bank fields omitted
Reference providerthe one request their private link opens
Staffcross-tenant, through staff-only routes; reads and changes are audited where listed in Audit trail and evidence
Connectors and the MCP serveronly what core endpoints that already authorize the caller return; they never hold a database login

Rules the code follows#

  • New queries go through a repository per aggregate; controllers do not call prisma directly in new code.
  • Personal fields are tagged // pii: <kind> where declared (schema and contracts). Tagging is not complete yet; add the tag when you touch a field.
  • Never log personal data. Log lines use hashed or masked identifiers (shared/log-pii.ts). Audit rows hold ids and an IP hash, never values.
  • Personal data stays out of URLs, error messages and analytics. Reference and invitation links carry opaque tokens only.
  • Object storage is private: browsers get short-lived signed URLs after an authorization check, never a stored path.
  • Signature images are served with no-store, nosniff and a locked CSP.

Export and deletion#

  • A person can download their own data: GET /v1/profile/export returns a JSON file (profile, business profile, own applications, notifications, saved references; the stored default signature is left out), limited to 5 exports per hour and audited as user.data_exported. See Profile and account API.
  • A person can deactivate their account with an emailed code (POST /v1/auth/delete-account/code, then /auth/delete-account); the browser session ends with it.
  • Credit teams can export their organization's applications and references as CSV. See Exports API.

Not done yet: field-level encryption, and audit events for CSV exports and staff reads of personal data. Do not assume either exists.