Skip to content

Multi-tenant daemon isolation (authenticated principal) #358

Description

@mostafa

Summary

Add logical multi-tenancy to rsigma engine daemon so one process can serve many tenants without cross-tenant leakage in correlation state, alert/risk stores, sink routing, rules, enrichment, snapshots, or control-plane API reads. Tenant identity is bound only from an authenticated principal, never from event payload fields or unsigned headers.

Motivation

MSSP and SaaS deployments ingest logs for many customers into one detection pipe. Today correlation windows, alert dedup, risk entities, and API reads are daemon-global, so identical group_by keys from different customers share state. Community PR #163 proposed isolating correlation by an event field (--tenant-field); that is client-controlled content and is not a security boundary.

Design principle

Aligned with OWASP Multi Tenant Security:

  • Establish tenant context at the edge from a verified principal.
  • Never trust tenant IDs from the event body, query params, or unsigned client headers.
  • Propagate context through every layer; key all state by tenant.
  • Fail closed when tenancy is enabled and context is missing.

Proposed approach

Allowed bindings

  • HTTP/OTLP: token.tenant on the shipped daemon API auth principal.
  • NATS: authenticated user/NKey → tenant map in config (not subject-token parsing).
  • Dedicated source: static tenant: when the whole pipe is one tenant by construction.
  • Optional later: signed publisher-assertion header (JWT/HMAC from an edge after publisher auth) for shared fan-in.

Isolation surfaces

  • Composite correlation StateKey including TenantId; snapshot schema bump.
  • Tenant-keyed alert dedup, risk entities, silences/dispositions.
  • Send-time {tenant} sink routing with validated tenant charset.
  • Per-tenant state quotas and tenant-aware eviction.
  • Rule directory scoping (rules/tenants/<tenant>/) and enricher tenant filters.
  • API reads scoped to the principal's tenant (admin tenants:* escape).

Out of scope

  • Process-level crash/memory isolation (deploy one daemon per tenant for that).
  • Treating event fields or X-Rsigma-Tenant as identity.
  • Kafka I/O (orthogonal to PR Kafka support and multitenant awareness #163's Kafka half).
  • Multi-node clustering (consumes TenantId in keys once this ships).

Tasks

  • Phase 0: TenantId validation, TenantContext, config/CLI skeleton, threading
  • Phase 1: correlation StateKey + snapshot v2 + tenant_id on all results
  • Phase 2: principal bindings (API token, NATS user map, static source)
  • Phase 3: per-tenant quotas / eviction
  • Phase 4: send-time output routing
  • Phase 5: alert/risk/silence keys; rule + enricher scoping
  • Phase 6: fail-closed API filter; gated metrics; docs; CHANGELOG
  • Optional follow-on: verified publisher-assertion header for shared bus fan-in

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestrustPull requests that update rust code

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions