Multi-tenancy and Isolation
SecuSiem — Multi-tenancy and Isolation
Multi-tenancy and Isolation
Multi-tenancy and Isolation
SecuSiem implements complete multi-tenant isolation at every layer of the architecture.
Naming Convention
Pattern: {type}-{client_code}-{environment}
Examples:
Loki tenant_id: tenant-acme
S3 bucket: secusiem-acme-logs
Grafana org: ACME Corporation (ID: 5)
Authentik group: SecuSiem-acmeIsolation Methods by Component
| Component | Method | Implementation |
|---|---|---|
| Loki | Tenant ID | X-Scope-OrgID header per request |
| S3 | Bucket | Dedicated OVH bucket per tenant (AES256 encryption) |
| Grafana | Organization | Separate organization, isolated datasource |
| Authentik | Group | SSO group with tenant_slug attribute |
| PostgreSQL | Column | tenant_id as foreign key on all tables |
| Redis | Prefix | Key prefixed with tenant:{code}: |
Loki Isolation
Loki is configured with auth_enabled: true in the Helm values. Every request to Loki contains the X-Scope-OrgID header that identifies the tenant.
The ingestion-api automatically adds this header when forwarding logs:
async with httpx.AsyncClient() as client:
response = await client.post(
f"{settings.loki_url}/loki/api/v1/push",
headers={
"X-Scope-OrgID": loki_org_id, # tenant-{slug}
"Content-Type": "application/json"
},
json=push_request.dict(),
)Required Loki Labels
# Indexed labels
tenant_id: string # "tenant-acme"
app: string # "conformvault", "api"
environment: string # "production", "staging"
severity: string # "debug", "info", "warning", "error", "critical"
source_type: string # "kubernetes", "syslog", "api"
# Security labels (added by detection)
security_event: string # "sql_injection", "brute_force"
mitre_technique: string # "T1190", "T1110"S3 Isolation
Each tenant has a dedicated OVH S3 bucket, created automatically by the S3Manager during provisioning:
- Versioning enabled for data protection
- Lifecycle policy: GLACIER archival after 90 days, deletion after 365 days
- Encryption: AES256 at rest
- CORS: Configured for
https://*.secuaas.ca
Grafana Isolation
Each tenant has its own Grafana Organization created via the admin API. The Loki datasource is configured with the tenant-specific X-Scope-OrgID.
Database Isolation
All PostgreSQL tables use a tenant_id column as a foreign key to the tenants table. Queries are systematically filtered by tenant.
Security
| Aspect | Implementation |
|---|---|
| API Keys | bcrypt hashing, sk_live_ prefix, rotation, expiration |
| TLS | TLS 1.3 for all communications |
| Encryption at rest | S3 AES256, PostgreSQL encrypted volume |
| Rate limiting | Redis-based, configurable per tenant |
| Audit | audit_logs table for all operations |