Files
2026-05-27 23:29:53 +01:00

3.3 KiB

Capability Spec Delta: api-tenant-resolver-header (api-tenant-resolver-header)

Package: @suaveplan/api-tenant-resolver-header Status: PROPOSED

Every requirement below carries a **Verified by:** line at authoring time.

ADDED Requirements

Requirement: Resolves tenant from configured header

The package SHALL expose createHeaderTenantResolver({ headerName, validate, registry }) that reads headerName (default X-Tenant-Id) and returns { tenantId, source: "header" } when the value validates AND (when registry is supplied) is a member of the tenant registry.

Scenario: well-formed header resolves

  • WHEN a request carries X-Tenant-Id: acme AND acme is in the registry
  • THEN the resolver returns { tenantId: "acme", source: "header" } AND api.tenant.resolves_total{resolver="header"} increments

Verified by: src/resolver/resolver.test.ts::"well-formed header resolves"


Requirement: Strict mode behaviour for invalid values

The package SHALL react to invalid header values per strict config: when strict: true, raise TENANT_HEADER_INVALID (HTTP 400). When strict: false, return null so a downstream resolver may match.

Scenario: strict raises 400

  • WHEN the header value fails the validator AND strict: true
  • THEN the resolver raises TENANT_HEADER_INVALID

Scenario: non-strict returns null

  • WHEN the header value fails the validator AND strict: false
  • THEN the resolver returns null

Verified by: src/resolver/resolver.test.ts::"strict mode raises 400 on invalid" AND src/resolver/resolver.test.ts::"non-strict mode returns null on invalid"


Requirement: Trusted-source enforcement

The package SHALL ignore the header when request.metadata.source is not in trustedSources (default ["service-mesh"]). When ignored AND strict: true, raise TENANT_HEADER_UNTRUSTED_SOURCE; when ignored AND strict: false, return null.

Scenario: untrusted source raises in strict

  • WHEN the header is present AND request.metadata.source = "edge" AND trustedSources = ["service-mesh"] AND strict: true
  • THEN the resolver raises TENANT_HEADER_UNTRUSTED_SOURCE

Verified by: src/trust/trust.test.ts::"untrusted source raises in strict mode"


Requirement: Not-found-in-registry distinct from invalid

The package SHALL distinguish a tenant that fails validation (TENANT_HEADER_INVALID) from one that is well-formed but not in the registry (TENANT_HEADER_NOT_FOUND_IN_REGISTRY). Both surface in strict mode; both return null in non-strict mode.

Scenario: well-formed but unknown tenant

  • WHEN the header is X-Tenant-Id: unknown-tenant-1 AND the registry does not contain it AND strict: true
  • THEN the resolver raises TENANT_HEADER_NOT_FOUND_IN_REGISTRY

Verified by: src/resolver/resolver.test.ts::"well-formed but unknown raises NOT_FOUND_IN_REGISTRY in strict"


Requirement: Passes runTenantResolverConformance

The package SHALL pass the conformance harness exported by @suaveplan/api-tenant-provider/testing.

Scenario: conformance passes

  • WHEN runTenantResolverConformance("header", makeHeaderResolver) runs
  • THEN every harness it(...) passes

Verified by: src/resolver/resolver.spec-conformance.test.ts::"header resolver passes runTenantResolverConformance"