Skip to content

Commit 06cab0d

Browse files
PythonFZclaudepre-commit-ci[bot]
authored
fix: replace worker password with per-task JWT tokens (#904)
* docs: add design spec for worker auth JWT redesign Replace the shared-password model for the internal worker user with per-task JWT tokens minted at dispatch time, eliminating the well-known default credential that grants superuser access on unpatched deployments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: drop unnecessary register guard from worker auth spec Rely on fastapi-users' built-in "user already exists" rejection for registration — a custom guard is YAGNI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs: add implementation plan for worker auth JWT redesign 8-task plan covering config changes, executor simplification, JWT minting via WorkerTokenDep, login guard, broker cleanup, Docker/docs sweep, and integration tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: replace worker_password with internal_worker_email in Settings * refactor: auto-gen worker password, add lookup_worker_user helper Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor: executor accepts per-task JWT token instead of static credentials Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: mint per-task JWT for internal worker via WorkerTokenDep Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: simplify broker — executor only needs base_url * feat: block internal worker email from public login endpoint Add a custom /jwt/login route that shadows the fastapi-users login to reject login attempts with the internal worker email (403), while preserving normal login behavior for all other users. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore: remove all worker_password references from Docker and docs Removes ZNDRAW_SERVER_WORKER_PASSWORD from docker/templates/.env and the corresponding migration reference from the pydantic-settings plan. Worker authentication now uses JWT tokens, not passwords. Verification: grep -r 'worker_password', 'WORKER_PASSWORD', 'WORKER_EMAIL' all return zero hits (excluding worker-auth-jwt docs). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * test: add integration test for WorkerTokenDep JWT minting Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix: resolve SQLite deadlock in WorkerTokenDep and harden test wiring _mint_worker_token now accepts SessionDep so FastAPI reuses the request-scoped session instead of opening a second one (which re-entered the non-reentrant SQLite asyncio.Lock and deadlocked every @internal task submission). JWTStrategy moved to closure scope. Test conftest now wires get_worker_token override (mirrors lifespan), and the test verifies the conftest-wired override — not a hand-rolled one. Also fixes FAST002 lint (Annotated), removes dead TYPE_CHECKING block, corrects stale error message, and updates spec wording. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: wire WorkerTokenDep stub in joblib test conftest submit_task always resolves WorkerTokenDep, even for @global jobs. The joblib test conftest was missing the override, causing 18 test failures with NotImplementedError. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: simplify WorkerTokenDep — real dependency, drop login guard Make get_worker_token a proper FastAPI dependency that reads from request.app.state instead of a stub requiring override in lifespan and test conftest. Remove the YAGNI custom /jwt/login route — the random UUID password is sufficient protection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: remove unused lookup_worker_user helper Query logic now lives solely in get_worker_token (zndraw_joblib). Calling back into zndraw from zndraw_joblib would create a circular import, so the helper had no callers. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: ensure_internal_worker update path mirrors create flags Set is_active and is_verified in the update branch so a previously disabled or unverified worker user is repaired on startup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 42b7c36 commit 06cab0d

15 files changed

Lines changed: 1064 additions & 44 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ RUN WHEEL=$(ls /tmp/*.whl) && uv pip install --system --no-cache-dir --prereleas
6161
# Set environment
6262
ENV PYTHONUNBUFFERED=1 \
6363
PYTHONDONTWRITEBYTECODE=1 \
64-
ZNDRAW_HOST=0.0.0.0
64+
ZNDRAW_SERVER_HOST=0.0.0.0
6565

6666
USER appuser
6767

docker/templates/.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ ZNDRAW_SERVER_WORKER_ENABLED=false
77

88
# --- Secrets (MUST change in production) ---
99
ZNDRAW_SERVER_GUEST_PASSWORD=zndraw
10-
ZNDRAW_SERVER_WORKER_PASSWORD=zndraw-worker
1110
ZNDRAW_AUTH_SECRET_KEY=CHANGE-ME-IN-PRODUCTION-SECRET!
1211
ZNDRAW_AUTH_RESET_PASSWORD_TOKEN_SECRET=CHANGE-ME-RESET
1312
ZNDRAW_AUTH_VERIFICATION_TOKEN_SECRET=CHANGE-ME-VERIFY

docs/superpowers/plans/2026-03-25-pydantic-settings-phase1.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@ Apply renames across all five files:
329329
- `ZNDRAW_REDIS_URL``ZNDRAW_SERVER_REDIS_URL`
330330
- `ZNDRAW_WORKER_ENABLED``ZNDRAW_SERVER_WORKER_ENABLED`
331331
- `ZNDRAW_GUEST_PASSWORD``ZNDRAW_SERVER_GUEST_PASSWORD`
332-
- `ZNDRAW_WORKER_PASSWORD``ZNDRAW_SERVER_WORKER_PASSWORD`
333332

334333
Leave unchanged: `ZNDRAW_AUTH_*`, `ZNDRAW_URL`, `ZNDRAW_USER`, `ZNDRAW_PASSWORD` (client/auth env vars).
335334

0 commit comments

Comments
 (0)