#!/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//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//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 `) 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-." >&2 exit 1 fi # init.sh runs as root in uid-wrapper.sh BEFORE gosu drops privileges to the # agent user — so $HOME here is /root, not the agent home. Claude Code will # run as the agent user and read its config from $AGENT_HOME/.claude. Resolve # the agent home explicitly so settings.json lands where claude looks. AGENT_USER="${AGENT_USER:-agent}" AGENT_HOME=$(getent passwd "$AGENT_USER" | cut -d: -f6) if [ -z "$AGENT_HOME" ] || [ ! -d "$AGENT_HOME" ]; then AGENT_HOME="/home/$AGENT_USER" fi # CLAUDE_CONFIG_DIR overrides ~/.claude when set. CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$AGENT_HOME/.claude}" mkdir -p "$CONFIG_DIR" chown "$AGENT_USER:" "$CONFIG_DIR" 2>/dev/null || true chmod 0755 "$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" </dev/null || true chmod 0644 "$SETTINGS_FILE" echo "minimax api_key wired via apiKeyHelper at $SETTINGS_FILE (agent_user=$AGENT_USER)"