Skip to content

fix(handlers): KI-005 — CanCommunicate hierarchy guard on terminal endpoint - #1690

Closed
molecule-ai[bot] wants to merge 4 commits into
mainfrom
fix/ki005-terminal-auth
Closed

molecule-ai[bot] wants to merge 4 commits into
mainfrom
fix/ki005-terminal-auth

Conversation

@molecule-ai

@molecule-ai molecule-ai Bot commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Closing duplicate — fix is in PR #1681.

Molecule AI App-FE and others added 3 commits April 22, 2026 23:32
Both handlers used shell-interpolated concat form "/configs/" + path
which allows path traversal to escape the /configs bind mount.
Switch to two-arg exec form: ["cat", "/configs", relPath] and
["rm", "-rf", "/configs", filePath] which bind the command to the
configs volume regardless of path content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Validate() scans: SELECT id, prefix, org_id FROM org_api_tokens
(sql.NullString for org_id). Updated all mock expectations:
- TestValidate_HappyPath: 3-column WillReturnRows
- TestValidate_UnknownHashErrInvalid: 3-col regex, ErrNoRows
- TestValidate_RevokedTokenNotAccepted: 3-col regex, ErrNoRows

Also rewrote wsauth_middleware_org_id_test.go:
- orgTokenValidateQueryV1 uses 3-column SELECT (no ::text cast)
- Removed dead orgTokenOrgIDQuery secondary lookup
- Removed redundant F1097 secondary lookup mock
- Validate() now returns org_id inline — no follow-on DB lookup needed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…I-005)

KI-005 CRITICAL: terminal.go HandleConnect had zero CanCommunicate check.
Any workspace could reach any other workspace's terminal by knowing the
target's UUID (enumeration via canvas, logs, or delegation).

Fix: when caller presents X-Workspace-ID header with a bearer token:
1. ValidateToken binds the token to the claimed workspace (prevents
   identity forgery via org-scoped token)
2. canCommunicateCheck(callerID, workspaceID) gates terminal access

Self-access (callerID == workspaceID) always allowed — a workspace's
own token reaches its own terminal without hierarchy check.

Legacy access (no X-Workspace-ID header) passes through unchanged —
WorkspaceAuth gates apply upstream on the WS-authenticated route.

Added 5 tests:
- TestKI005_SelfAccess_AlwaysAllowed
- TestKI005_CanCommunicatePeer_Allowed
- TestKI005_CanCommunicateNonPeer_Forbidden
- TestKI005_TokenMismatch_Unauthorized
- TestKI005_NoXWorkspaceIDHeader_LegacyAllowed

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve conflicts:
- wsauth_middleware_org_id_test.go: take 3-column org_id scan version
- orgtoken/tokens_test.go: take 3-column org_id scan version

Both our staged files and origin/main's files reflect the F1097
migration-036 org_id single-round-trip refactor; the only difference
was the base version (stage 1) still had the pre-migration 2-query
pattern. Take the post-migration version from stage 2.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Closing — per own body text, duplicate of #1681; the KI-005 CanCommunicate guard was landed via commit 66ea0b6 (#1574) and is present on current staging.

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.

1 participant