You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make Watchtower the central management platform and identity provider for a family of per-customer application deployments (single-tenant Elarion apps, one deployment + database + subdomain per customer), so those applications can deliver the auth features that were deliberately deferred out of the instances: device/session management (list signed-in devices + revoke), MFA, and SSO-backed switching between instances.
The downstream product's architecture decisions (private repo) concluded that these features must not be built per-instance: its cookie auth has no server-side session to list or revoke, and in-app TOTP would be discarded once authentication moves to a central IdP. Watchtower's central-authorization work (Phase 1: local users, revocable DB sessions, forward-auth with ES256 JWT/JWKS, per-route policy, audit rows; Phase 2 planned in #18) is the natural home. This issue collects everything Watchtower must provide for that plan to proceed. It complements #18 — overlaps are called out per requirement.
Note the directional difference from #18 §1: there, Watchtower is an OIDC relying party toward an upstream IdP. Here, Watchtower must additionally act as an OIDC provider for downstream tenant applications. The two roles compose (Watchtower may broker an upstream IdP while remaining the issuer for its tenants), but they are distinct pieces of work.
Requirements
R1 — OIDC authorization server (provider role)
Standard OpenID Connect authorization-code flow (+ PKCE) with Watchtower as the issuer; one confidential client registration per tenant instance (each instance runs on its own subdomain with its own backend).
Build on OpenIddict on top of ASP.NET Core Identity rather than hand-rolling the protocol. Watchtower already runs ASP.NET Core Identity core (security stamps etc., per Phase 1), so this is an extension, not a rebuild.
Discovery document, JWKS, token endpoint, end-session/logout endpoint per issuer (see R2 for multi-issuer).
Refresh tokens with sliding expiration are required — they are what makes persistent login ("stay signed in") work and what gives sessions a server-side identity to list and revoke (R6).
R2 — Realms by population, never by tenant
Three realms: central management (operator staff — effectively Watchtower's existing local users), tenant-app staff (professional users across all tenant instances — one identity, many tenants), and end customers (self-service, high volume).
A realm per tenant is explicitly rejected: one person must be able to reach several tenants with one identity and hold a different role in each.
Non-negotiable: a separate user store per realm — the end-customer/staff boundary must be real, not a flag on a shared table. Separate issuer paths and per-realm signing keys; whether that is one deployment or several is a deployment detail (start with one).
Self-registration, if ever enabled, exists only in the end-customer realm and must be unable to touch the staff stores.
Tokens/userinfo carry the stable subject, e-mail, and e-mail-verified state. Nothing else.
No names, no profile data, no roles, no permissions: authorization vocabulary is generated per application/version and stays entirely in the instance. The instance maps issuer + sub to its local account row (standard user_logins binding) and keeps role assignment local.
Privacy consequence (the reason this matters): the central platform becomes custodian of end-customer credentials, never of end-customer data — keeps each tenant's data isolation intact and narrows the contractual (data-processing agreement) scope.
R4 — Tenant registry and membership
This is the stated justification for building on Watchtower instead of adopting Keycloak: the IdP doubles as the tenant registry.
API for a signed-in user's reachable-instances list: this becomes the data source behind the downstream apps' instance switcher (already built behind a directory-provider seam; only the adapter changes).
Membership is administered by tenant admins through their own instance (see R5), not centrally hand-edited.
R5 — Invitation-first provisioning API (never just-in-time)
JIT provisioning is rejected: access is deny-by-default and the tenant administrator stays in control.
Flow to support: tenant instance invites by e-mail → instance calls Watchtower to register the membership (pending) → on the person's first sign-in, Watchtower asserts the e-mail is verified, the instance matches its pending local row by e-mail once, and thereafter the binding is by subject only (e-mail becomes display data — e-mail matching after binding is an account-takeover path).
Watchtower needs: authenticated server-to-server API for instances (register/revoke membership, query binding state), e-mail verification enforcement, and the failure mode "invitation could not be registered centrally" surfaced to the instance rather than swallowed.
Requires outbound e-mail capability in Watchtower (invites, verification, password reset), configurable like the rest of the platform (SMTP settings as an operator-configured port).
R6 — Device/session management (the headline feature)
Persisted, per-user sessions/authorizations (OpenIddict authorizations + refresh tokens; Phase 1's revocable DB sessions extended to the provider role) with recorded metadata: created/last-used timestamps, IP, user agent / rough device label.
Self-service "signed-in devices" page per user (all realms): list active sessions/devices, revoke one, revoke all others.
Admin-side: view/revoke sessions per user; central deactivation of an identity ends access to all tenants at once (the second off-boarding lever; local deactivation in one instance remains the first).
Revocation must actually bite within a bounded time on instances: short access-token lifetimes plus refresh-token revocation as the baseline; back-channel logout or introspection optional hardening.
Persistent-login policy per realm (e.g. staff 30 days sliding, configurable).
Per-realm enforcement: required (or at least enforceable) for the two staff realms, optional for end customers — the realms differ in assurance, not just purpose.
Passkeys/WebAuthn optional beyond that.
R8 — Account lifecycle, audit, and admin surface
Centralized: password reset, e-mail change with re-verification, deactivation, login history. Per-realm admin UI for the operator.
Login history remains additionally visible inside each instance (it already exists there today; instances keep recording their own logins on token sign-in).
R9 — Availability and break-glass
The IdP becomes a single point of failure across every tenant. Required mitigations, designed up front:
Token lifetimes chosen so a short IdP outage does not sign everyone out mid-work.
A break-glass local administrator login per tenant instance that works with the IdP down (the instances keep ASP.NET Identity; the local-password path is retained for exactly this).
Watchtower's own recovery path (RESETPASSWORD break-glass) extended to cover the provider role; backup/restore story for the identity stores.
R10 — Migration support
Instances will run cookie login and OIDC login in parallel during migration, enabling per-instance, per-realm cutover.
Rollout order that keeps risk low: staff realm on one pilot instance → staff everywhere (unlocks SSO instance switching) → end-customer realm last.
Existing users are migrated invitation-style: pre-registered membership + one-time verified-e-mail match on first central sign-in (same mechanism as R5, so no bulk credential migration).
Out of scope
Anything role/permission-shaped in tokens (stays in the applications).
The instance-side work (external-login binding, directory adapter, parallel login paths, break-glass UX) — tracked in the downstream product's own (private) issues; listed here only where it constrains Watchtower's API surface.
The detailed requirements derive from two architecture decision records in the downstream product's private repo ("instance switching is navigation; identity moves to a central IdP" and "central identity — realms by population, credentials only, authorization stays local"); ask internally for access.
Goal
Make Watchtower the central management platform and identity provider for a family of per-customer application deployments (single-tenant Elarion apps, one deployment + database + subdomain per customer), so those applications can deliver the auth features that were deliberately deferred out of the instances: device/session management (list signed-in devices + revoke), MFA, and SSO-backed switching between instances.
The downstream product's architecture decisions (private repo) concluded that these features must not be built per-instance: its cookie auth has no server-side session to list or revoke, and in-app TOTP would be discarded once authentication moves to a central IdP. Watchtower's central-authorization work (Phase 1: local users, revocable DB sessions, forward-auth with ES256 JWT/JWKS, per-route policy, audit rows; Phase 2 planned in #18) is the natural home. This issue collects everything Watchtower must provide for that plan to proceed. It complements #18 — overlaps are called out per requirement.
Note the directional difference from #18 §1: there, Watchtower is an OIDC relying party toward an upstream IdP. Here, Watchtower must additionally act as an OIDC provider for downstream tenant applications. The two roles compose (Watchtower may broker an upstream IdP while remaining the issuer for its tenants), but they are distinct pieces of work.
Requirements
R1 — OIDC authorization server (provider role)
R2 — Realms by population, never by tenant
R3 — Claims contract: credentials only
issuer + subto its local account row (standarduser_loginsbinding) and keeps role assignment local.R4 — Tenant registry and membership
This is the stated justification for building on Watchtower instead of adopting Keycloak: the IdP doubles as the tenant registry.
StackTemplatetenant instances and the "group-per-tenant" semantics already planned in Central authorization Phase 2: OIDC upstream, groups, template inheritance, TOTP #18 §3.R5 — Invitation-first provisioning API (never just-in-time)
R6 — Device/session management (the headline feature)
R7 — MFA
R8 — Account lifecycle, audit, and admin surface
AuthEventrows but has no viewing surface (Central authorization Phase 2: OIDC upstream, groups, template inheritance, TOTP #18 follow-up) — required here, since off-boarding and session revocation across tenants must be auditable.R9 — Availability and break-glass
The IdP becomes a single point of failure across every tenant. Required mitigations, designed up front:
RESETPASSWORDbreak-glass) extended to cover the provider role; backup/restore story for the identity stores.R10 — Migration support
Out of scope
References
docs/central-auth/design.md.