Skip to content

Commit 2aff0f3

Browse files
lpcoxCopilotCopilot
authored
fix: copy get-claude-key.sh to chroot-accessible path (#1508)
* fix: copy get-claude-key.sh to chroot-accessible path In chroot mode, /usr is bind-mounted from the host (read-only), shadowing the container's /usr/local/bin/get-claude-key.sh. Claude Code finds the apiKeyHelper config but the script fails with exit 127 (not found). Follow the existing one-shot-token.so pattern: copy the script to /host/tmp/awf-lib/ before chroot activation, then update the apiKeyHelper config files to reference the chroot-accessible path. Closes #1507 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update containers/agent/entrypoint.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: overwrite stale apiKeyHelper path instead of erroring When settings.json persists between AWF runs (e.g. in CI), a previous run's chroot-adjusted path (/tmp/awf-lib/get-claude-key.sh) causes a mismatch with the current env var (/usr/local/bin/get-claude-key.sh). Overwrite with the current value instead of exiting with an error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent ddfbc43 commit 2aff0f3

1 file changed

Lines changed: 52 additions & 5 deletions

File tree

containers/agent/entrypoint.sh

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,26 @@ if [ -n "$CLAUDE_CODE_API_KEY_HELPER" ]; then
175175
if grep -q '"apiKeyHelper"' "$config_file"; then
176176
CONFIGURED_HELPER=$(grep -o '"apiKeyHelper":"[^"]*"' "$config_file" | cut -d'"' -f4)
177177
if [ "$CONFIGURED_HELPER" != "$CLAUDE_CODE_API_KEY_HELPER" ]; then
178-
echo "[entrypoint][ERROR] apiKeyHelper mismatch in $label:"
179-
echo "[entrypoint][ERROR] Environment variable: $CLAUDE_CODE_API_KEY_HELPER"
180-
echo "[entrypoint][ERROR] Config file value: $CONFIGURED_HELPER"
181-
exit 1
178+
# Overwrite stale path (e.g. a previous run's chroot-adjusted path)
179+
echo "[entrypoint] Updating apiKeyHelper in $label (was: $CONFIGURED_HELPER)"
180+
if AWF_CONFIG_FILE="$config_file" AWF_KEY_HELPER="$CLAUDE_CODE_API_KEY_HELPER" \
181+
node -e "
182+
const fs = require('fs');
183+
const f = process.env.AWF_CONFIG_FILE;
184+
const obj = JSON.parse(fs.readFileSync(f, 'utf8'));
185+
obj.apiKeyHelper = process.env.AWF_KEY_HELPER;
186+
fs.writeFileSync(f, JSON.stringify(obj) + '\n');
187+
" 2>/dev/null; then
188+
chmod 666 "$config_file"
189+
echo "[entrypoint] ✓ Updated apiKeyHelper in $label"
190+
else
191+
echo "{\"apiKeyHelper\":\"$CLAUDE_CODE_API_KEY_HELPER\"}" > "$config_file"
192+
chmod 666 "$config_file"
193+
echo "[entrypoint] ✓ Wrote apiKeyHelper to $label (overwrite fallback)"
194+
fi
195+
else
196+
echo "[entrypoint] ✓ $label apiKeyHelper validated"
182197
fi
183-
echo "[entrypoint] ✓ $label apiKeyHelper validated"
184198
else
185199
echo "[entrypoint] $label exists but missing apiKeyHelper, merging..."
186200
# Use node to safely add apiKeyHelper to existing JSON without losing other fields
@@ -426,6 +440,39 @@ if [ "${AWF_CHROOT_ENABLED}" = "true" ]; then
426440
fi
427441
fi
428442

443+
# Copy get-claude-key.sh to chroot-accessible path
444+
# The script is baked into the Docker image at /usr/local/bin/, but the chroot
445+
# bind-mounts the host's /usr (read-only), shadowing the container's copy.
446+
# We must copy it to /tmp/awf-lib/ (writable) before the chroot activates.
447+
if [ -n "$CLAUDE_CODE_API_KEY_HELPER" ] && [ -f "$CLAUDE_CODE_API_KEY_HELPER" ]; then
448+
if mkdir -p /host/tmp/awf-lib 2>/dev/null; then
449+
CHROOT_KEY_HELPER="/tmp/awf-lib/$(basename "$CLAUDE_CODE_API_KEY_HELPER")"
450+
if cp "$CLAUDE_CODE_API_KEY_HELPER" "/host${CHROOT_KEY_HELPER}" 2>/dev/null && \
451+
chmod +x "/host${CHROOT_KEY_HELPER}" 2>/dev/null; then
452+
echo "[entrypoint] Claude key helper copied to chroot at ${CHROOT_KEY_HELPER}"
453+
# Update apiKeyHelper in config files to use the chroot-accessible path
454+
for cfg in "/host$HOME/.claude.json" "/host$HOME/.claude/settings.json"; do
455+
if [ -f "$cfg" ] && grep -q '"apiKeyHelper"' "$cfg" 2>/dev/null; then
456+
if AWF_CFG="$cfg" AWF_NEW="$CHROOT_KEY_HELPER" \
457+
node -e "
458+
const fs = require('fs');
459+
const f = process.env.AWF_CFG;
460+
const obj = JSON.parse(fs.readFileSync(f, 'utf8'));
461+
obj.apiKeyHelper = process.env.AWF_NEW;
462+
fs.writeFileSync(f, JSON.stringify(obj) + '\n');
463+
" 2>/dev/null; then
464+
echo "[entrypoint] ✓ Updated apiKeyHelper path in $cfg"
465+
fi
466+
fi
467+
done
468+
CLAUDE_CODE_API_KEY_HELPER="$CHROOT_KEY_HELPER"
469+
else
470+
echo "[entrypoint][WARN] Could not copy get-claude-key.sh to chroot"
471+
echo "[entrypoint][WARN] Claude Code API key helper may not work in chroot mode"
472+
fi
473+
fi
474+
fi
475+
429476
# Verify capsh is available on the host (required for privilege drop)
430477
if ! chroot /host which capsh >/dev/null 2>&1; then
431478
echo "[entrypoint][ERROR] capsh not found on host system"

0 commit comments

Comments
 (0)