auth-yes/tasks/new/2026-0821.01.jul.feat.auth-yes.seamless-3rd-party-sso-1609.md

5.1 KiB

TASK METADATA

  • Target Files:
    • server/oidc.ts
    • server/db.ts
    • server/main.ts
    • ui/admin/integrations.tsx
    • server/oidc.test.ts
    • server/main.test.ts
  • Core Objective: Implement a Zero-Click OpenID Connect (OIDC) Identity Provider in Auth-Yes and enhance Traefik ForwardAuth header injection to enable seamless, passwordless SSO across 3rd-party self-hosted services (e.g., Gitea, Grafana, Portainer).
  • Dependencies:
    • PostgreSQL 18 DDL schema for OIDC client applications and authorization codes
    • Valkey 8 token/code replay protection cache
    • Existing WebAuthn passkey session cookie authority (.atyg.org)
  • Additional Important Notes:
    • Keep server/oidc.ts modular and decoupled from main.ts.
    • Strictly React-free pure Hono SSR JSX for UI components.
    • Implement full PKCE (RFC 7636) support and standard OIDC Discovery metadata at /.well-known/openid-configuration.

Architectural Considerations & Risks

Risks

  1. Open Redirect Vulnerabilities: Malicious actors could craft authorization requests redirecting users to arbitrary domains.
    • Mitigation: Strict exact-match validation against registered redirect_uris in PostgreSQL.
  2. Authorization Code & Token Replay: Stolen or intercepted authorization codes could be exchanged for tokens.
    • Mitigation: Single-use authorization codes with short TTL (e.g. 60s) backed by Valkey atomic deletion on exchange (GETDEL / transaction). Mandatory PKCE (code_challenge / code_verifier).
  3. Cross-Origin & Wildcard Cookie Collisions: Subdomain applications attempting to hijack .atyg.org session cookies.
    • Mitigation: Explicit SameSite=Lax, Secure, and HttpOnly cookie constraints with server-side revocation validation.

Alternatives Considered

  • Heavy OAuth2 Frameworks / Dependencies: Rejected. Incorporating large Node.js OAuth libraries introduces runtime dependencies and bloat. A native, zero-dependency TypeScript implementation utilizing Deno standard Web Crypto API (crypto.subtle) for RS256/EdDSA JWT signing ensures a minimal, ultra-fast footprint.

Proposed Implementation

Phase 1: Database Schema & Client Registry Migration (server/db.ts)

  1. Add oidc_clients table:
    • client_id (VARCHAR PK)
    • client_name (VARCHAR)
    • client_secret_hash (VARCHAR)
    • redirect_uris (TEXT[] array of allowed callback URLs)
    • grant_types (TEXT[] e.g., ["authorization_code", "refresh_token"])
    • scopes (TEXT[] e.g., ["openid", "profile", "email", "roles"])
    • created_at (TIMESTAMP)
  2. Add oidc_authorization_codes table or Valkey ephemeral storage:
    • Ephemeral 60s TTL storage for code, client_id, user_id, code_challenge, and scopes.

Phase 2: OIDC Provider & Endpoints (server/oidc.ts)

  1. OIDC Discovery & JWKS:
    • GET /.well-known/openid-configuration: Returns standard OIDC discovery metadata.
    • GET /oauth/jwks.json: Serves public keys for RS256/Ed25519 token verification.
  2. Zero-Click Authorization Endpoint (GET /oauth/authorize):
    • Validates client_id, redirect_uri, response_type=code, and PKCE challenge.
    • Checks active Auth-Yes session cookie (auth_session).
    • If session is active: instantly issues authorization code and redirects to redirect_uri?code=...&state=... with 0 UI friction.
    • If unauthenticated: redirects to WebAuthn passkey login and resumes flow upon successful authentication.
  3. Token Endpoint (POST /oauth/token):
    • Verifies authorization code, PKCE code_verifier, and client authentication.
    • Issues signed RS256 id_token (JWT) and access_token.
  4. UserInfo Endpoint (GET /oauth/userinfo):
    • Validates Bearer access token and returns user profile, email, and mapped roles.

Phase 3: Traefik ForwardAuth Header Enrichment (server/main.ts)

  1. Expand GET /api/forward-auth to inject standard identity headers for reverse-proxy auth:
    • X-Forwarded-User: <username>
    • X-Forwarded-Email: <email>
    • X-Forwarded-Groups: <roles>
    • X-Forwarded-Preferred-Username: <username>
  2. This allows Gitea, Grafana, and tools with ENABLE_REVERSE_PROXY_AUTHENTICATION = true to log users in transparently upon reverse-proxy routing.

Phase 4: Integrations Catalog Admin UI (ui/admin/integrations.tsx)

  1. Build pure Hono SSR JSX admin view under /admin/integrations:
    • Quick-setup presets for popular self-hosted services (Gitea, Grafana, Portainer, Nextcloud, Vaultwarden).
    • Display Client ID, Secret generation, and copyable config snippets for each application.

Phase 5: Unit & Integration Tests (server/oidc.test.ts)

  1. Test OIDC Discovery metadata and JWKS key export.
  2. Test /oauth/authorize with active passkey session (verifying zero-click instant redirect).
  3. Test /oauth/token exchange with valid PKCE verifier vs invalid verifier (verifying rejection).
  4. Test token replay prevention (verifying code cannot be used twice).
  5. Verify all quality gates pass (deno fmt, deno task lint, deno task check, deno task test).