132 lines
5.1 KiB
Markdown
132 lines
5.1 KiB
Markdown
# 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`).
|