Accept access tokens on protected routes; persist OIDC state #57

Merged
ryan merged 1 commits from fix/access-token-auth-backend into main 2026-10-12 17:44:56 -04:00
Owner

Release 1 of 2 for the auth fix (phase 0a in docs/desktop-client.md). Backend only; the access-token frontend follows in a separate PR once this is live on both colors.

Changes

  • New transitional @jwt_access_required (blueprints/users/decorators.py): accepts the access token, and for now also the refresh token, so the current frontend (refresh token on every call) keeps working. Used on all protected routes and inside admin_required. /api/user/refresh stays refresh-only.
  • Pending OIDC state/PKCE verifiers move from an in-process dict to an oidc_states table (10 min TTL, single-use), so a login that spans a blue/green flip no longer fails with "Invalid or expired state". The unused redirect_after_login is dropped.
  • Migration 16_..._add_oidc_states (aerich-generated): additive table; also contains aerich's no-op JSONB→JSONB ALTERs on users.ldap_groups and beli_restaurants.cuisine/tags.
  • Unit tests for the decorator and the state store.

Deploy

  • make redeploy; startup runs aerich upgrade (creates oidc_states).
  • Wait for "Deploy complete" (old color stopped) before shipping the frontend PR: the pre-PR backend answers access tokens with 422.
  • Once the frontend PR is live, never roll back past this release.

Test plan

  • pytest tests/ -q: 118 passed
  • State store checked against Postgres 16
  • After deploy: existing tabs still work; fresh Authelia login works

🤖 Generated with Claude Code

Release 1 of 2 for the auth fix (phase 0a in docs/desktop-client.md). Backend only; the access-token frontend follows in a separate PR once this is live on both colors. ## Changes - New transitional `@jwt_access_required` (blueprints/users/decorators.py): accepts the access token, and for now also the refresh token, so the current frontend (refresh token on every call) keeps working. Used on all protected routes and inside `admin_required`. `/api/user/refresh` stays refresh-only. - Pending OIDC state/PKCE verifiers move from an in-process dict to an `oidc_states` table (10 min TTL, single-use), so a login that spans a blue/green flip no longer fails with "Invalid or expired state". The unused `redirect_after_login` is dropped. - Migration `16_..._add_oidc_states` (aerich-generated): additive table; also contains aerich's no-op JSONB→JSONB ALTERs on `users.ldap_groups` and `beli_restaurants.cuisine/tags`. - Unit tests for the decorator and the state store. ## Deploy - `make redeploy`; startup runs `aerich upgrade` (creates `oidc_states`). - Wait for "Deploy complete" (old color stopped) before shipping the frontend PR: the pre-PR backend answers access tokens with 422. - Once the frontend PR is live, never roll back past this release. ## Test plan - [x] `pytest tests/ -q`: 118 passed - [x] State store checked against Postgres 16 - [ ] After deploy: existing tabs still work; fresh Authelia login works 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ryan added 1 commit 2026-10-12 17:44:48 -04:00
- Add transitional @jwt_access_required (accepts access tokens, and for now
  also refresh tokens) and use it on every protected route and inside
  admin_required. /api/user/refresh stays refresh-only.
- Move pending OIDC state/PKCE verifiers from an in-process dict to an
  oidc_states table (10 min TTL, single-use) so logins survive a blue/green
  flip. Drop the unused redirect_after_login.
- Unit tests for the decorator and the state store.

Deploy this commit on its own, before the access-token frontend: the old
backend answers access tokens with 422, so the new frontend only works once
this backend is live on both colors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ryan merged commit b77e21474a into main 2026-10-12 17:44:56 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ryan/simbarag#57