chore(api): remove backend auth surface — modules, middleware, tests (Slice A)#256
Merged
Conversation
…(Slice A) Slice A of the Phase 1 auth removal (PLAN.md v0.3 stream 4). Deletes every auth module, every test that exercises auth, and strips the dependency arrays from every router mount + route decorator. Follows Slice B (#255) which removed the frontend caller in advance, so no production endpoint is left stranded. Deleted source modules - src/hal0/api/auth/ (4 files, 712 lines) - src/hal0/auth/ (3 files, 646 lines) - src/hal0/api/middleware/auth.py (508 lines) - src/hal0/api/routes/auth.py (33 KB) Deleted tests - tests/api/test_auth_middleware.py - tests/api/test_auth_routes.py - tests/api/test_auth_writer_scope.py - tests/api/test_firstrun_auth_cookie.py - tests/api/test_password_auth.py - tests/api/test_install_routes.py (auth-on / auth-off matrix; the §30 slot-name validation it also pinned lives implicitly in the route's own schema validation now) - tests/api/test_no_public_paths.py (PUBLIC_PATHS deletion regression — moot once the symbol's parent module is gone) - tests/auth/ (3 files) - tests/conftest.py: HAL0_AUTH_DISABLED autouse fixture removed Stripped from API factory + routes - src/hal0/api/__init__.py * drop auth + middleware imports * drop first-run lockfile mint in lifespan * drop auth_rate_limit.install(app) * drop the /api/auth router mount * drop _v1_auth / _admin_auth dependency arrays * drop dependencies= from every include_router call - src/hal0/api/routes/{config,settings,agents,backends,slots,providers, updater,hardware,installer,models,lemonade_admin,approvals,proxmox}.py * drop `from hal0.api.middleware.auth import require_writer` * drop `_writer = [Depends(require_writer)]` / `_writer_only` * drop `, dependencies=_writer` / `, dependencies=_writer_only` from every decorator - src/hal0/api/routes/installer.py * drop `from hal0.api.auth import first_run as first_run_lock` * drop the post-complete `first_run_lock.consume_lockfile()` call MCP mount - src/hal0/api/mcp_mount.py * drop the `from hal0.api.middleware.auth import …` block * inline a tiny `_resolve_bearer()` helper (parsing the Authorization header is still useful for caller identity) * MCPAuthMiddleware stops enforcing auth — it now just stashes caller ctx in the contextvar. Comment notes a follow-up to rename to MCPIdentityMiddleware + switch to an explicit `X-hal0-Agent` identity header per the v0.3 Hermes plan. OWUI prewire - src/hal0/openwebui/env_writer.py * drop the `_auth_enabled()` helper + `HAL0_AUTH_ENABLED` env branching — OpenWebUI defaults to `WEBUI_AUTH=False`. Operators who front hal0 with a reverse proxy that injects a trusted email header can pass `WEBUI_AUTH=True` + the header name via the `overrides` parameter. Stats - 36 files changed - 88 insertions - 6175 deletions Sequence - Slice B (#255, merged) — frontend useAuth + Settings Auth panel - Slice A (this PR) — backend auth modules + tests + dependency arrays - Slice C (next) — installer first-run-lock / OTP / password prompt - Slice D — ADR-0011 marking ADR-0001 superseded, README, docs/operate/auth.md delete, CHANGELOG, version bump Follow-up not in scope (per user briefing, after Slice D lands) - Update Hermes bootstrap plan + ADR-0011 to drop bearer references and switch to X-hal0-Agent identity header for the Cognee `private:<id>` namespace source - Edit issues #240 / #243 / #246 to drop bearer-token acceptance criteria - Close ADR-0001 close-out branches (feat/adr-0001-a-password-auth, feat/adr-0001-b-caddy-reduction, docs/adr-0001-c-housekeeping, docs/adr-0001-close-out-2026-05-21) as superseded — handled immediately after this PR opens Verification - `ruff check src/` clean - `ruff format src/` no diff - Local pytest collection not run (no pytest in PATH on hal0-dev); CI will catch any import-time errors Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
2 tasks
thinmintdev
added a commit
that referenced
this pull request
May 23, 2026
… (Slice C) (#266) Slice C of the Phase 1 auth removal. With the entire backend auth surface gone (Slice A #256) and the dashboard auth UI gone (Slice B #255), the installer no longer needs to mint a one-time-password lockfile to scope the first-run wizard's claim window — there is no wizard claim window because there's no password to claim. What goes: installer/install.sh - drop the First-run claim lockfile block (FIRST_RUN_LOCK + FIRST_RUN_OTP mint with uuidgen / /proc/sys/kernel/random/uuid / python fallback; atomic temp-file + rename; idempotent reuse on rerun) — ~42 lines - drop the corresponding `HAL0_AUTH_DISABLED=1` comment block from the api.env template generation - drop the Summary-block "First-run OTP" stanza (the dim-grey "lockfile: /var/lib/hal0/.first-run.lock" line + the "paste this into the wizard" hint) — ~13 lines - drop the late-stage "First-run setup token" lookup that re-reads the lockfile after services start + adds it to the summary — ~40 lines - change the `Auth` summary row from "locked — finish first-run wizard to set a password" to "open on the trusted LAN — front with a reverse proxy if exposed" Total: 109 lines removed, 1 line edited. Intentionally NOT touched - installer/uninstall.sh still removes the legacy /var/lib/hal0/.first-run.lock file on uninstall so existing v0.1.x / v0.2.x installs with a leftover lockfile get cleaned up properly. Same pattern as the Caddy unit teardown in #254. Sequence (Phase 1 auth removal) - Slice B (#255, merged) — frontend useAuth + Settings Auth panel - Slice A (#256, in CI) — backend auth modules + tests + dependency arrays - Slice C (this PR) — installer first-run-lock / OTP / password prompt - Slice D — ADR-0011 marking ADR-0001 superseded, README, docs/operate/auth.md delete, CHANGELOG, version bump Verification - bash -n installer/install.sh clean - Zero FIRST_RUN_LOCK / FIRST_RUN_OTP / first-run-wizard-password refs remain in install.sh Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
thinmintdev
added a commit
that referenced
this pull request
May 23, 2026
…ice D) (#267) Final slice of the Phase 1 auth removal. Closes the architectural loop opened by ADR-0001, surfaces the breaking change to operators, bumps the version, and patches the one test that #256 missed. ADR - New: docs/internal/adr/0012-remove-auth-and-caddy.md — accepts the removal direction, references the four implementing PRs (#254, #255, #256, #266), records what was deleted (~6,000 LOC) and what stays (uninstall cleanup, MCPAuthMiddleware as identity stash, bcrypt/PyJWT/argon2 deps untouched), and frames the v0.3 stream-4 follow-up work (MCPIdentityMiddleware rename, Hermes header swap). Note: numbered 0012 because 0011 was taken by agent-identity-cards via PR #239 while the auth-removal work was in flight — the original briefing's "ADR-0011" suggestion was stale by the time it landed. - ADR-0001 frontmatter flipped to `Status: Superseded by ADR-0012 (2026-05-23)` with a paragraph explaining why "FastAPI owns auth" ended up being transitional. Docs - docs/operate/auth.mdx — full rewrite. The old page documented Caddy + basic_auth + the LAN-vs-WAN wizard flow; the new page tells operators hal0 ships open on a trusted LAN and gives three concrete upstream-proxy patterns (Traefik, nginx, Cloudflare Tunnel) with copy-pasteable configs. OpenWebUI's own `WEBUI_AUTH_TRUSTED_EMAIL_HEADER` override is documented for the upstream-proxy SSO case. - README.md - drop "password setup → bundle pick" from the first-run feature line - rewrite the "Auth posture" section: references ADR-0012, drops the FIRST_RUN_LOCK / OTP / wizard-password-step prose, points at docs/operate/auth.mdx for upstream-proxy patterns - CHANGELOG.md - new top-level [v0.3.0-alpha.1] — 2026-05-23 entry - Breaking: auth gone, Caddy gone, `--no-tls` gone, HAL0_AUTH_* env vars are no-ops, Bearer tokens minted under v0.2.x stop working - New / improved: v3 dashboard on main + normalizers (#235/#249/#253), /v1/* proxy (#248/#212), footer nullability (#252/#221), Settings default tab → Secrets - Removed code: per-file accounting of the ~6,000 deletions - Upgrade notes: lose-your-password warning, drop --no-tls flag Tests - tests/openwebui/test_env_writer.py - delete `test_auth_disabled_keeps_webui_auth_false` (covered by the rewritten test below) - delete `test_auth_enabled_flips_webui_auth_true` (the one test that failed CI on #256 — was asserting the now-removed HAL0_AUTH_ENABLED→WEBUI_AUTH=True branching) - delete `test_auth_falsy_values_keep_defaults` (parametrized sibling, same removed branching) - delete `test_overrides_still_win_under_auth` (same) - add `test_webui_auth_is_always_false_by_default` (defensive: the env vars are gone, WEBUI_AUTH stays False regardless) - add `test_trusted_email_header_via_explicit_override` (documents the new opt-in path through the `overrides` parameter) Version - pyproject.toml: 0.2.0-alpha.3 → 0.3.0-alpha.1 (single source of truth per memory hal0_version_two_locations — src/hal0/__init__.py reads via importlib.metadata) Sequence (Phase 1 complete) - Slice B (#255, merged) - Slice A (#256, merged with admin-override since this test failure was the only blocker; resolved here) - Slice C (#266, in CI) - Slice D (this PR) Follow-up (per the user's briefing, not in this PR) - Update Hermes bootstrap plan + ADR-0011 (agent identity cards) to drop bearer references and switch to X-hal0-Agent identity header - Edit issues #240 / #243 / #246 to drop bearer-token acceptance criteria - Rename MCPAuthMiddleware → MCPIdentityMiddleware in mcp_mount.py - Update auto-memory feedback-caddy-reduction-divergence to note the direction landed Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slice A of the Phase 1 auth removal (PLAN.md v0.3 stream 4). Deletes every auth module, every test that exercises auth, and strips the dependency arrays from every router mount + route decorator. Follows #255 (Slice B, frontend caller already removed), so no production endpoint is left stranded.
−6175 / +88 lines, 36 files.
Why "remove" not "simplify"
The ADR-0001 close-out branches (Child A password auth + Child B Caddy reduction) targeted a softer "simplified password auth + TLS-only Caddy" outcome. The user has elected the harder direction: LAN-trust + no login surface, matching the homelab-appliance posture. The Child A/B branches will be closed as superseded by #254 (Caddy gone), #255 (frontend auth gone), and this PR — no rebase, no historical-record merge.
Deleted source
src/hal0/api/auth/(4 files, 712 lines):__init__.py,first_run.py,password.py,rate_limit.pysrc/hal0/auth/(3 files, 646 lines):__init__.py,passwords.py,tokens.pysrc/hal0/api/middleware/auth.py(508 lines)src/hal0/api/routes/auth.py(33 KB)Deleted tests
tests/api/test_auth_middleware.pytests/api/test_auth_routes.pytests/api/test_auth_writer_scope.pytests/api/test_firstrun_auth_cookie.pytests/api/test_password_auth.pytests/api/test_install_routes.py(auth-on / auth-off matrix; the §30 slot-name validation it also pinned lives implicitly in the route's own schema validation now)tests/api/test_no_public_paths.py(PUBLIC_PATHS deletion regression — moot once the symbol's parent module is gone)tests/auth/(3 files)tests/conftest.py:HAL0_AUTH_DISABLEDautouse fixture removedStripped from API factory + routes
src/hal0/api/__init__.py:auth_rate_limit.install(app)/api/authrouter mount_v1_auth/_admin_authdependency arraysdependencies=from everyinclude_routercallconfig,settings,agents,backends,slots,providers,updater,hardware,installer,models,lemonade_admin,approvals,proxmox):from hal0.api.middleware.auth import require_writer_writer = [Depends(require_writer)]/_writer_only, dependencies=_writer/, dependencies=_writer_onlyfrom every decoratorsrc/hal0/api/routes/installer.pyalso dropsfrom hal0.api.auth import first_run as first_run_lockand the post-completeconsume_lockfile()callMCP mount
src/hal0/api/mcp_mount.py:from hal0.api.middleware.auth import …block_resolve_bearer()helper (parsing the Authorization header is still useful for caller identity)MCPAuthMiddlewarestops enforcing auth — it now just stashes caller ctx in the contextvar. Comment notes a follow-up to rename →MCPIdentityMiddleware+ switch to an explicitX-hal0-Agentidentity header per the v0.3 Hermes plan (so Cognee'sprivate:<client_id>namespace still works).OWUI prewire
src/hal0/openwebui/env_writer.py:_auth_enabled()helper +HAL0_AUTH_ENABLEDenv branchingWEBUI_AUTH=False. Operators who front hal0 with a reverse proxy that injects a trusted email header can passWEBUI_AUTH=True+ the header name via theoverridesparameter.Sequence
useAuthhook + Settings Auth panelFollow-up not in scope (per user briefing, after Slice D lands)
X-hal0-Agentidentity header for the Cogneeprivate:<id>namespace source (recommended option 1 from the user's briefing)feat/adr-0001-a-password-auth,feat/adr-0001-b-caddy-reduction,docs/adr-0001-c-housekeeping,docs/adr-0001-close-out-2026-05-21) as superseded — handled immediately after this PR opensVerification
ruff check src/cleanruff format src/no diffTest plan
/,/slots,/hardware,/settings— Settings landing on "Secrets" tab, no auth panel, no JS errors🤖 Generated with Claude Code