Skip to main content

Notification Tenant Isolation

Summary

The Notification Service is a cross-tenant consumer. NotificationDbContext applies no global tenant query filter by design; tenant scoping is applied explicitly on each query. The tenant identifier flows from the consumed event header and is nullable.

Scoping model

Per-query scoping (verified)

  • Templates resolve a tenant-specific active row first, then fall back to the global default where TenantId is null.
  • Recipients are keyed and upserted by (TenantId, RecipientType, ExternalRef).
  • Preferences are evaluated with the tenant, recipient and channel in the predicate.
  • Inbox reads filter by the supplied tenantId and recipientRef.
  • Idempotency and audit rows carry the tenant for traceability.

Deliberate cross-tenant posture

Because the service observes every tenant’s events, the DbContext comment documents the absence of a global filter as intentional. This places responsibility for correct tenant scoping on each query rather than on a context-wide guard.

Isolation risks (verified)

Endpoints accept tenantId as a caller-supplied parameter with no authenticated tenant claim. A query that omits tenantId (or supplies another tenant’s value) is not blocked by a context-level filter, so isolation depends on callers passing the correct value and on upstream enforcement.

Requires Confirmation

Whether upstream components guarantee the correct tenantId on every notification request, and whether a defense-in-depth tenant guard is planned, require confirmation.

Source References

  • microservices/src/notification-service/Infrastructure/NotificationDbContext.cs
  • microservices/src/notification-service/Application/NotificationDispatcher.cs
  • microservices/src/notification-service/Application/TemplateEngine.cs
  • microservices/src/notification-service/Api/NotificationEndpoints.cs

See Also

Keywords

Tenant isolation, multi-tenancy, query scoping, global default, cross-tenant.

Revision Information

  • Status: Draft
  • Last reviewed: 2026-07-21
  • Next review: 2026-10-21