Security
Security as an invariant, not a feature.
Multi-tenancy boundary enforced at the AST level. mTLS agents with auto-rotation. An immutable audit log. Details below.
Architectural invariants
- Every TSDB query is injected with an organization_id. composeQuery and rewritePromQL add organization_id as a mandatory matcher. There is no raw path for user input — cross-tenant data leakage is structurally impossible.
- Embed JWT model. API keys issue short-lived JWTs with mandatory filters baked into claims. Handlers read filters from claims, never the URL. Spoofing via a crafted URL is impossible.
- Secrets via SecretBox (AES-256-GCM). OAuth tokens, channel signing secrets and embed keys are stored encrypted with a master key. Plaintext never reaches the logs.
- Agent identity = verified client cert. Not a header, not the body. mTLS validation happens in the server TLS config, not in application code.
- JWT keys rotate with a kid header. Multiple signing keys live in memory during rotation. KeyRevocator invalidates issued tokens early when needed.
- Public dashboard tokens never take org_id from the URL. Org_id is resolved server-side from the token row — a hand-crafted URL cannot pivot organizations.
Authentication
- Cookie sessions with CSRF double-submit
- Password + bcrypt
- TOTP 2FA (RFC 6238)
- WebAuthn / passkeys
- OAuth: GitHub, Google, Apple
- Magic link for passwordless
- SCIM 2.0 for IdP auto-provisioning
Transport security
- Cabinet over HTTPS — TLS 1.2+, HSTS in production
- mTLS ingest — dedicated listener, mandatory client auth
- Agent certs — 24h TTL, auto-rotation
- Built-in agent CA, not a public one
Data at rest
- Postgres — disk-level encryption (managed) or app-level (SecretBox for secrets)
- TSDB — disk-level encryption (LUKS / cloud KMS)
- Backups — encrypted with your own key, not a shared one
Disclosure policy
Found a vulnerability? Email [email protected]. PGP fingerprint on request. We respond within 48 hours.
- Critical / RCE / data leak / auth bypass — patched within 7 days
- High — patched within 30 days
- Medium — patched within 90 days
- Low — in the next release
Public disclosure follows the fix release, crediting you if you wish. We pay a bounty for serious findings.
Subprocessors
The managed offering uses the subprocessors below. The full list with purpose and data scope is in the DPA document.
- Cloud hosting — infrastructure (US, EU regions)
- Global payment provider — payment processing
- Transactional email
- CDN + DDoS protection