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