Fix node diagnostic raw-surface auth boundary - #1886
Open
simple-agent-manager[bot] wants to merge 3 commits into
Open
Fix node diagnostic raw-surface auth boundary#1886simple-agent-manager[bot] wants to merge 3 commits into
simple-agent-manager[bot] wants to merge 3 commits into
Conversation
Contributor
simple-agent-manager
Bot
force-pushed
the
sam/fix-critical-node-wide-c6hc8n
branch
from
August 23, 2026 04:41
02e0ad6 to
77e065f
Compare
simple-agent-manager
Bot
force-pushed
the
sam/fix-critical-node-wide-c6hc8n
branch
2 times, most recently
from
August 23, 2026 05:00
1647877 to
1f025e8
Compare
Auto-committed by SAM on agent completion.
|
30 tasks
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
/events,/events/export,/metrics/export,/logs,/containers,/logs/stream,/debug-package, and existing shared/system-info)./workspaces/{workspaceId}/eventsbehavior for matching workspace auth./api/nodes/:id/...proxy routes intact and sanitizing the log-stream proxy so browserAuthorization/Cookiematerial is not forwarded to the VM agent.Do not merge and do not deploy staging from this PR. This is a constituent fix for a coordinated review wave; the parent will build a mega PR and perform consolidated staging.
Validation
pnpm lintpnpm typecheckpnpm test.claude/rules/47-control-loop-io-budget.md) — N/A: no sweep/cron/alarm candidate selection changed.Additional validation:
cd packages/vm-agent && go test ./internal/server -run 'TestNodeWide|TestWorkspaceScopedEvents'— passed.cd packages/vm-agent && go test ./internal/server— passed.cd packages/vm-agent && go test ./...— passed.cd packages/vm-agent && go vet ./...— passed.cd packages/vm-agent && go test -race ./internal/server -run 'TestNodeWide|TestWorkspaceScopedEvents'— passed.pnpm --filter @simple-agent-manager/api test -- tests/unit/routes/node-observability-logs.test.ts tests/unit/task-callback-auth-routing.test.ts tests/unit/routes/mcp-knowledge-policy-tools.test.ts tests/unit/routes/mcp-streamable-http.test.ts— passed, 4 files / 36 tests.pnpm -s --filter @simple-agent-manager/api test— passed, 591 files / 7923 tests.pnpm format:check— passed.pnpm build— passed.pnpm test— passed, 21 tasks successful; API 591/591 files and web 286/286 files.cd packages/vm-agent && staticcheck ./...— not clean due pre-existing unrelated findings outside this patch, including ACP test unused values, persistence/publish unused helpers, server unused helpers inlogs.go/workspace_routing.go, andTypeRegAdeprecations. No new staticcheck finding is introduced by the touched code.Staging Verification (REQUIRED for all code changes — merge-blocking)
All checkboxes below are mandatory for any PR that changes runtime code (
.ts,.tsx,.go, etc.). WriteN/A: docs-onlyONLY if the PR contains zero runtime code changes. See.claude/rules/13-staging-verification.md.Staging Verification Evidence
Staging was not deployed and not verified for this constituent PR by explicit user instruction: "DO NOT merge the PR and DO NOT deploy staging. The parent will build one mega PR and perform consolidated staging."
UI Compliance Checklist (Required for UI changes)
End-to-End Verification (Required for multi-component changes)
.claude/rules/10-e2e-verification.md)Data Flow Trace
apps/web/src/lib/api/nodes.tscalls/api/nodes/:nodeId/...;apps/api/src/routes/nodes.tsverifies user/node ownership viarequireNodeOwnership, thenapps/api/src/services/node-agent.ts:nodeAgentRequestornodeAgentRawRequestsigns node-scoped management JWTs withsignNodeManagementToken(userId, nodeId, null, env).apps/api/src/routes/nodes.tsmints a node-scoped management JWT, puts it on the VM-agent/logs/streamURL, sets backendAuthorization: Bearer <node-management-token>, and forwards only allowlisted WebSocket handshake headers plusX-SAM-Node-Id.packages/vm-agent/internal/server/server.gomaps node-wide diagnostics to handlers inevents.go,logs.go,debug_package.go, andsystem_info.go; those handlers callrequireNodeEventAuth, which now accepts only node-scoped management JWTs and rejects workspace cookies/workspace-scoped management tokens before returning node-wide data or archives.packages/vm-agent/internal/server/events.go:handleListWorkspaceEventscontinues to callcheckWorkspaceRequestAuthand then reads only the requested workspace events.Capability coverage:
packages/vm-agent/internal/server/events_test.gobuilds a realistic two-workspace single-node fixture with workspace-B canary data across event store, in-memory events, Docker logs/containers, and debug archive paths./logs/stream, management tokens still read node-wide observability, workspace-scoped events remain scoped, invalid/expired/replayed tokens fail closed, auth precedence is deterministic, and denied/debug-packageresponses do not begin partial archives.apps/api/tests/unit/routes/node-observability-logs.test.tsproves the control-plane/api/nodes/:id/logs/streamproxy strips clientAuthorization/Cookieand sends node-management auth to the VM agent.Untested Gaps
Live staging validation is intentionally deferred by explicit parent release contract. Automated local coverage exercises the affected direct VM-agent surfaces and the control-plane log-stream proxy behavior; the parent mega PR must perform live staging and VM/infrastructure verification before merge/deploy.
Post-Mortem (Required for bug fix PRs)
What broke
A workspace-authenticated browser session for one workspace on a multi-workspace node could directly request node-wide diagnostic endpoints and read other workspaces' logs, events, container metadata, raw SQLite exports, and debug-package archive content.
Root cause
packages/vm-agent/internal/server/events.go:requireNodeEventAuthtreated any valid workspace session cookie as sufficient node-wide authorization.logs.go,debug_package.go, exports, and system-info shared that helper even though those endpoints expose node-wide/raw data.Class of bug
Multi-tenant authorization boundary failure / confused trust boundary between workspace-scoped browser auth and node-scoped operator diagnostics.
Why it wasn't caught
The prior tests were source-string assertions that encoded browser workspace auth as expected behavior for node events. There was no adversarial two-workspace canary scenario covering direct HTTP/WebSocket/archive endpoints or control-plane proxy header precedence.
Process fix included in this PR
Added behavioral regression tests in
packages/vm-agent/internal/server/events_test.goandapps/api/tests/unit/routes/node-observability-logs.test.ts, replacing source-string assertions with scenario-driven auth/leakage tests. Public docs/specs now state the node-scoped diagnostic trust boundary.Post-mortem file
This PR body is the post-mortem artifact for this constituent fix; no separate task file was committed to keep the PR tightly scoped per release contract.
Specialist Review Evidence (Required for agent-authored PRs)
If local subagents were used during Phase 5, list every reviewer below. Do NOT merge until every row shows PASS or ADDRESSED. If any reviewer could not complete (timeout, workspace killed, error), you MUST add the
needs-human-reviewlabel and stop — do not self-merge. See.claude/rules/25-review-merge-gate.md.needs-human-reviewlabel added and merge deferred to human — N/A: both local reviewers completed./api/nodes/:id/logs/streamforwarded clientAuthorization/Cookie, which could break VM-agent query-token auth precedence and leak client auth to the node. Fixed by allowlisting WebSocket headers and setting VM-agent node-management Authorization; added route regression test.Exceptions (If any)
Agent Preflight (Required)
Classification
External References
N/A: no external API or third-party documentation was needed; the fix is internal VM-agent/API authorization behavior.
Codebase Impact Analysis
Affected paths:
packages/vm-agent/internal/server/events.gofor shared node-wide diagnostic auth,packages/vm-agent/internal/server/events_test.gofor behavioral coverage across events/logs/exports/debug archive/WebSocket,apps/api/src/routes/nodes.tsfor control-plane log-stream proxy header sanitization, andapps/api/tests/unit/routes/node-observability-logs.test.tsfor the proxy regression. Public docs/spec paths updated underapps/www/src/content/docs/docs/reference/vm-agent.md,specs/020-node-observability/contracts/vm-agent-logs.md, andspecs/014-multi-workspace-nodes/contracts/node-agent-api.md.Documentation & Specs
Updated
apps/www/src/content/docs/docs/reference/vm-agent.mdto document node-scoped management auth for node-wide diagnostics. Updatedspecs/020-node-observability/contracts/vm-agent-logs.mdandspecs/014-multi-workspace-nodes/contracts/node-agent-api.mdso contracts distinguish node-wide diagnostics from workspace-scoped event access.Constitution & Risk Check
Checked Principle XI/no-hardcoded-values: production code adds no hardcoded deployment URL, timeout, limit, or identifier; route behavior continues deriving VM-agent protocol/port/domain and token material from existing config/services. Security risk is intentionally reduced by fail-closing node-wide diagnostics under workspace auth while preserving control-plane proxy workflows and route/response contracts. Staging risk is deferred by explicit parent contract and covered locally with focused VM-agent/API tests plus full monorepo validation.