fix: shared Claude OAuth credentials in containers — mount + flock to prevent token rotation race (#693)

- Make ~/.claude volume mount read-write (was :ro) so containers can
  write back refreshed OAuth tokens
- Wrap Claude CLI in flock(1) inside tmux sessions using
  ~/.claude/session.lock — prevents concurrent token refresh races
  across agents sharing the same credentials
- Add ANTHROPIC_API_KEY detection in entrypoint.sh: when set, skips
  OAuth entirely (no rotation issues, metered billing)
- Log active auth method (API key vs OAuth vs missing) at container
  startup for easier 401 debugging
- Document 'claude auth login' requirement in disinto init output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
openhands 2026-03-25 17:48:21 +00:00
parent cfdbaeeb5b
commit cf6400e8f3
3 changed files with 34 additions and 2 deletions

View file

@ -287,8 +287,20 @@ create_agent_session() {
if [ -n "${CLAUDE_MODEL:-}" ]; then
model_flag="--model ${CLAUDE_MODEL}"
fi
# Acquire a session-level mutex via flock to prevent concurrent Claude
# sessions from racing on OAuth token refresh (rotating the refresh token
# invalidates it for other sessions). The lock is held for the lifetime
# of the Claude process inside the tmux session.
# Use ~/.claude/session.lock so the lock is shared across containers when
# the host ~/.claude directory is bind-mounted.
local lock_dir="${HOME}/.claude"
mkdir -p "$lock_dir"
local claude_lock="${lock_dir}/session.lock"
local claude_cmd="flock -n ${claude_lock} claude --dangerously-skip-permissions ${model_flag}"
tmux new-session -d -s "$session" -c "$workdir" \
"claude --dangerously-skip-permissions ${model_flag}" 2>/dev/null
"$claude_cmd" 2>/dev/null
sleep 1
tmux has-session -t "$session" 2>/dev/null || return 1
agent_wait_for_claude_ready "$session" 120 || return 1