Documentation
¶
Overview ¶
Package tenant provides multi-tenant context helpers and a Connect interceptor that extracts a tenant ID from authenticated auth.Claims and stores it in the request context.
The interceptor must run AFTER the auth interceptor in the chain. Generated forge projects wire it via a thin shim in pkg/middleware/tenant_gen.go.
Index ¶
- func ApplyToContext(ctx context.Context, cfg Config, claimsFromContext ClaimsLookup) (context.Context, error)
- func ExtractClaim(claims *auth.Claims, field string) string
- func FromContext(ctx context.Context) string
- func NewInterceptor(cfg Config, claimsFromContext ClaimsLookup) connect.UnaryInterceptorFunc
- func Require(ctx context.Context) (string, error)
- func WithTenantID(ctx context.Context, tenantID string) context.Context
- type ClaimsLookup
- type Config
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyToContext ¶
func ApplyToContext(ctx context.Context, cfg Config, claimsFromContext ClaimsLookup) (context.Context, error)
ApplyToContext extracts the tenant ID from claims (read via claimsFromContext) and returns a context with the tenant ID set. If claims are not present, the context is returned unchanged. If claims are present but the tenant claim is empty, ApplyToContext returns a PermissionDenied connect.Error unless cfg.Optional is set.
This is the testable core of NewInterceptor; the interceptor wraps it with the AnyRequest plumbing.
func ExtractClaim ¶
ExtractClaim is the default claim-to-tenant-id mapping. It checks the requested field first, falls back to OrgID for unknown fields (preserves the legacy template behaviour).
func FromContext ¶
FromContext returns the tenant ID stored in the context (empty string when absent).
func NewInterceptor ¶
func NewInterceptor(cfg Config, claimsFromContext ClaimsLookup) connect.UnaryInterceptorFunc
NewInterceptor returns a Connect interceptor that extracts the tenant ID from authenticated claims and injects it into the request context.
claimsFromContext is the project's claims-from-context helper (typically middleware.ClaimsFromContext). When it returns ok=false the request passes through unchanged (matching the legacy "no claims = no tenant" semantics).
Types ¶
type ClaimsLookup ¶
ClaimsLookup is the function the project supplies for reading auth.Claims from the request context. Typically middleware.ClaimsFromContext.
type Config ¶
type Config struct {
// ClaimField is the JWT claim from which the tenant ID is read
// (e.g. "org_id", "tenant_id"). Defaults to "org_id".
ClaimField string
// ColumnName is the database column used for tenant scoping. Stored on
// Config so callers can introspect it; the interceptor itself does not
// touch the database. Defaults to "org_id".
ColumnName string
// Optional, when true, lets requests proceed when claims are present but
// the tenant claim is empty. The default (false) matches the legacy
// template behaviour: a present-but-empty tenant claim returns
// PermissionDenied.
Optional bool
// Extract, when non-nil, fully overrides the default tenant-claim
// extraction. Useful for tenant claims that aren't on Claims directly.
Extract func(claims *auth.Claims, field string) string
}
Config configures the tenant interceptor.
func (Config) EffectiveClaimField ¶
EffectiveClaimField returns ClaimField or the "org_id" default.
func (Config) EffectiveColumnName ¶
EffectiveColumnName returns ColumnName or the "org_id" default.