Skip to content

fix(security): require dashboard auth for plugin API routes (salvage #19541) - #23220

Merged
teknium1 merged 2 commits into
mainfrom
salvage/pr-19541-plugin-api-auth
May 10, 2026
Merged

teknium1 merged 2 commits into
mainfrom
salvage/pr-19541-plugin-api-auth

Conversation

@teknium1

Copy link
Copy Markdown
Collaborator

Summary

Plugin HTTP routes (/api/plugins/*) now go through the same session-token auth middleware as core API routes. Previously a one-line whitelist in auth_middleware exempted plugin routes — meaning hermes dashboard --host 0.0.0.0 exposed unauthenticated POST/PATCH/DELETE on the kanban board (and any other plugin's API) to anyone on the LAN.

What changed

  • hermes_cli/web_server.py (line 228): drop the and not path.startswith("/api/plugins/") clause. Plugin routes now flow through the existing _has_valid_session_token(request) check.
  • plugins/kanban/dashboard/plugin_api.py: rewrite the "Security note" docstring (previously said "plugin routes are unauthenticated by design" — actively wrong after this change).
  • tests/hermes_cli/test_web_server.py: extend TestPluginAPIAuth to cover non-GET methods (PATCH/DELETE), a non-kanban plugin path (hermes-achievements), an unknown plugin namespace, and a regression check that the HTTP middleware change didn't accidentally start gating WebSocket upgrades. Replace the previous "200 OR 404 acceptable" assertion with a real-handler check via /api/plugins/example/hello.

What this is not

The dashboard's session-token model isn't multi-user auth — anyone who can read the printed startup URL+token gets full access. This PR doesn't change that. It just removes the plugin-routes-only carve-out so plugins use the same auth as the rest of the dashboard.

Validation

Before After
tests/hermes_cli/test_web_server.py::TestPluginAPIAuth 3/3 (with vacuous 200-or-404 assertion) 7/7 (real auth-success check + PATCH/DELETE/non-kanban/WS coverage)
Wider tests/hermes_cli/test_web_server.py 141 pass / 3 PTY-WS pre-existing fail 141 pass / 3 PTY-WS pre-existing fail (unchanged)

Closes #19533 via salvage. Salvage of #19541; commit 9ab2c3dfc by @liuhao1024 preserved as the committing author. The two unrelated commits in the original PR (fix(gateway): WHATSAPP_NPM_INSTALL_TIMEOUT and fix(tools): mark patch tool conditionally required params) were not carried — the latter would have actively broken mode='patch' callers.

liuhao1024 and others added 2 commits May 10, 2026 07:01
Remove the blanket /api/plugins/* exemption from auth_middleware so
plugin API routes (e.g. Kanban dashboard) require the same session
token as all other /api/ endpoints.

Fixes #19533
…tring

Follow-up to the previous commit's middleware fix.

- plugins/kanban/dashboard/plugin_api.py: rewrite the "Security note"
  docstring. The previous text said "/api/plugins/ is unauthenticated by
  design" — that's now actively wrong and dangerously misleading. New
  text explains that plugin routes flow through the same session-token
  middleware as core API routes and that --host 0.0.0.0 is safe to use
  on a LAN as a result.

- tests/hermes_cli/test_web_server.py: extend TestPluginAPIAuth to cover
  the surfaces the original PR didn't pin:
  * test_plugin_route_allows_auth now exercises a real plugin path
    (/api/plugins/example/hello) instead of accepting 200 OR 404 from
    a maybe-loaded kanban plugin — the assertion was effectively vacuous.
  * test_plugin_patch_requires_auth + test_plugin_delete_requires_auth
    cover non-GET mutation methods in case a future regression
    whitelists them by accident.
  * test_non_kanban_plugin_route_requires_auth proves the fix is
    plugin-agnostic, not kanban-specific (hits hermes-achievements +
    a non-existent plugin namespace; both 401 before route resolution).
  * test_plugin_websocket_unaffected_by_http_middleware locks in that
    the HTTP middleware change didn't accidentally start gating WS
    upgrades — kanban /events still uses its own ?token= check.
  Plus a cosmetic blank-line cleanup.
@teknium1
teknium1 merged commit ae4b09c into main May 10, 2026
12 of 15 checks passed
@teknium1
teknium1 deleted the salvage/pr-19541-plugin-api-auth branch May 10, 2026 14:04
@github-actions

Copy link
Copy Markdown

🔎 Lint report: salvage/pr-19541-plugin-api-auth vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8000 on HEAD, 7998 on base (🆕 +2)

🆕 New issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:13284: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:13287: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown, Unknown] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`

✅ Fixed issues (3):

Rule Count
invalid-argument-type 3
First entries
run_agent.py:13287: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown | str, Unknown | str | dict[str, str]] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
run_agent.py:13284: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:7160: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`

Unchanged: 4218 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(security): require dashboard auth for Kanban plugin API

2 participants