docs(tasks): groom backlog and move completed extraction task to complete/

This commit is contained in:
Tyler Gillispie 2026-08-23 10:31:11 -07:00
parent 6d0b811637
commit 8a6cd6f72e
2 changed files with 119 additions and 34 deletions

View File

@ -1,46 +1,131 @@
# TASK METADATA
- **Target Files:** `auth-yes/server/db.ts`, `auth-yes/server/oidc.ts`,
`auth-yes/server/main.ts`, `auth-yes/ui/admin/integrations.tsx` (and related
UI files)
- **Core Objective:** Implement seamless 3rd-party SSO via a Zero-Click OIDC
Provider and Traefik ForwardAuth Header injection.
- **Dependencies:** Core Auth-Yes session mechanisms, Valkey cache, Hono
routing, React/JSX for UI.
- **Additional Important Notes:** Ensure OIDC logic is decoupled from `main.ts`
to prevent a monolith. Database migrations are required for OIDC
clients/authorization codes.
- **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`.
---
### Phase 2: The Bonus Stage — Seamless 3rd-Party SSO (Gitea, Portainer, etc.)
## Architectural Considerations & Risks
Your vision for frictionless 3rd-party access without double-logins is
achievable through two native patterns we can bring directly into auth-yes:
### Risks
#### 1. The "Zero-Click" OIDC Provider in auth-yes
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.
• Most self-hosted power tools (Gitea, Nextcloud, Grafana, Portainer, Proxmox,
Vaultwarden) support standard OpenID Connect (OIDC). • When auth-yes exposes
standard OIDC endpoints (/oauth/authorize, /oauth/token, /oauth/userinfo): • You
click "Login with Auth-Yes" on Gitea (or configure Gitea for auto-login). •
Gitea redirects to auth.atyg.org. • Because you already have your .atyg.org
passkey cookie active, auth-yes instantly authorizes and redirects back in ~10
milliseconds without presenting any login dialogs. • Gitea automatically creates
and syncs your account on the fly.
### Alternatives Considered
#### 2. Reverse-Proxy Header Authentication (Traefik ForwardAuth)
- **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.
• Apps like Gitea have native Reverse Proxy Auth
(ENABLE_REVERSE_PROXY_AUTHENTICATION = true). • When Traefik calls
/api/forward-auth, auth-yes injects X-Forwarded-User: <username>. Gitea
immediately trusts the header and logs you in transparently with zero
interaction.
---
#### 3. 3rd-Party App Integrations Manager in Admin Console
## Proposed Implementation
• We can expand our Application Registry (/admin/apps) with an Integrations
Catalog (Client IDs, OIDC secrets, callback URLs, and role-mapping presets for
Gitea, Grafana, Portainer, etc.). • This gives you a single pane of glass to
manage passkey-secured SSO across your entire self-hosted ecosystem, allowing
you to optionally bypass Cloudflare Zero Trust popups entirely.
### 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`).