Files
git.stella-ops.org/docs/modules/notifier/prep/2025-11-20-ten-48-001-prep.md
master e950474a77
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
api-governance / spectral-lint (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
up
2025-11-27 15:16:31 +02:00

4.1 KiB

Notifier Tenancy Prep — PREP-NOTIFY-TEN-48-001

Status: Implemented (2025-11-27) Owners: Notifications Service Guild Scope: Tenancy model and DAL/routes for tenant context in Notifier WebService.

Overview

Tenant scoping for the Notifier module ensures that rules, templates, incidents, and channels are isolated per tenant with proper row-level security (RLS) in MongoDB storage.

Implementation Summary

1. Tenant Context Service (src/Notifier/StellaOps.Notifier.Worker/Tenancy/)

  • TenantContext.cs: AsyncLocal-based context propagation for tenant ID and actor
  • TenantServiceExtensions.cs: DI registration and configuration options
  • ITenantAccessor: Interface for accessing tenant from HTTP context

Key pattern:

// Set tenant context for async scope
using var scope = tenantContext.SetContext(tenantId, actor);
await ProcessEventAsync();

// Or with extension method
await tenantContext.WithTenantAsync(tenantId, actor, async () =>
{
    await ProcessNotificationAsync();
});

2. Incident Repository (src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/)

New files:

  • Repositories/INotifyIncidentRepository.cs: Repository interface for incident persistence
  • Repositories/NotifyIncidentRepository.cs: MongoDB implementation with tenant filtering
  • Serialization/NotifyIncidentDocumentMapper.cs: BSON serialization for incidents

Key features:

  • All queries include mandatory tenantId filter
  • Document IDs use {tenantId}:{resourceId} composite pattern for RLS
  • Correlation key lookup scoped to tenant
  • Soft delete support with deletedAt field

3. MongoDB Indexes (tenant-scoped)

Added in EnsureNotifyIndexesMigration.cs:

// incidents collection
{ tenantId: 1, status: 1, lastOccurrence: -1 }  // Status filtering
{ tenantId: 1, correlationKey: 1, status: 1 }   // Correlation lookup

4. Existing Tenancy Infrastructure

The following was already in place:

  • All models have TenantId property (NotifyRule, NotifyChannel, NotifyTemplate, etc.)
  • Repository interfaces take tenantId as parameter
  • Endpoints extract tenant from X-StellaOps-Tenant header
  • MongoDB document IDs use tenant-prefixed composite keys

Configuration

{
  "Notifier": {
    "Tenant": {
      "TenantIdHeader": "X-StellaOps-Tenant",
      "ActorHeader": "X-StellaOps-Actor",
      "RequireTenant": true,
      "DefaultActor": "system",
      "ExcludedPaths": ["/health", "/ready", "/metrics", "/openapi"]
    }
  }
}

Usage Examples

HTTP API

GET /api/v2/rules HTTP/1.1
X-StellaOps-Tenant: tenant-123
X-StellaOps-Actor: user@example.com

Worker Processing

public class NotificationProcessor
{
    private readonly ITenantContext _tenantContext;

    public async Task ProcessAsync(NotifyEvent @event)
    {
        using var scope = _tenantContext.SetContext(@event.TenantId, "worker");

        // All subsequent operations are scoped to tenant
        var rules = await _rules.ListAsync(@event.TenantId);
        // ...
    }
}

Handoff Notes

  • Incident storage moved from in-memory to MongoDB with full tenant isolation
  • Worker should use ITenantContext.SetContext() before processing events
  • All new repositories MUST include tenant filtering in queries
  • Test tenant isolation with multi-tenant integration tests
  • src/Notifier/StellaOps.Notifier.Worker/Tenancy/TenantContext.cs
  • src/Notifier/StellaOps.Notifier.Worker/Tenancy/TenantServiceExtensions.cs
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Repositories/INotifyIncidentRepository.cs
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Repositories/NotifyIncidentRepository.cs
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Serialization/NotifyIncidentDocumentMapper.cs
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Options/NotifyMongoOptions.cs (added IncidentsCollection)
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/Migrations/EnsureNotifyIndexesMigration.cs (added incident indexes)
  • src/Notify/__Libraries/StellaOps.Notify.Storage.Mongo/ServiceCollectionExtensions.cs (added INotifyIncidentRepository registration)