Skip to content

feat: Google OAuth login via ZeroID human IdP federation #42

Description

@saucam

Summary

Add Google OAuth as a login method for the Codeoid web UI. The daemon-side infrastructure is almost entirely implemented — the main remaining work is the web UI login button and confirming ZeroID's support for the auth-code exchange.

Current state (what's already built)

Component Status
`GoogleOAuthProvider` in `identity-provider.ts` ✅ Complete — exchanges Google code for verified user
`OAuthHandler` in `oauth.ts` ✅ Complete — full OAuth 2.0 + PKCE flow
Server routing in `server.ts` ✅ Complete — `/auth/authorize`, `/auth/idp-callback`, `/auth/callback`, `/auth/token` all wired
`GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` env vars ✅ Read in `server.ts`, switches from `LocalProvider` → `GoogleOAuthProvider`
Web UI "Sign in with Google" button ❌ Missing
ZeroID auth-code grant confirmation ❓ Needs verification with AuthN team

Auth flow (already implemented daemon-side)

1. User clicks "Sign in with Google" in web UI
2. Browser → GET /auth/authorize?client_id=codeoid&code_challenge=<PKCE>
3. Daemon → 302 to https://accounts.google.com/o/oauth2/v2/auth
4. Google verifies user → 302 to /auth/idp-callback?code=<google-code>
5. Daemon exchanges with Google, gets verified user (sub, email, name)
6. Daemon mints HS256 auth code JWT signed with shared hmac_secret
7. 302 → /auth/callback?code=<auth-code>
8. Browser POSTs code + PKCE verifier to /auth/token
9. Daemon proxies to ZeroID /oauth2/token (authorization_code grant)
10. ZeroID validates HS256 auth code → returns RS256 access token
11. Web UI stores token, connects to daemon WebSocket ✅

What needs to be done

1. Web UI — "Sign in with Google" button (web/src/components/SignIn.tsx)

Add a button that generates a PKCE pair, stores the verifier in sessionStorage, then redirects to /auth/authorize. The existing /auth/callback page already handles the browser-side token exchange.

2. Config — move Google credentials through config schema

GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET are currently read directly from process.env in server.ts. They should be part of the config schema in config.ts like the other OAuth fields.

3. ZeroID — confirm auth-code grant support

The flow relies on ZeroID accepting grant_type=authorization_code with HS256 auth codes minted by codeoid (validated via the shared hmac_secret). Confirm with the AuthN team that highflame-authn supports this and document the required ZeroID-side config.

4. CLI — codeoid login --google (nice-to-have)

Opens the system browser to /auth/authorize, listens on a local redirect URI, persists the token.

Why this matters

This is a prerequisite for the planned mobile app — the mobile UX is designed around OAuth rather than manual API-key entry.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions