feat: dual auth middleware — accept Keycloak JWT alongside API key #267
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-api#267
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Standalone — discovered during pal-e-app "app definition" compliance audit (2026-04-12). Blocks all downstream identity features.
Repo
forgejo_admin/pal-e-apiUser Story
As a pal-e-app user, I want the API to validate my Keycloak JWT token so that the backend knows WHO I am, not just WHETHER I'm authenticated.
As an MCP agent, I want the existing API key auth to keep working unchanged.
Context
pal-e-app has Keycloak OIDC (realm
pal-e, clientpal-e-docs-app, PKCE). The frontend passesAuthorization: Bearer {jwt}but the backend (auth.py, 24 lines) only checks a static API key viaX-PALEDocs-Tokenheader. The backend has no concept of WHO is making a request. This ticket adds JWT validation alongside the existing API key, enabling all downstream identity-aware features.File Targets
Files the agent should modify or create:
src/pal_e_docs/auth.py(24 lines) — add JWT validation,get_current_user()dependency,UserContextdataclasssrc/pal_e_docs/config.py— addkeycloak_url,keycloak_realmsettingssrc/pal_e_docs/routes/users.py(new) —GET /meendpoint returning user claims from JWTpyproject.toml— addPyJWT[crypto]orpython-jose[cryptography]dependencyFiles the agent should NOT touch:
src/pal_e_docs/routes/notes.py— wiring UserContext into endpoints is the next ticketsrc/pal_e_docs/models.py— adding columns is the next ticketAcceptance Criteria
curl -H "Authorization: Bearer {valid_jwt}" /mereturns{ sub, email, name, roles }curl -H "X-PALEDocs-Token: {api_key}" /notesstill works (no regression)curl -H "Authorization: Bearer {valid_jwt}" /notesreturns authenticated dataGET /mewithout JWT returns 401Test Expectations
GET /mewith mocked JWT returns claimsGET /mewithout auth returns 401pytest tests/ -vConstraints
get_is_authenticated()must stay exactly as-is — 20 endpoints depend on itget_current_user()that returnsUserContext | Nonehttps://keycloak.tail5b443a.ts.net/realms/pal-e/protocol/openid-connect/certsChecklist
Related
pal-e-docs— project this affectsdefinition-app— the app definition driving this work