Skip to content

The contractor portal

For admins

The contractor portal lets external contractors do four things — see what’s open against them, upload certificates, mark jobs complete, and optionally claim a permanent account — without you having to create a Keystone user for every plumber and PAT tester.

Each contractor record can have one or more access tokens. A token is a compound string (<uuid>.<secret>) that authorises one contractor (not one user). Only the SHA-256 hash of the secret is stored in the database — a leaked database does not yield working tokens. You email the URL with the token in the path to the contractor; they bookmark it.

When they visit /contractor/<token>, Keystone:

  1. Splits the token on the first . to recover the access-token UUID and the secret, then verifies the SHA-256 hash against the stored value.
  2. Resolves the token record to a contractor row.
  3. Renders the contractor’s landing page with their open jobs.

No password is asked for. The token is the credential.

  • View open jobs — inspections referencing this contractor.
  • Upload a certificate — drag-and-drop PDF/JPG against an inspection. Files run through the same attachment scan pipeline as the rest of Keystone, with quarantine on a virus hit.
  • Mark a job complete — outcome (pass / partial / fail) plus a free-text summary and optional inspector name.
  • Claim a permanent account — optional. Useful for contractors who do many visits a year. Promotes the token-only access into a full user with a password.

Tokens can optionally carry an expires_at date; expired tokens are rejected on every request. Tokens without an expiry live until you revoke them. Rotate the token if a contractor’s email is compromised or they part ways with the trust.

The contractor’s password policy (for claimed accounts) matches the trust’s standard policy. Don’t relax it for contractors.

  • Only the SHA-256 hash of the token secret is stored — once minted, the plain-text URL is gone from the server side. Re-issue a fresh token if a contractor has lost theirs.
  • Workspace context is set per-request from the token. A token from workspace A scanned by an admin already in workspace B will still land them on A — that’s intentional, since the contractor’s view should never be cross-tenant.
  • Don’t use a single contractor record for a multi-person firm. Issue one record per person if you need attribution; the audit log records the token, not the person at the keyboard.