AUTH4D-8 tenant and application policy
This ticket adds package services and policy helpers; it does not enable management or authentication
routes. Callers resolve a customer tenant by its required tenantId and resolve a client using the
compound (tenantId, clientId) key. The configured auth origin forms the issuer; request host and
forwarded-host headers are never used. Suspended tenants and disabled or confidential tenant clients
fail closed in resolveAuthenticationApplication. Authentication starts and refresh requests use
the same resolver before continuing. Security-sensitive D1 reads use first-primary sessions.
Application policy requires exact registered redirect URI and browser Origin matches. Redirects
must use HTTPS, except explicit loopback HTTP for local development; fragments, credentials, and
wildcards are rejected. Origins must be canonical origins and follow the same HTTPS/loopback rule.
All requested scopes and grant types must be enabled for that application. Signup intent is denied
when the trusted tenant signup setting is false. Provider login is allowed only for enabled providers;
email and Discord read their enablement from tenant-scoped provider configuration, while guest login
is a built-in provider. A trusted provider-policy adapter may disable guest login for a tenant.
The frozen foundation schema does not contain a signup-enabled column. The tenancy repository accepts a trusted signup-setting adapter and defaults to enabled until a later schema-owned ticket adds persistence. No caller-supplied public configuration can set this value. Its public projection only contains tenant/client identifiers, display name, issuer, client type, scopes, signup state, and enabled provider names; it omits client secret hashes, provider client IDs, secret bindings, and all credential material.
Customer application management creates browser or native public clients only. Native clients use device authorization and cannot register browser redirects or origins. Confidential server clients are reserved for the console/control-plane integration and are not created or exposed by ordinary customer tenant operations.
Project membership policy
Membership capability checks are tenant-bound and never grant /management/* control-plane access.
Management routes still require a control-plane actor, the immutable management audience, and the
route’s required management scope.
| Project role | Permissions |
|---|---|
| owner | All tenant, client, user, session, and audit permissions |
| admin | Tenant read; client, user, and session read/write or revoke; audit read |
| viewer | Tenant, client, user, session, and audit read |
Owner transfer is intentionally not part of ordinary role assignment. Owners may grant admin or
viewer; admins may grant viewer; viewers cannot assign roles. The existing shared membership table
stores owner and member; its member rows project to least-privileged viewer. Admin grants are
accepted by the policy helper for later management-membership storage, without changing the frozen
shared schema.
Source: docs/api-spec/auth4d-8.md