Legal

Security Posture

Last updated April 17, 2026

The summary an enterprise procurement or security team will want. Everything below is a property of the schema and the deployment configuration, not a marketing claim. If you want the software-development-and-operations control set behind a SOC 2 audit, email gene@updocmedia.com and we will send the current control narrative and status.

1. Structural anonymity of survey responses

The responses table in the primary Postgres database has no user_id column and never will. Instead, each answer row carries:

  • A salted SHA-256 token (anon_token_hash) that ties the 17 answers from one respondent's sitting together without being reversible.
  • A submission timestamp bucketed to 15-minute windows (submitted_bucket), so a unique submission time cannot be used to identify a respondent.
  • The cycle, cohort, and question identifiers needed for aggregation, plus the numeric score.

Aggregate scores are suppressed below five respondents per cohort at the SQL layer (get_cycle_dimension_scores RPC), so any route that reads scores (dashboard, results page, CSV export, API) inherits the suppression floor automatically.

2. Tenant isolation via Postgres RLS

Every organization-scoped table in the public schema has Row-Level Security enabled, and its policies run through a single SECURITY DEFINER function, is_org_member(org_id). A user can only read or write rows in organizations they are a member of, enforced by Postgres at the query planner, not by application code. An application-layer filter mistake cannot leak data across tenants.

3. Append-only audit log

The audit_log table records every state-changing action. UPDATE and DELETE privileges on that table are revoked from the authenticated, anon, and service_role roles. Not even UpDoc's own service role can rewrite an audit row without a migration that itself would be in Git history. This is the foundation for SOC 2 evidence and for supporting customer-initiated data subject requests.

4. One-time access codes

Respondent access codes are 8 characters drawn from a reduced alphabet (no 0/O/1/I/L). Codes are bcrypt-hashed at rest; verification uses a constant-time bcrypt compare. A HMAC-SHA256 lookup hash is stored alongside the bcrypt hash so an inbound code can be located in O(1) without enumerating bcrypt rows. Plaintext codes exist only in the browser at issuance; once the owner navigates away, the plaintext is gone.

5. Transport and at-rest encryption

All inbound traffic is TLS 1.2+, terminated at the edge by the hosting provider. HSTS is set to two years withincludeSubDomains; preload. All Customer Data is stored encrypted at rest by the database host. Database credentials and third-party secrets live in the hosting provider's environment variable store, never in the repository.

6. Authentication and SSO

Available today

  • Email magic-link (Supabase Auth, PKCE flow).
  • Google Workspace (OAuth 2.0).
  • Microsoft Entra ID / Azure AD / Microsoft 365 (OAuth 2.0, multitenant).

Enterprise, on request

  • SAML 2.0 with Okta, OneLogin, Ping, JumpCloud, or a custom IdP.

Platform-admin protection

UpDoc-staff cross-tenant access is gated by a server-only flag (app_metadata.platform_admin) that customers cannot set from within the product. Every cross-tenant view is audited.

7. Rate limiting and abuse prevention

Sign-in requests, survey submissions, and OAuth starts are rate-limited per IP and per email (where applicable) to stop spray-and-pray attacks against bcrypt and against our email delivery. Survey submissions use a HMAC lookup before the bcrypt compare so a burst of invalid codes does not consume CPU at the bcrypt step.

8. Backups and disaster recovery

The primary database is on Supabase's managed Postgres platform with point-in-time recovery. Backups and disaster recovery guarantees follow the platform SLA. Backups inherit the same encryption at rest as the live database.

9. Vendor abstraction

Every third-party dependency sits behind a typed port interface: Auth, Billing, Mail, Rate-Limit, AI. Replacing a vendor is a single-file adapter change. This reduces the impact of a subprocessor incident: we can swap a compromised vendor within hours, not re-architect the product.

10. Compliance posture

  • SOC 2 Type I: in progress. We will not claim certification until the attestation letter issues.
  • GDPR / UK GDPR / Swiss FADP: aligned. See Privacy Policy and DPA. Structural anonymity of responses removes them from the scope of "personal data" by design.
  • US state privacy laws (CCPA, CPRA, VCDPA, CPA, CTDPA, UCPA): aligned. We do not sell personal data and do not process for targeted advertising.
  • HIPAA: not in scope. Hiyer is not a covered entity or business associate; the schema does not support PHI.

11. Vulnerability reporting

If you believe you have found a security issue in Hiyer, email gene@updocmedia.com with subject "SECURITY". We acknowledge reports within two business days. We do not currently run a public bug bounty; a private disclosure program is planned for 2026.