Commit 06cab0d
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
- docker/templates
- docs/superpowers
- plans
- specs
- src
- zndraw_joblib
- zndraw
- tests
- zndraw_joblib
- zndraw
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
11 | 10 | | |
12 | 11 | | |
13 | 12 | | |
| |||
Lines changed: 0 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
329 | 329 | | |
330 | 330 | | |
331 | 331 | | |
332 | | - | |
333 | 332 | | |
334 | 333 | | |
335 | 334 | | |
| |||
0 commit comments