Files
agent-runtime-framework/harnesses/contexts/minimax/v1/init.sh
Paul O'Reilly cb1b411276 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>
2026-05-07 13:14:21 +12:00

57 lines
2.2 KiB
Bash
Executable File

#!/bin/bash
# minimax init — write ~/.claude/settings.json with apiKeyHelper.
#
# The MiniMax API key is mounted by ESO at /run/agent/secrets/minimax/api_key
# (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"
if [ ! -r "$API_KEY_FILE" ]; then
echo "ERROR: $API_KEY_FILE not readable. Check ESO ExternalSecret acct-<minimax-id>." >&2
exit 1
fi
# 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"