From 739b70e8bc1bea203c5a35ab699f1df51d091568 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sun, 6 Sep 2026 01:13:09 +0300 Subject: [PATCH] fix: fail safely in registry admin scripts (#1622) The takedown script previously treated any nonempty `ALL_VERSIONS` value, including `false`, as permission to delete every version. Require exactly `true` when the variable is set, and reject other values before sending a request. Enable strict shell error handling in the auth helper so a failed identity-token command stops execution before exchanging an empty token. Validation: `bash -n` and `git diff --check` passed. Mocked command checks confirmed that `false`, `1`, and `TRUE` are rejected before network access, and that identity-token retrieval failure stops before the token exchange. The updated scripts also completed the authorized takedown associated with #1563; public API reads confirmed the deleted record and removal from default results. --- tools/admin/auth.sh | 14 ++++++++++---- tools/admin/takedown.sh | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/tools/admin/auth.sh b/tools/admin/auth.sh index 1d4324b..8062e44 100755 --- a/tools/admin/auth.sh +++ b/tools/admin/auth.sh @@ -1,6 +1,8 @@ #!/bin/bash # Simple OIDC authentication helper using gcloud +set -euo pipefail + REGISTRY_URL="${REGISTRY_URL:-https://registry.modelcontextprotocol.io}" if ! gcloud projects list &> /dev/null; then @@ -11,19 +13,23 @@ fi OIDC_TOKEN=$(gcloud auth print-identity-token) # Exchange for registry token -RESPONSE=$(curl -s -X POST "${REGISTRY_URL}/v0/auth/oidc" \ +RESPONSE=$(curl -sS -X POST "${REGISTRY_URL}/v0/auth/oidc" \ -H "Content-Type: application/json" \ -d "{\"oidc_token\": \"${OIDC_TOKEN}\"}") # Check if successful -REGISTRY_TOKEN=$(echo "$RESPONSE" | jq -r '.registry_token // empty') +if ! REGISTRY_TOKEN=$(printf '%s\n' "$RESPONSE" | jq -r '.registry_token // empty' 2>/dev/null); then + REGISTRY_TOKEN="" +fi if [ -z "$REGISTRY_TOKEN" ]; then echo "Error: Authentication failed" >&2 - echo "$RESPONSE" | jq '.' >&2 + if ! printf '%s\n' "$RESPONSE" | jq '.' >&2 2>/dev/null; then + printf '%s\n' "$RESPONSE" >&2 + fi exit 1 fi # Output the export command echo "# Successfully authenticated! Now run this to use your token:" >&2 -echo "export REGISTRY_TOKEN='${REGISTRY_TOKEN}'" \ No newline at end of file +echo "export REGISTRY_TOKEN='${REGISTRY_TOKEN}'" diff --git a/tools/admin/takedown.sh b/tools/admin/takedown.sh index d6b7dff..f9fceed 100755 --- a/tools/admin/takedown.sh +++ b/tools/admin/takedown.sh @@ -34,6 +34,10 @@ fi # Require an explicit choice, so that a forgotten VERSION cannot silently take # down every version of a server. +if [ -n "$ALL_VERSIONS" ] && [ "$ALL_VERSIONS" != "true" ]; then + echo "Error: ALL_VERSIONS must be exactly true when set." >&2 + exit 1 +fi if [ -n "$VERSION" ] && [ -n "$ALL_VERSIONS" ]; then echo "Error: set either VERSION or ALL_VERSIONS, not both." >&2 exit 1