Security
How ClimaHQ protects your organization's data at every layer, from the network edge to the database row.
Data Isolation
Multi-tenant architecture with database-enforced boundaries.
PostgreSQL Row-Level Security
Every tenant-scoped table has a row-level security policy that filters rows by organization. Enforced by Postgres itself, not application code, so even a bug in our controllers cannot leak data across tenants.
Per-Request Tenant Context
Each request sets a Postgres session variable with the authenticated organization ID, and clears it when the request finishes. RLS policies reference this variable, ensuring queries never return another tenant's rows.
UUID Primary Keys
All records use UUIDv4 identifiers instead of sequential integers. Resource IDs cannot be guessed or enumerated.
Encryption
Data protected in transit and at rest.
TLS Everywhere
All traffic is encrypted with TLS. HTTPS is enforced in production with HSTS headers, and plaintext HTTP requests are automatically redirected.
Encrypted Sensitive Attributes
Demographic attributes (gender, ethnicity) used for equity analysis, along with survey text responses and integration credentials, are encrypted at the application layer using AES-256-GCM before being written to the database.
Hashed API Keys
API keys are SHA-256 hashed before storage. We never store the raw token. It is shown once at creation and cannot be retrieved again.
bcrypt Password Hashing
User passwords are hashed with bcrypt. Raw passwords are never stored or logged.
Anonymity & Privacy
Employee trust is the foundation of honest culture data.
5+ Response Minimum Threshold
Groups below the anonymity threshold, at least 5 responses and configurable higher per organization, are automatically hidden from every dashboard, export, and report. This prevents managers from identifying individual respondents in small teams.
Aggregate-Only Reporting
All culture scores, equity metrics, and compliance reports are computed from aggregated data. Individual survey responses are never displayed to administrators or managers.
No Individual Identification
Survey responses are pseudonymous and are never surfaced to managers or administrators as individual records, only as part of an aggregate of 5 or more responses. Row-level security and policy-based access control enforce this at the database and application layer.
Application Security
Headers, policies, and browser protections.
Content Security Policy
A CSP restricts script, style, image, and frame sources, with nonce-based script allowlisting on every request. frame-ancestors is set to 'none' to prevent clickjacking.
Strong Parameter Whitelisting
All controller actions use explicit parameter permit lists. Blanket permit is forbidden by project policy and enforced in code review.
Sensitive Parameter Filtering
Passwords, tokens, API keys, and other sensitive values are automatically redacted from application logs.
Continuous Security Testing
Automated checks on every commit.
Static analysis scanner that checks for SQL injection, XSS, mass assignment, and other Rails-specific vulnerabilities on every CI run.
Checks all Ruby gem dependencies against the Ruby Advisory Database for known CVEs before every deploy.
Scans vendored JavaScript dependencies for known vulnerabilities.
Questions about our security practices?
We're happy to discuss our architecture, answer security questionnaires, or walk you through our approach to protecting employee data.