fix(dashboard): isolate internal websocket capabilities - #67305
Open
StellarisW wants to merge 1 commit into
Open
fix(dashboard): isolate internal websocket capabilities#67305StellarisW wants to merge 1 commit into
StellarisW wants to merge 1 commit into
Conversation
Collaborator
Related to merged #37972: this follows up by scoping server-internal WebSocket capabilities to their route/profile/channel and stripping them before child processes. The dashboard remains loopback by default; no unauthorized external-attacker PoC was supplied. |
Contributor
|
Thanks for the focused security fix. I found no blocking defect in the implementation.
Automated hermes-sweeper review. |
StellarisW
marked this pull request as ready for review
July 19, 2026 04:45
(cherry picked from commit 41c0fccd462ad07fc77a32ef6b83494d20038333)
StellarisW
force-pushed
the
fix/dashboard-internal-capability-isolation
branch
from
July 22, 2026 16:53
7afb8ba to
f86a13b
Compare
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.
What does this PR do?
Fixes a Dashboard internal WebSocket capability-confusion issue found during a security audit.
Previously, server-spawned TUI processes received one reusable internal bearer that could authenticate multiple Dashboard WebSocket endpoints. A profile-scoped sidecar publisher could therefore reuse its
/api/pubcredential against the broader/api/wsgateway.This PR replaces that shared bearer with audience-bound capabilities and limits their propagation:
gatewaycapability accepted only by/api/ws;sidecarcapability bound to the exact profile and channel and accepted only by/api/pub;/api/pty,/api/events, and/api/consolecontinue to reject internal capabilities;The capabilities remain multi-use within their exact scope so existing reconnect behavior is preserved.
Related Issue
N/A — security audit finding.
Type of Change
Changes Made
hermes_cli/dashboard_auth/ws_tickets.pyhermes_cli/web_server.py/api/wsand/api/pubinto their respective internal audiences;ui-tui/src/gatewayClient.ts,tui_gateway/entry.py,tui_gateway/server.py,tools/environments/local.pyshell.exec.Infographic
Capability audience and profile/channel scope are validated at the accepting route, while lower-trust subprocesses no longer inherit the capability URL.
How to Test
cd ui-tui npm run check npm run lintChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass (targeted canonical-wrapper suites above: 1011 Python tests passed)Documentation & Housekeeping
docs/, docstrings) — N/A; behavior is covered by code docstrings and regression testscli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
No UI change. Verification summaries:
Main branch refresh (2026-07-21)
Merged upstream
mainatf4df260f26c93f15694698869f3ea8e965eea301and resolved the conflict intui_gateway/entry.py. The resolution keeps dashboard capability variables consumed before gateway imports while also retaining the current main-branch stdin EOF recovery hook.Merge commit:
7afb8ba5ec2d116f4850c22ed647d6cb991c749aValidation:
scripts/run_tests.sh -j 8 tests/dashboard/test_ws_client_host.py tests/hermes_cli/test_dashboard_auth_ws_auth.py tests/hermes_cli/test_dashboard_auth_ws_tickets.py tests/hermes_cli/test_dashboard_internal_capabilities.py tests/hermes_cli/test_web_server.py tests/hermes_cli/test_web_server_profile_unification.py tests/test_tui_gateway_entry_capability_env.py tests/test_tui_gateway_server.py tests/tools/test_hermes_subprocess_env.py tests/tools/test_local_env_blocklist.pyLatest conflict refresh (2026-07-23)
This section supersedes the earlier merge-based refresh. The single functional commit was replayed cleanly onto upstream
main@9b1028f2974f7b456285b23b28eac5336f71e13c, removing the obsolete merge commit; the refreshed head isf86a13b2b46e720e4d8bb26e79d50b951da158ad.The
tui_gateway/entry.pyresolution consumes capability-bearing environment variables before runtime imports while retaining main's stdin EOF recovery hook. The server test file keeps both main's battery coverage and the PR's child-environment capability stripping regression. Independent review confirmed the same 17-file, +605/-194 functional delta was preserved.Validation after conflict resolution:
git diff --check: passed.