Tenant ID is not a filter preference

In a multi-tenant product, the tenant identifier is a security boundary. Treating it as an optional query parameter creates a design where one missed filter can expose another customer's records.

The authenticated context should resolve the tenant or account before business logic runs. Services should receive that trusted scope and repositories should require it for every account-owned query and mutation.

Use layered enforcement

No single control is enough. Browser route guards improve usability but are not authorization. API middleware helps, but individual services can still issue unsafe queries. Row Level Security is powerful, but background jobs and privileged connections need equally careful context handling.

  • Identity: resolve the authenticated user, tenant memberships, and active tenant.
  • Authorization: check role and permission for the requested operation.
  • Service layer: pass tenant scope explicitly and reject cross-scope identifiers.
  • Database: include tenant predicates, composite ownership constraints, or Row Level Security.
  • Async work: store and revalidate tenant context in every queued job.
  • Exports and files: scope generated artifacts and signed access to the same tenant.

Relationships need tenant integrity too

A row can carry the correct tenant ID and still point to a parent from another tenant. Composite foreign keys or validated ownership checks prevent these cross-tenant relationships from entering the database.

This becomes especially important in hierarchical products involving campaigns, projects, facilities, packages, contacts, evidence, or geographic records.

Test denial, not only success

Most feature tests prove that an authorized user can complete a workflow. Multi-tenant assurance requires equally deliberate negative tests: a user from Tenant A cannot read, mutate, export, attach, or infer Tenant B data.

The most valuable tests exercise service boundaries, repository predicates, stored procedures, background jobs, generated exports, stale concurrency paths, and administrative roles.

Make isolation observable

Audit records should include the acting user, tenant scope, operation, object identity, and result without leaking sensitive values. Operational alerts should detect repeated cross-scope denials, malformed tenant context, and jobs that cannot resolve their expected owner.

Good isolation is not merely an implementation detail. It is a product capability that enterprise customers need to trust.