molecule-core/workspace
Hongming Wang 74c5e0d7a8 fix(workspace-runtime): add Origin header so SaaS edge WAF accepts MCP tool calls
Discovered while smoke-testing the molecule-mcp external-runtime path
against a live tenant (hongmingwang.moleculesai.app). Every tool call
that hit /workspaces/* or /registry/*/peers returned 404 — but
/registry/register and /registry/heartbeat returned 200. Diagnosis:
the tenant's edge WAF requires a same-origin header. Without it,
unhandled paths get silently rewritten to the canvas Next.js app,
which has no /workspaces or /registry/:id/peers route and returns an
empty 404. The molecule-mcp-claude-channel plugin already sets this
header (server.ts:271-276); the workspace runtime never did because
in-container PLATFORM_URLs (Docker network) aren't behind the WAF.

Fix: extend platform_auth.auth_headers() to include
Origin: ${PLATFORM_URL} whenever PLATFORM_URL is set. Inside-container
behavior is unchanged (the WAF is path-irrelevant for the internal
hostnames). External-runtime calls now thread the WAF correctly.

Verification (live, against a freshly-registered external workspace):
  pre-fix:  get_workspace_info → "not found", list_peers → 404
  post-fix: get_workspace_info → full workspace JSON,
            list_peers → "Claude Code Agent (ID: 97ac32e9..., status: online)"

This is the kind of bug unit tests can never catch — caught only by
running the wheel against the real tenant. Memory:
feedback_always_run_e2e.md.

Test coverage: 4 new tests in test_platform_auth.py — Origin alone
when no token + Origin + Authorization both, no-PLATFORM_URL falls
through to original empty-dict behavior, env-token path with Origin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 15:30:15 -07:00
..
adapters fix: comprehensive a2a-sdk 1.x migration sweep across workspace/ 2026-04-27 09:42:57 -07:00
builtin_tools feat(harness): coordinator phase-boundary instrumentation for RFC #2251 2026-04-28 20:11:46 -07:00
lib feat(workspace): pre-stop serialization for pause/resume (closes #1386) 2026-04-21 12:40:44 +00:00
molecule_audit chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
platform_tools Merge pull request #2261 from Molecule-AI/fix/harness-cleanup-failed-event 2026-04-29 05:35:43 +00:00
plugins_registry feat(plugin): implement MCPServerAdaptor (issue #847) 2026-04-24 01:42:13 +00:00
policies feat(platform): single-source-of-truth tool registry — adapters consume, no drift 2026-04-28 17:11:36 -07:00
scripts fix(git-token-helper): close TOCTOU window + stop swallowing chmod errors (closes #1552) 2026-04-26 08:22:29 -07:00
skill_loader feat(skills): per-skill runtime compatibility (#119, hermes pattern) 2026-04-27 01:57:43 -07:00
tests fix(workspace-runtime): add Origin header so SaaS edge WAF accepts MCP tool calls 2026-04-30 15:30:15 -07:00
.coveragerc test(workspace): centralize pytest-cov config + 92% floor (closes #1817) 2026-04-26 06:21:22 -07:00
a2a_cli.py fix(runtime): use lowercase wire role for v0.3 JSON-RPC compat layer 2026-04-27 12:40:11 -07:00
a2a_client.py feat(workspace): surface peer-discovery failure reason instead of "may be isolated" 2026-04-30 11:09:26 -07:00
a2a_executor.py fix: comprehensive a2a-sdk 1.x migration sweep across workspace/ 2026-04-27 09:42:57 -07:00
a2a_mcp_server.py feat(workspace-runtime): expose universal MCP server to runtime=external operators 2026-04-30 15:20:19 -07:00
a2a_tools.py feat(workspace): surface peer-discovery failure reason instead of "may be isolated" 2026-04-30 11:09:26 -07:00
adapter_base.py feat(platform): single-source-of-truth tool registry — adapters consume, no drift 2026-04-28 17:11:36 -07:00
agent.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
agents_md.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
build-all.sh fix: update workspace script comments for workspace-template → workspace rename 2026-04-18 01:48:05 -07:00
config.py fix(compliance): flip default mode to owasp_agentic (detect-only) 2026-04-24 11:52:09 -07:00
consolidation.py fix: apply #1124 env-var defaults + scrub F1088 credentials from INCIDENT_LOG.md (#1347) 2026-04-21 08:11:44 +00:00
coordinator.py feat(harness): coordinator phase-boundary instrumentation for RFC #2251 2026-04-28 20:11:46 -07:00
Dockerfile feat(workspace): 45-min gh-token refresh daemon + credential helper cache 2026-04-22 19:52:46 -07:00
entrypoint.sh fix(workspace): credential helper security hardening (#1797) 2026-04-23 18:14:55 +00:00
events.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
executor_helpers.py feat(prompt): Platform Capabilities preamble at top of system prompt 2026-04-29 21:31:13 -07:00
heartbeat.py fix(runtime): use lowercase wire role for v0.3 JSON-RPC compat layer 2026-04-27 12:40:11 -07:00
initial_prompt.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
internal_chat_uploads.py feat(workspace): /internal/chat/uploads/ingest endpoint (RFC #2312, PR-B) 2026-04-29 14:16:32 -07:00
internal_file_read.py feat(chat_files): rewrite Download as HTTP-forward (RFC #2312, PR-D) 2026-04-29 15:19:02 -07:00
main.py feat(chat_files): rewrite Download as HTTP-forward (RFC #2312, PR-D) 2026-04-29 15:19:02 -07:00
mcp_cli.py feat(workspace-runtime): expose universal MCP server to runtime=external operators 2026-04-30 15:20:19 -07:00
molecule_ai_status.py fix(runtime): replace remaining /app/ legacy paths in agent prompts + docstrings 2026-04-27 11:22:00 -07:00
platform_auth.py fix(workspace-runtime): add Origin header so SaaS edge WAF accepts MCP tool calls 2026-04-30 15:30:15 -07:00
platform_inbound_auth.py feat(saas): deliver platform_inbound_secret via /registry/register (RFC #2312, PR-F) 2026-04-29 15:12:34 -07:00
plugins.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
preflight.py feat(preflight): replace SUPPORTED_RUNTIMES static list with adapter discovery 2026-04-27 00:44:51 -07:00
prompt.py feat(prompt): Platform Capabilities preamble at top of system prompt 2026-04-29 21:31:13 -07:00
pytest.ini feat(preflight): replace SUPPORTED_RUNTIMES static list with adapter discovery 2026-04-27 00:44:51 -07:00
rebuild-runtime-images.sh fix: update workspace script comments for workspace-template → workspace rename 2026-04-18 01:48:05 -07:00
requirements.txt feat(workspace): /internal/chat/uploads/ingest endpoint (RFC #2312, PR-B) 2026-04-29 14:16:32 -07:00
runtime_wedge.py chore(workspace): drop claude_sdk_executor — Phase 2 of #87 2026-04-27 00:52:55 -07:00
shared_runtime.py feat(platform): single-source-of-truth tool registry — adapters consume, no drift 2026-04-28 17:11:36 -07:00
transcript_auth.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
watcher.py chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00