The GitHub Actions job "Required Checks" on texera.git/main has failed.
Run started by GitHub user github-merge-queue[bot] (triggered by 
github-merge-queue[bot]).

Head commit for run:
5c2eaa2ce612b2d31df2d751614d17a8a8b1a2cc / Yicong Huang 
<[email protected]>
fix(auth): make JwtAuthFilter eager-401 with @PermitAll opt-out (#5404)

### What changes were proposed in this PR?

Replaces the lazy pass-through behavior in `common/auth/JwtAuthFilter`
with an RFC 6750 eager 401 + `WWW-Authenticate` challenge. Missing
`Authorization` throws the bare `Bearer` challenge; an invalid token
throws `error="invalid_token"` so a well-behaved client can distinguish
"please log in" from "your stored token is invalid, discard it". Valid
tokens populate a `SecurityContext` exactly as before.

Endpoints that need to serve anonymous traffic opt out with `@PermitAll`
(JSR-250). This PR audits every resource method in the 5 microservices
and applies `@PermitAll` where the lazy filter previously made it
implicit:

- 5x `HealthCheckResource` (liveness probes)
- `AccessControlResource` `/auth/*` (routing proxy that authenticates
itself via `parseToken` in the resource body)
- `LiteLLMProxyResource` `/chat/*`, `LiteLLMModelsResource` `/models`
(preserve current "gated only by `guiWorkflowWorkspaceCopilotEnabled`"
behavior; whether these should require an authenticated user is a
separate hardening decision)
- `DatasetResource`: 5 endpoints with `/public-*` or `/publicVersion`
paths, plus `/{did}/cover` and `/{did}/cover-url` which already take
`@Auth Optional[SessionUser]` for opt-in user context

`UnauthorizedException` + `UnauthorizedExceptionMapper` carry the
`WWW-Authenticate` challenge to the JAX-RS edge. The exception extends
`RuntimeException` (not `WebApplicationException`) so unit tests can run
without a Jersey `RuntimeDelegate` on the classpath, and is constructed
with `writableStackTrace=false` to avoid `fillInStackTrace` cost on the
auth hot path.

### Any related issues, documentation, discussions?

Closes #4901. The earlier attempt at this fix, #4903, was reverted in
#5025 because expired tokens from `localStorage` were piggy-backed onto
`/api/config/gui` and broke the login page (#5026). PR #5392 has since
fixed the frontend to drop expired tokens client-side (`skipWhenExpired:
true`) and clear the session reactively on 401, so this PR can now ship
safely.

### How was this PR tested?

Added `JwtAuthFilterSpec` (header-missing / non-Bearer / invalid-token /
valid-token; method- and class-level `@PermitAll`; resource-info-absent
fallback) and `UnauthorizedExceptionMapperSpec`. Updated existing
service specs to expect 401 (from the filter) instead of 403 (from the
role filter) for missing-Authorization scenarios, and `*ServiceRunSpec`
mocks verify the new `UnauthorizedExceptionMapper` registration. `sbt
Auth/test` + 4 service specs all green; `sbt scalafmtCheckAll` clean.
Manually tested end-to-end against a running `config-service` build with
`curl` (missing / bad / valid tokens, `@PermitAll` healthcheck and
pre-login) and in the browser with a forged JWT in localStorage to
confirm the eager 401 path interoperates cleanly with PR #5392's 401
interceptor.

### Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Opus 4.7)

Report URL: https://github.com/apache/texera/actions/runs/27077427387

With regards,
GitHub Actions via GitBox

Reply via email to