# NuQloud Identity Provider ## Purpose Turn a NuQloud instance into a primary authentication and identity server for private self-hosted services. The goal is that a user account on a NuQloud instance can authenticate into other trusted apps through standard OpenID Connect (OIDC), while retaining the Qortal-powered ownership model already used by the current broker login flow. ## Short Version NuQloud should become an OIDC Identity Provider. Recommended direction: 1. Use the existing `qortal-oidc-broker` as the identity provider core. 2. Keep Nextcloud as the user/admin/account-management surface. 3. Register other private services as OIDC clients. 4. Issue scoped identity claims based on NuQloud account state, group policy, and linked Qortal identity proof. This avoids making Nextcloud itself the final identity authority. Nextcloud can still be the visible control surface, but the broker should own token issuance, client policy, redirect validation, identity mapping, and future service-level access rules. ## Product Shape Primary user outcome: - A user logs into a NuQloud instance once. - The same identity can sign into approved private apps. - The user does not need separate passwords for each service. - Admins can decide which users or groups can access which services. Primary admin outcome: - Admin can add a private app as an OIDC client. - Admin can configure redirect URIs, scopes, group access, and display label. - Admin can disable a service without deleting user identities. - Admin can audit which users authenticated to which services. ## Architecture ### NuQloud Broker The broker becomes the identity provider. Responsibilities: - OIDC discovery: - `/.well-known/openid-configuration` - Authorization: - `/authorize` - Token exchange: - `/token` - User info: - `/userinfo` - Signing keys: - `/jwks` - Client registration and policy storage. - Redirect URI validation. - Authorization code issuance. - Access token and ID token issuance. - Scope and claim filtering. - Login/session handoff to Qortal-powered identity proof. - Audit events for authentication and token activity. ### Nextcloud App Nextcloud remains the primary UI surface. Responsibilities: - Admin UI for identity provider settings. - OIDC client registration UI. - Service access policy UI. - User/group mapping UI. - Audit log viewing. - User self-service identity linking. - Product language mode display. Non-responsibilities: - Signing OIDC tokens. - Storing client secrets in browser-visible state. - Trusting client-side access decisions. ### Qortal External Auth External Auth remains the proof and signing layer. Responsibilities: - Prove identity ownership. - Support login challenge flows. - Support future signed approval flows. - Avoid exposing sensitive secrets to Nextcloud UI or client apps. ### Private Apps Private apps are OIDC relying parties. Examples: - Gitea - GitLab - OpenProject - Grafana - Wiki.js - Outline - Custom internal apps Integration paths: 1. Native OIDC support in the app. 2. OIDC-aware reverse proxy for apps without native OIDC. 3. Future NuQloud app launcher with preconfigured client templates. ## Identity Model NuQloud should expose stable identities that do not break when a user changes display name, email, or linked service labels. Recommended subject model: - Internal subject: - stable broker identity ID - Public OIDC `sub`: - stable per issuer - never derived directly from mutable display values - Optional claims: - `preferred_username` - `name` - `email` - `email_verified` - `groups` - `nuqloud_account_id` - `qortal_address` when policy allows Powered Mode default: - Hide protocol-native wording from normal users. - Present this as NuQloud identity. - Only expose Qortal-specific claims to clients explicitly allowed by policy. Full Qortal Mode: - Allow Qortal-native claims and UI labels where appropriate. - Keep claim release controlled per client. ## Client Registry Add a broker-side OIDC client registry. Minimum fields: - `client_id` - `client_secret_hash` - `display_name` - `redirect_uris` - `post_logout_redirect_uris` - `allowed_scopes` - `allowed_groups` - `enabled` - `require_pkce` - `created_by` - `created_at` - `updated_at` Security rules: - Redirect URIs must be exact-match allowlisted. - Client secrets must be hashed at rest. - Public clients must require PKCE. - Confidential clients should support secret rotation. - Disabled clients must fail authorization and token exchange. ## Sessions And Tokens Initial MVP can use short-lived authorization codes and short-lived tokens. Recommended defaults: - Authorization code TTL: 2 minutes. - ID token TTL: 10 minutes. - Access token TTL: 10 minutes. - Refresh tokens: disabled for MVP. - PKCE: required for public clients, optional but recommended for confidential clients. Later phases can add: - Refresh tokens. - Token revocation. - Back-channel logout. - Front-channel logout. - Device/session management. - Per-client session duration. ## Access Policy Policy must be enforced server-side by the broker. Policy inputs: - NuQloud account status. - Linked identity status. - Nextcloud user ID. - Nextcloud groups. - Client allowlist. - Requested scopes. - Admin-defined service access rules. Policy outputs: - Allow authorization. - Deny authorization. - Require re-authentication. - Require identity proof refresh. - Require admin approval or invite. ## Data Model Suggested broker tables: - `identity_subject` - `id` - `nextcloud_user_id` - `primary_qortal_address` - `status` - `created_at` - `updated_at` - `oidc_client` - `id` - `client_id` - `client_secret_hash` - `display_name` - `enabled` - `require_pkce` - `created_by` - `created_at` - `updated_at` - `oidc_client_redirect_uri` - `client_id` - `redirect_uri` - `oidc_client_scope` - `client_id` - `scope` - `oidc_client_group_policy` - `client_id` - `group_id` - `policy` - `oidc_auth_code` - `code_hash` - `client_id` - `subject_id` - `redirect_uri` - `scope` - `pkce_challenge` - `expires_at` - `consumed_at` - `oidc_audit_event` - `event_type` - `client_id` - `subject_id` - `ip_hash` - `user_agent_hash` - `metadata_json` - `created_at` ## Delivery Plan ### Phase 0: Branch Start Status: - Branch: `feature/nuqloud-identity-provider` - First implementation slice: broker-side client registry with hashed secrets, exact redirect URI matching, per-client scopes, enable/disable, and secret rotation. ### Phase 1: Provider Hardening Outcome: - Existing broker OIDC flow becomes suitable for multiple clients. Work: - Keep current durable auth request/code storage. - Add client registry. Started. - Enforce exact redirect URI validation. Started. - Add hashed client secrets. Started. - Add client update and disable controls. Started. - Add PKCE enforcement per client. Started. - Add per-client scopes. Started. - Add group policy checks. Started. - Add scoped claim release. Started. - Add audit events. Started. Exit criteria: - Nextcloud still logs in through the broker. - A second test OIDC client can log in through the same NuQloud issuer. - Invalid redirect URIs and disabled clients are rejected. ### Phase 2: Admin UI Outcome: - Admin can manage private app clients from NuQloud. Work: - Add Identity Provider admin page. - Add Nextcloud admin API bridge for clients and audit events. Started. - Add create/edit/disable OIDC client actions. Started. - Add redirect URI management. - Add client secret generation and rotation. - Add group access rules. - Add setup snippets for common self-hosted apps. - Add built-in setup guides for client templates. Completed. - Ensure setup, start, recreate, and host-hybrid flows sync the identity provider as a built-in feature. Completed. Exit criteria: - Admin can register a private app without editing env files. - Admin can disable access to a private app immediately. ### Phase 3: Service Access And Claims Outcome: - Different apps can receive different identity data. Work: - Add claim release policy per client. - Add group claims. - Add Powered Mode vs Full Qortal Mode claim behavior. - Add optional consent screen for sensitive claims. - Add service-level audit view. Exit criteria: - One app can receive only basic profile claims. - Another approved app can receive Qortal-specific claims. - Admin can inspect recent auth events. ### Phase 4: Logout, Revocation, And Session Management Outcome: - NuQloud can act as a stronger central identity layer. Work: - Add token revocation endpoint. - Add refresh token support if needed. - Add app session list. - Add revoke all sessions for a user. - Add logout redirect support. - Investigate back-channel logout support for compatible clients. Exit criteria: - Admin or user can revoke app access. - Tokens issued before revocation no longer work after their allowed window. ### Phase 5: App Templates And Reverse Proxy Auth Outcome: - NuQloud becomes easy to use as identity for a full private stack. Work: - Add templates for common apps. - Add generated OIDC configuration instructions. - Add optional reverse-proxy auth pattern for apps without OIDC. - Add service catalog and app launcher hooks. Exit criteria: - Admin can add a common app from a template. - Non-OIDC apps have a documented protected-proxy option. ## Security Requirements - All public OIDC endpoints must validate inputs strictly. - All internal admin APIs must require server-side auth. - All state-changing Nextcloud controller routes must preserve CSRF protection unless explicitly designed as token-authenticated API routes. - No raw user input should be rendered into admin or user pages. - Client secrets must never be logged or exposed after creation. - Token signing keys must be rotatable. - Redirect URIs must be exact-match allowlisted. - Authorization codes must be single-use. - Token claims must be scoped per client. - Group and service access must be checked at authorization time. - Audit logs must avoid storing sensitive token or secret material. ## Compatibility Risks - Some self-hosted apps implement OIDC incompletely. - Some apps require email to be present and verified. - Some apps do not support group claims consistently. - Logout behavior varies widely by client. - Mobile apps may require app passwords or separate flows. - Nextcloud version changes can affect the admin UI and `user_oidc` integration. - Reverse proxy auth for non-OIDC apps has a larger blast radius and should be treated as a separate hardening track. ## Open Questions 1. Should NuQloud support dynamic client registration, or only admin-created clients? 2. Should refresh tokens be part of v1, or deferred until session management is mature? 3. Should Qortal-specific claims be disabled by default in Powered Mode? 4. Should each client receive a pairwise `sub`, or should all clients receive the same stable subject? 5. Should service access be based on Nextcloud groups, NuQloud-specific groups, or both? 6. Should app templates live in the broker, the Nextcloud app, or static docs? 7. Should NuQloud provide an OIDC-aware reverse proxy profile, or only document third-party proxy patterns? ## First MVP Target The smallest useful MVP: 1. Keep Nextcloud login working through the broker. 2. Add one additional OIDC client manually in broker config or database. 3. Validate redirect URI and client secret. 4. Issue ID token and userinfo for that second client. 5. Gate access by an existing Nextcloud group. 6. Log successful and failed auth attempts. Recommended first integration target: - Gitea or OpenProject. Both are realistic private-service examples and make the value of NuQloud as a primary identity provider obvious.