Skip to content

fix(authn): Google sign-in goes direct to Google + repair auth e2e drift from the Security API cutover - #277

Merged
izzywdev merged 4 commits into
masterfrom
claude/authn-google-direct
Jul 16, 2026
Merged

fix(authn): Google sign-in goes direct to Google + repair auth e2e drift from the Security API cutover#277
izzywdev merged 4 commits into
masterfrom
claude/authn-google-direct

Conversation

@izzywdev

@izzywdev izzywdev commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Two AuthN correctness fixes this session owns. Both stem from the Security API cutover.

1. Google sign-in got stuck on Authentik's UI

startSocialLogin 302'd to the generic OIDC authorize endpoint. Authorize requires a session; with none, Authentik falls back to the brand's auth flow and renders its identification page (/if/flow/...) with a "Google" button — the IdP's own UI, leaking across our boundary.

Fix: launch the Google source directly — /source/oauth/login/google/?next=<authorize>. That view 302s straight to accounts.google.com; after the callback the source flow runs (silent enrollment first time, login when returning), then next resumes authorize, which issues the code silently. Same cookie/state/PKCE round-trip — one hop inserted ahead of authorize, so no /if/flow/ ever renders. Adds a regression assertion that the redirect never matches /if/.

This unblocks devops dropping /if from the IdP ingress.

2. The auth e2e suite was testing endpoints we deleted

E2E (sign-in) has been red on master since the cutover — not flake, and not something to wave off as "pre-existing". The SPA moved to /api/v1/security/* (POST /session, GET /methods, /social/google/start, /session/exchange) but the tests still waited on /api/auth/login and mocked /api/auth/method. The frontend never calls those anymore, so waitForResponse hung until timeout.

Repointed: auth-simple, clock-load, mobile-layout, pages/login-page, google-signin, federated-apps-register-activate, and the post-prod live-smoke. Where login is awaited, the HTTP method is matched tooGET /session ("me") shares the URL and would otherwise satisfy the wait before login completed.

Also adds the coverage that was missing: oidc-plumbing only exercised the deprecated /api/auth shim and had zero coverage of the surface the SPA and consumers actually use. It now asserts the capability descriptor, password sign-in, wrong-password 401, and a boundary check that no response leaks authentik/permit. The shim assertions stay — it's still mounted for one release.

Verification

CI is the gate (local install hangs on this Windows box). The proof is E2E (sign-in) going green on this PR having been red on master.

hold + no auto-merge — master is deploy-on-push; merge in a deploy window. Does not touch package-lock.json.

Co-Authored-By: Claude

startSocialLogin sent the browser to the generic OIDC authorize endpoint, which
requires an authenticated session. With none, Authentik fell back to the brand's
authentication flow and rendered its own identification page (/if/flow/...) with
a "Google" button — stranding the user on the IdP's UI instead of Google.

Launch the Google source directly instead: /source/oauth/login/google/?next=<authorize>.
The source-redirect view 302s straight to accounts.google.com; after the callback
the source flow runs (silent enrollment first time, login when returning), then
`next` resumes authorize, which issues the code silently. Same cookie/state/PKCE
round-trip — one hop inserted ahead of authorize, so no /if/flow/ ever renders.
This also lets devops drop /if from the IdP ingress.

Also corrects the stale source-google.yaml comment (the removed auth.fuzefront.com
-> app.fuzefront.com); the callback is host-derived, not a settable field.

Co-Authored-By: Claude <claude-opus-4-8> <noreply@anthropic.com>
Claude-Session-Id: cf830721-b1ef-4fe0-a024-035ad280dcf7
@izzywdev izzywdev added the hold label Jul 16, 2026
@github-actions
github-actions Bot enabled auto-merge (squash) July 16, 2026 09:44
@github-actions

Copy link
Copy Markdown
Contributor

Automated code review (gate-code-review)

  • backend/security/src/providers/authentik/AuthentikIdentityProvider.ts:262 — The source path is hardcoded to /source/oauth/login/google/, ignoring the provider argument to startSocialLogin. Any non-Google social provider will now be silently routed through Google's source login instead of its own, breaking that flow (previously the redirect derived from the provider-specific url).

Report-only — this check never blocks merge.

…ly uses

The security cutover moved the SPA onto /api/v1/security/* (POST /session to
log in, GET /methods for capabilities, /social/google/start, /session/exchange),
but the e2e suite still waited on /api/auth/login and mocked /api/auth/method.
The frontend never calls those anymore, so page.waitForResponse() hung until
timeout — this is why "E2E (sign-in)" has been red on master since the cutover.
The tests were asserting an endpoint we deleted from the client, not a real bug.

- auth-simple / clock-load / mobile-layout / pages/login-page: wait on
  POST /api/v1/security/session. Match the METHOD too — GET /session ("me")
  shares the URL and would otherwise satisfy the wait before login completes.
- google-signin: mock /api/v1/security/methods with the neutral descriptor
  (`social: ['google']` replaces the vendor-flavoured `oidcConfigured`), and
  route the real endpoints — /social/google/start and /session/exchange.
- federated-apps-register-activate: "me" is GET /api/v1/security/session.
- live-smoke (post-prod): smoke /methods and sign in via /session — the same
  surface prod serves browsers, so it fails if real sign-in breaks.

Also ADDS the missing coverage of the new surface to oidc-plumbing (it only
tested the deprecated /api/auth shim): capability descriptor, password sign-in,
wrong-password 401, plus a boundary assertion that no response leaks the vendor.
The /api/auth shim assertions stay — it is still mounted for one release.

Co-Authored-By: Claude <claude-opus-4-8> <noreply@anthropic.com>
Claude-Session-Id: cf830721-b1ef-4fe0-a024-035ad280dcf7
@github-actions

Copy link
Copy Markdown
Contributor

Automated code review (gate-code-review)

Credit balance is too low

Report-only — this check never blocks merge.

@izzywdev izzywdev changed the title fix(security): Google sign-in goes directly to Google (no Authentik UI) fix(authn): Google sign-in goes direct to Google + repair auth e2e drift from the Security API cutover Jul 16, 2026
The source path was hardcoded to google. The `provider !== 'google'` guard above
means nothing else can reach it today, so this is not a live bug — but it is a
trap: widening that guard would silently route every new provider through
Google's source. Track `provider` so the slug cannot drift from the guard.

Co-Authored-By: Claude <claude-opus-4-8> <noreply@anthropic.com>
Claude-Session-Id: cf830721-b1ef-4fe0-a024-035ad280dcf7
@github-actions

Copy link
Copy Markdown
Contributor

Automated code review (gate-code-review)

Credit balance is too low

Report-only — this check never blocks merge.

@izzywdev

Copy link
Copy Markdown
Owner Author

Re: the gate-code-review note on AuthentikIdentityProvider.ts:262 (hardcoded /source/oauth/login/google/) — fixed in 2e2461e: the slug now tracks provider (/source/oauth/login/${provider}/).

One correction for the record: it wasn't a live break. startSocialLogin throws InvalidInputError for any provider !== google before reaching that line, so no other provider could ever be routed through Google's source. But the underlying point stands as a latent trap — widening that guard would have silently sent a new provider to Google. The slug and the guard can no longer drift apart.

(The second review comment reported only "Credit balance is too low" — no finding to address.)

🤖 Addressed by Claude Code

@izzywdev

Copy link
Copy Markdown
Owner Author

gate-code-review reported only "Credit balance is too low" — the reviewer bot failed to run rather than raising a finding, so there is nothing to address from it. (Its earlier substantive note, the hardcoded google source slug, was fixed in 2e2461e.)

The two red checks — Playwright sign-in flow and OIDC plumbing — are known and genuinely red, not flake. Root cause: the SPA now signs in via /api/v1/security/*, which only backend/security serves, and no e2e stack runs that service (docker-compose.e2e.yml builds the monolith backend/Dockerfile; e2e.yml starts the monolith only, with no Authentik). So the login POST 404s and the wait times out. Prod is unaffected — the k8s Ingress routes /api/v1/securityfuzefront-security.

Fix is in flight as separate PRs (add the security service to the compose stack + route it in nginx; then repoint the sign-in workflow). This PR stays red until that lands — deliberately not papering over it.

🤖 Addressed by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant