Security model
Enforced invariants
- Tenant context comes only from a verified signed session or a scoped service token; request payloads cannot select a different tenant.
- HTTP APIs, WebSocket events, search, files, exports, media grants, administration, and integrations authorize at their resource boundary.
- Production startup fails closed when signing, encryption, integration-token, WebAuthn, or media configuration is absent.
- Passwords use Argon2id. Passkeys require user verification; TOTP supports one-use recovery codes; sessions are revocable and rate limited.
- Identity is passkey-first on network deployments: binding to a non-loopback
HOSTrefuses password-only sign-in and requires a WebAuthn passkey assertion for session issuance (non-overridable in production;HAILDECK_ALLOW_PASSWORD_LOGIN=1exists for non-production LAN testing only). Account recovery redeems one-time recovery codes, stored only as SHA-256 digests, through a heavily rate-limited endpoint. The automatic test identity is refused in production and requires an explicitHAILDECK_TEST_IDENTITY=1flag outside the test runner. - Tenant secrets are encrypted at rest, administrative changes enter a tamper-evident tenant audit chain, and webhook payloads are signed.
- Private rooms and direct messages require membership. File access, search results, realtime fan-out, recordings, and exports retain tenant boundaries.
- Browser policy is server-generated CSP, restricted origins, secure cookie policy, and no inline event handlers. The TLS edge is Caddy.
- Uploaded files are hashed, scanned by policy, quarantined when unsafe, quota limited, permission checked, and retention managed.
- Integrations use scoped service accounts and explicit commands; arbitrary in-process plugins are prohibited. Webhooks require HTTPS and reject local/private destinations.
Deployment responsibility
Replace every example secret before deployment, use public TLS names for the portal and LiveKit, restrict host administration, keep encrypted offline backups, and rotate exposed credentials immediately. The bundled persistent store is intended for this internal, self-hosted deployment and uses atomic file replacement plus tenant-scoped records and keys. PostgreSQL, external KMS, S3-compatible object storage, NATS, and OpenSearch are optional scale adapters, not runtime prerequisites.
Before admitting regulated or materially sensitive production data, complete organization-specific threat modeling, SAST/DAST and image/secret scans, an SBOM review, and an independent penetration test. Those external assurance activities cannot be represented by an application test suite.
Reporting
Do not include secrets or operational data in a vulnerability report. Record the affected version, reproduction steps, impact, and suggested containment through the private internal security process.
source: docs/SECURITY.md — rendered at build time; the repository copy is authoritative.