From 50b9181fd40d77ca3d1ef2b1abb38b0ee0d5e2fc Mon Sep 17 00:00:00 2001 From: "Molecule AI Dev Engineer A (Kimi)" Date: Fri, 22 May 2026 09:56:03 +0000 Subject: [PATCH 1/2] =?UTF-8?q?fix(e2e):=20#1644=20Part=20A=20=E2=80=94=20?= =?UTF-8?q?peer-visibility=20scripts=20consume=20inline=20auth=5Ftoken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test_peer_visibility_mcp_local.sh: - Remove dev-only GET /admin/workspaces/:id/test-token preflight and mint. - Extract auth_token inline from POST /workspaces 201 response. - Store tokens in WS_TOKENS_MAP (bash 3.2 portable) and use at gate time. - test_peer_visibility_mcp_staging.sh: - Remove fallback to POST /admin/workspaces/$WID/tokens admin route. - Rely solely on inline auth_token from create response; fail fast if absent. - Update auth-model comment to reflect no dev-only routes in E2E. Both scripts now consume the workspace bearer directly from the create payload (PR#1669), satisfying feedback_no_dev_only_routes_in_e2e. Co-Authored-By: Claude Opus 4.7 --- tests/e2e/test_peer_visibility_mcp_local.sh | 47 +++++++++++-------- tests/e2e/test_peer_visibility_mcp_staging.sh | 37 +++------------ 2 files changed, 33 insertions(+), 51 deletions(-) diff --git a/tests/e2e/test_peer_visibility_mcp_local.sh b/tests/e2e/test_peer_visibility_mcp_local.sh index 4fd378d45..da8a2550a 100755 --- a/tests/e2e/test_peer_visibility_mcp_local.sh +++ b/tests/e2e/test_peer_visibility_mcp_local.sh @@ -24,14 +24,12 @@ # # Only PROVISIONING differs from staging: # - staging: POST /cp/admin/orgs (cold EC2 tenant) + per-tenant admin -# token + each workspace's MCP bearer from create response or an admin -# token-mint fallback. +# token + each workspace's MCP bearer from the POST /workspaces +# create response. # - local: POST /workspaces directly against the local stack -# (BASE, default http://localhost:8080), MCP bearer minted via -# GET /admin/workspaces/:id/test-token (e2e_mint_test_token — -# deterministic, gated by MOLECULE_ENV != production). Same model -# every other local E2E (test_priority_runtimes_e2e.sh, -# test_api.sh) already uses; no new credential/provision flow. +# (BASE, default http://localhost:8080), MCP bearer consumed inline +# from the create response (auth_token field). Same model every +# other local E2E uses; no new credential/provision flow. # # By default the local backend creates external-mode workspace rows and # drives the literal MCP path directly. That keeps the local peer-visibility @@ -81,6 +79,17 @@ NAME_PREFIX="PV-Local-$$-$(date +%H%M%S)" log() { echo "[$(date +%H:%M:%S)] $*"; } ok() { echo "[$(date +%H:%M:%S)] ✅ $*"; } +extract_auth_token() { + python3 -c " +import sys, json +try: + d = json.load(sys.stdin) +except Exception: + print(''); sys.exit(0) +print(d.get('auth_token') or d.get('connection', {}).get('auth_token') or '') +" 2>/dev/null +} + CREATED_WSIDS=() ADMIN_BEARER="${MOLECULE_ADMIN_TOKEN:-${ADMIN_TOKEN:-}}" ADMIN_AUTH=() @@ -131,17 +140,6 @@ if ! curl -fsS "$BASE/health" -m 5 >/dev/null 2>&1; then echo "::error::Local stack not healthy at $BASE/health — bring it up (make up) before this gate. Infra, not a workspace bug (feedback_fix_root_not_symptom)." >&2 exit 1 fi -# admin/test-token is the local MCP-bearer mint path; it 404s in -# production. If it is off, this gate cannot drive the literal call. -if ! curl -fsS "$BASE/admin/workspaces/preflight-probe/test-token" ${ADMIN_AUTH[@]+"${ADMIN_AUTH[@]}"} -m 5 >/dev/null 2>&1; then - # A 404 here is EITHER "no such ws" (fine — endpoint is enabled) OR the - # endpoint is disabled (MOLECULE_ENV=production). Distinguish by body. - PROBE=$(curl -s "$BASE/admin/workspaces/preflight-probe/test-token" ${ADMIN_AUTH[@]+"${ADMIN_AUTH[@]}"} -m 5 2>/dev/null) - if echo "$PROBE" | grep -qi 'production\|disabled\|not found.*endpoint'; then - echo "::error::GET /admin/workspaces/:id/test-token disabled (MOLECULE_ENV=production?). Cannot mint a local MCP bearer." >&2 - exit 1 - fi -fi ok " local stack healthy" # ─── Resolve per-runtime provisioning secrets ────────────────────────── @@ -244,6 +242,7 @@ log "1/5 provisioning parent ($PARENT_RUNTIME, mode=$PV_LOCAL_PROVISION_MODE) + P_RESP=$(curl -s -X POST "$BASE/workspaces" ${ADMIN_AUTH[@]+"${ADMIN_AUTH[@]}"} -H "Content-Type: application/json" \ -d "{\"name\":\"${NAME_PREFIX}-parent\",\"runtime\":\"$PARENT_RUNTIME\",\"tier\":3$PARENT_EXTRA,\"secrets\":$PARENT_SECRETS}") PARENT_ID=$(echo "$P_RESP" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("id",""))' 2>/dev/null) +PARENT_TOKEN=$(echo "$P_RESP" | extract_auth_token) if [ -z "$PARENT_ID" ]; then echo "::error::parent create failed: $(echo "$P_RESP" | head -c 300)" >&2 exit 1 @@ -259,6 +258,8 @@ log " PARENT_ID=$PARENT_ID runtime=$PARENT_RUNTIME" WS_IDS_MAP="" # shellcheck disable=SC2034 # map values are updated through portable eval-based helpers. VERDICT_MAP="" +# shellcheck disable=SC2034 # map values are updated through portable eval-based helpers. +WS_TOKENS_MAP="" _map_set() { # _map_set local __m="$1" __k="$2" __v="$3" __cur eval "__cur=\$$__m" @@ -294,11 +295,17 @@ for rt in $PV_RUNTIMES; do R=$(curl -s -X POST "$BASE/workspaces" ${ADMIN_AUTH[@]+"${ADMIN_AUTH[@]}"} -H "Content-Type: application/json" \ -d "{\"name\":\"${NAME_PREFIX}-$rt\",\"runtime\":\"$CREATE_RUNTIME\",\"tier\":2,\"parent_id\":\"$PARENT_ID\"$CREATE_EXTRA,\"secrets\":$SEC}") WID=$(echo "$R" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("id",""))' 2>/dev/null) + WTOK=$(echo "$R" | extract_auth_token) if [ -z "$WID" ]; then echo "::error::$rt workspace create failed: $(echo "$R" | head -c 300)" >&2 exit 1 fi + if [ -z "$WTOK" ]; then + echo "::error::$rt workspace create did not return an auth_token — cannot drive the literal MCP call" >&2 + exit 1 + fi _map_set WS_IDS_MAP "$rt" "$WID" + _map_set WS_TOKENS_MAP "$rt" "$WTOK" CREATED_WSIDS+=("$WID") ALL_WS_IDS="$ALL_WS_IDS $WID" ACTIVE_RUNTIMES="$ACTIVE_RUNTIMES $rt" @@ -356,10 +363,10 @@ log "4/5 driving the LITERAL list_peers MCP call per online runtime..." echo "" for rt in $ONLINE_RUNTIMES; do wid="$(_map_get WS_IDS_MAP "$rt")" - WTOK=$(e2e_mint_test_token "$wid" 2>/dev/null || true) + WTOK="$(_map_get WS_TOKENS_MAP "$rt")" if [ -z "$WTOK" ]; then echo "--- $rt (ws=$wid) ---" - echo " ✗ $rt: could not mint a local MCP bearer (admin/test-token) — cannot drive the literal call" + echo " ✗ $rt: workspace create did not return an auth_token — cannot drive the literal call" _map_set VERDICT_MAP "$rt" "FAIL(no-bearer)" REGRESSED=1 echo "" diff --git a/tests/e2e/test_peer_visibility_mcp_staging.sh b/tests/e2e/test_peer_visibility_mcp_staging.sh index 43daf0646..e7c5af3eb 100755 --- a/tests/e2e/test_peer_visibility_mcp_staging.sh +++ b/tests/e2e/test_peer_visibility_mcp_staging.sh @@ -40,10 +40,10 @@ # drives: POST /cp/admin/orgs (provision), GET # /cp/admin/orgs/:slug/admin-token (per-tenant token), DELETE # /cp/admin/tenants/:slug (teardown). The per-tenant admin token drives -# tenant workspace creation; each workspace's OWN auth_token drives its -# MCP call. External-like runtimes may return the token in POST -# /workspaces; managed container runtimes usually require the admin token -# mint fallback below. +# tenant workspace creation; each workspace's OWN auth_token is consumed +# inline from the POST /workspaces 201 response to drive its MCP call. +# No dev-only admin token-mint routes are used in this E2E +# (feedback_no_dev_only_routes_in_e2e). # # Required env: # MOLECULE_ADMIN_TOKEN CP admin bearer — Railway staging CP_ADMIN_API_TOKEN @@ -265,44 +265,19 @@ log " PARENT_ID=$PARENT_ID" # WS_IDS[runtime]=id ; WS_TOKENS[runtime]=auth_token (the MCP bearer) declare -A WS_IDS WS_TOKENS ALL_WS_IDS="$PARENT_ID" -TOKEN_ERRORS=0 -TOKEN_ERROR_SUMMARY="" for rt in $PV_RUNTIMES; do R=$(tenant_call POST /workspaces \ -d "{\"name\":\"pv-$rt\",\"runtime\":\"$rt\",\"tier\":2,\"parent_id\":\"$PARENT_ID\",\"secrets\":$SECRETS_JSON}") WID=$(echo "$R" | python3 -c "import sys,json; print(json.load(sys.stdin).get('id',''))" 2>/dev/null) - # External-like runtimes may return connection.auth_token on create. - # Managed container runtimes usually return only id/status here, then - # receive their bearer through registry/bootstrap; for this literal MCP - # driver we mint through the production-safe admin token route below. WTOK=$(echo "$R" | extract_auth_token) - [ -n "$WID" ] || fail "$rt workspace create failed: $(echo "$R" | head -c 300)" - TOKEN_DIAG="" - if [ -z "$WTOK" ]; then - TTOK_FILE=$(mktemp) - TTOK_CODE=$(tenant_call_capture POST "/admin/workspaces/$WID/tokens" "$TTOK_FILE" 2>/dev/null || echo "curl_error") - TTOK_RESP=$(cat "$TTOK_FILE" 2>/dev/null || true) - WTOK=$(echo "$TTOK_RESP" | extract_auth_token) - TOKEN_DIAG="POST /admin/workspaces/$WID/tokens -> HTTP $TTOK_CODE body: $(echo "$TTOK_RESP" | redact_token_body)" - rm -f "$TTOK_FILE" - fi + [ -n "$WID" ] || fail "$rt workspace create failed: $(echo \"$R\" | head -c 300)" + [ -n "$WTOK" ] || fail "$rt workspace create did not return an auth_token — cannot drive its MCP call (workspace_id=$WID; create_resp: $(echo \"$R\" | redact_token_body))" WS_IDS[$rt]="$WID" - if [ -z "$WTOK" ]; then - TOKEN_ERRORS=$((TOKEN_ERRORS + 1)) - TOKEN_ERROR_SUMMARY="${TOKEN_ERROR_SUMMARY} -[$rt] workspace did not return or mint an auth_token — cannot drive its MCP call (workspace_id=$WID; create_resp: $(echo "$R" | redact_token_body); token_fallbacks: $TOKEN_DIAG)" - log " $rt → $WID (token acquisition failed; continuing to classify other runtimes)" - continue - fi WS_TOKENS[$rt]="$WTOK" ALL_WS_IDS="$ALL_WS_IDS $WID" log " $rt → $WID" done -if [ "$TOKEN_ERRORS" -gt 0 ]; then - fail "token acquisition failed for $TOKEN_ERRORS runtime(s):$TOKEN_ERROR_SUMMARY" -fi - if [ "${PV_TOKEN_DIAGNOSTIC_ONLY:-0}" = "1" ]; then ok "token diagnostic passed for runtimes: $PV_RUNTIMES" exit 0 -- 2.52.0 From d7519d815a19158063c7e58f679e76445583c00d Mon Sep 17 00:00:00 2001 From: cp-be Date: Fri, 22 May 2026 03:50:50 -0700 Subject: [PATCH 2/2] =?UTF-8?q?fix(e2e):=20#1644=20Part=20A=20=E2=80=94=20?= =?UTF-8?q?SC2034=20disable=20directive=20for=20PARENT=5FTOKEN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit shellcheck E2E job on PR#1680 (task 146208) flagged: In tests/e2e/test_peer_visibility_mcp_local.sh line 245: PARENT_TOKEN=$(echo "$P_RESP" | extract_auth_token) ^----------^ SC2034 (warning): PARENT_TOKEN appears unused. PARENT_TOKEN is captured for symmetry with the per-sibling auth-token capture below + reserved as a hand-off point for follow-up parent-auth flows. The current downstream peer-visibility checks reach the parent workspace via the admin token, so PARENT_TOKEN isn't dereferenced — surfacing as SC2034. Same disable-directive pattern as the WS_IDS_MAP / VERDICT_MAP declarations a few lines below (lines 257, 260) — surface the intention via comment rather than silence the lint. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/e2e/test_peer_visibility_mcp_local.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/e2e/test_peer_visibility_mcp_local.sh b/tests/e2e/test_peer_visibility_mcp_local.sh index da8a2550a..a69bc40a9 100755 --- a/tests/e2e/test_peer_visibility_mcp_local.sh +++ b/tests/e2e/test_peer_visibility_mcp_local.sh @@ -242,6 +242,11 @@ log "1/5 provisioning parent ($PARENT_RUNTIME, mode=$PV_LOCAL_PROVISION_MODE) + P_RESP=$(curl -s -X POST "$BASE/workspaces" ${ADMIN_AUTH[@]+"${ADMIN_AUTH[@]}"} -H "Content-Type: application/json" \ -d "{\"name\":\"${NAME_PREFIX}-parent\",\"runtime\":\"$PARENT_RUNTIME\",\"tier\":3$PARENT_EXTRA,\"secrets\":$PARENT_SECRETS}") PARENT_ID=$(echo "$P_RESP" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("id",""))' 2>/dev/null) +# PARENT_TOKEN captured for symmetry with the per-sibling auth-token +# capture in the runtime loop below + reserved for follow-up steps +# that need parent-side auth. Current downstream steps reach the parent +# via admin token, so the variable isn't dereferenced — SC2034. +# shellcheck disable=SC2034 # captured for downstream parent-auth use; see #1644 follow-up PARENT_TOKEN=$(echo "$P_RESP" | extract_auth_token) if [ -z "$PARENT_ID" ]; then echo "::error::parent create failed: $(echo "$P_RESP" | head -c 300)" >&2 -- 2.52.0