This document describes the Service's security posture, intended for IT security reviewers, public health inspectors, and customer procurement teams. It is current as of the date above and is updated when material changes occur.
Pool Operator Logbook is a browser-based progressive web application served as static assets from Netlify's edge CDN. The backend is PostgreSQL hosted on Supabase (Canada Central region). The application communicates with the backend over HTTPS using the Supabase JavaScript SDK and custom session tokens issued by server-side PostgreSQL functions.
pgcrypto extension. Plaintext PINs are never stored. The users.pin column has been dropped from the schema.must_change_pin; the operator must replace the PIN on first login before any other action is permitted.verify_pin RPC, 30-minute idle expiry, sliding renewal on activity. Stored client-side in localStorage and transmitted via the X-Session-Token header.operator can create entries and modify their own within the 24-hour edit window. supervisor and manager can edit any entry with a recorded reason, view the audit log, manage operators, and export organization data.users, sessions, pin_attempts, and audit_log have USING (false) RLS policies — they are accessible only via specific SECURITY DEFINER RPCs that perform additional permission checks.REVOKE INSERT, UPDATE, DELETE on the audit log. The log can only be appended via the audit trigger itself.editable_until = created_at + 24h. Within this window, operators can correct their own entries. After expiry, only managers can edit, and edits include a last_edit_reason field captured in the audit log.operator_id and operator_initials. RLS UPDATE policy prevents operators from modifying records attributed to other operators.Strict-Transport-Security: max-age=31536000; includeSubDomains; preload is set, instructing browsers to refuse non-HTTPS access.X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Permissions-Policy blocks geolocation, microphone, camera, payment, USB.eval or Function() constructors are used.| Data class | Retention |
|---|---|
| Operational records (tests, chems, etc.) | 7 years from entry |
| Audit log | 7 years |
| PIN attempts (security forensics) | 90 days |
| Expired sessions | Deleted nightly |
| Control | Status | Notes |
|---|---|---|
| PIN hashing (bcrypt) | Implemented | Work factor 10 |
| RLS on all tables | Implemented | Tested anon-cannot-read-PIN-hash |
| Audit log with diff viewer | Implemented | UI available in admin tab |
| Idle timeout | Implemented | 30 minutes |
| Rate limiting | Implemented | 5/min, 1-min lockout |
| Forced first-login PIN change | Implemented | For new + reset users |
| Security headers | Implemented | HSTS, CSP, X-Frame, etc. |
| XSS-escaped user content | Implemented | All user-typed fields |
| Multi-tenant org isolation (RLS) | Partial | org_id column on all tables; full per-org filtering pending |
| Two-factor authentication (TOTP) | Roadmap | Targeted for manager/supervisor roles |
| SSO (SAML / OIDC) | Roadmap | For municipal Azure AD integration |
| Penetration test | Roadmap | Pre-GA |
| SOC 2 audit | Roadmap | Type I targeted for 2027 |
| Web Application Firewall | Roadmap | Cloudflare in front of Netlify edge |
In the event of suspected unauthorized access or data tampering:
Security researchers are encouraged to report vulnerabilities directly to the Service operator named in your organization's pilot agreement. Good-faith reports are appreciated; we do not pursue legal action against researchers who follow responsible disclosure.
Direct security questions to your facility manager or the Service operator listed in your pilot agreement.