fix(minimax): wire api_key via apiKeyHelper, never via env
Mirrors agent-runtimes commit 1b83c81. CRS serves these harness files to dispatchers, so this repo must match for the fix to take effect. The minimax harness now writes ~/.claude/settings.json with an apiKeyHelper that `cat`s the ESO-mounted /run/agent/secrets/minimax/ api_key file. Claude Code routes apiKeyHelper output to `Authorization: Bearer <value>` for non-anthropic.com base URLs, which is what MiniMax's /anthropic proxy requires. The secret is never read into env, never written into a config file, and ESO rotation is auto-recovered via Claude Code's per-session helper invocation (also re-runs after a 401). - harness.yaml: drop ANTHROPIC_AUTH_TOKEN_FILE env var - init.sh: write (or jq-merge) settings.json with apiKeyHelper, chmod 0600 - bin/anthropic-compat-wrapper.sh: deleted Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Anthropic-compat wrapper for MiniMax (Phase 9 ESO-managed secrets).
|
|
||||||
# Reads the api_key file and passes it as ANTHROPIC_AUTH_TOKEN to claude.
|
|
||||||
# ANTHROPIC_BASE_URL is set in harness.yaml `env:` and flows through.
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
exec env \
|
|
||||||
ANTHROPIC_AUTH_TOKEN="$(cat /run/agent/secrets/minimax/api_key)" \
|
|
||||||
claude "$@"
|
|
||||||
@@ -5,9 +5,11 @@ description: "MiniMax coding plan — Anthropic-compatible proxy"
|
|||||||
requires: []
|
requires: []
|
||||||
provides: [claude-code]
|
provides: [claude-code]
|
||||||
|
|
||||||
|
# Auth is wired by init.sh via Claude Code's apiKeyHelper (settings.json).
|
||||||
|
# No credential env vars: the secret stays in the mounted file and is read
|
||||||
|
# only by the helper command at request time.
|
||||||
env:
|
env:
|
||||||
ANTHROPIC_BASE_URL: "https://api.minimax.io/anthropic"
|
ANTHROPIC_BASE_URL: "https://api.minimax.io/anthropic"
|
||||||
ANTHROPIC_AUTH_TOKEN_FILE: "/run/agent/secrets/minimax/api_key"
|
|
||||||
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1"
|
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS: "1"
|
||||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"
|
||||||
DISABLE_PROMPT_CACHING: "1"
|
DISABLE_PROMPT_CACHING: "1"
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -euo pipefail
|
# minimax init — write ~/.claude/settings.json with apiKeyHelper.
|
||||||
|
|
||||||
# Verify the ESO-managed MiniMax api_key file is mounted. The wrapper
|
|
||||||
# (`bin/anthropic-compat-wrapper.sh`) reads it at exec time and exports
|
|
||||||
# ANTHROPIC_AUTH_TOKEN to the claude subprocess.
|
|
||||||
#
|
#
|
||||||
# ANTHROPIC_BASE_URL is set in harness.yaml `env:` (not in the K8s Secret),
|
# The MiniMax API key is mounted by ESO at /run/agent/secrets/minimax/api_key
|
||||||
# so no file check is required for it.
|
# (mode 0400, secrets_required entry in harness.yaml). Claude Code's
|
||||||
|
# `apiKeyHelper` setting names a command that prints the key on stdout when
|
||||||
|
# the CLI needs it for an API request — the value never enters this process'
|
||||||
|
# environment, never appears in /proc/<pid>/environ of the claude subprocess,
|
||||||
|
# and is read fresh on each invocation so ESO secret rotations are picked up
|
||||||
|
# without a process restart.
|
||||||
|
#
|
||||||
|
# Why settings.json (not --settings inline or env vars):
|
||||||
|
# - ANTHROPIC_AUTH_TOKEN / ANTHROPIC_API_KEY in env exposes the secret in
|
||||||
|
# /proc/<pid>/environ, log aggregators, ps. The H-SECRET-4 rule disallows
|
||||||
|
# credential-shaped env vars for that reason.
|
||||||
|
# - --settings on the runner CLI line couples the runner to the harness
|
||||||
|
# layout. Per-harness settings.json keeps auth a harness concern.
|
||||||
|
# - The helper command (`cat <file>`) re-reads on each call, so secret
|
||||||
|
# rotation propagates without rewriting the config file.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
API_KEY_FILE="/run/agent/secrets/minimax/api_key"
|
API_KEY_FILE="/run/agent/secrets/minimax/api_key"
|
||||||
|
|
||||||
@@ -15,4 +27,30 @@ if [ ! -r "$API_KEY_FILE" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "minimax api_key verified at $API_KEY_FILE"
|
# Resolve the agent's home and write settings.json there. CLAUDE_CONFIG_DIR
|
||||||
|
# overrides ~/.claude when set; honour it so non-default profiles work.
|
||||||
|
CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
|
||||||
|
mkdir -p "$CONFIG_DIR"
|
||||||
|
chmod 0700 "$CONFIG_DIR"
|
||||||
|
|
||||||
|
SETTINGS_FILE="$CONFIG_DIR/settings.json"
|
||||||
|
|
||||||
|
# If a settings.json already exists from another harness layer, merge
|
||||||
|
# apiKeyHelper into it; otherwise create a minimal file. jq is in the base
|
||||||
|
# image; fall back to a clean overwrite if it isn't available for any reason.
|
||||||
|
if [ -f "$SETTINGS_FILE" ] && command -v jq >/dev/null 2>&1; then
|
||||||
|
TMP=$(mktemp)
|
||||||
|
jq --arg helper "cat $API_KEY_FILE" \
|
||||||
|
'. + {apiKeyHelper: $helper}' \
|
||||||
|
"$SETTINGS_FILE" > "$TMP"
|
||||||
|
mv "$TMP" "$SETTINGS_FILE"
|
||||||
|
else
|
||||||
|
cat > "$SETTINGS_FILE" <<EOF
|
||||||
|
{
|
||||||
|
"apiKeyHelper": "cat $API_KEY_FILE"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod 0600 "$SETTINGS_FILE"
|
||||||
|
echo "minimax api_key wired via apiKeyHelper at $SETTINGS_FILE"
|
||||||
|
|||||||
Reference in New Issue
Block a user