From 31346329e2a46a6dc6795cd534d6e468816333d1 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Mon, 23 Jun 2025 10:14:13 +0000 Subject: [PATCH 1/8] fix: handle UID 0 (root user) case in docker-entrypoint.sh - Detect when host user is root (CLAUDE_UID=0) - Use fallback UID 1000 to avoid conflict with existing root user - Also handle CLAUDE_GID=0 case with same fallback - Display clear warning messages about fallback behavior - Preserves security by still running as non-root in container - Fixes "usermod: UID '0' already exists" error Resolves #21 Co-authored-by: Eric Wang --- docker-entrypoint.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 582f7cf..2022435 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -59,6 +59,17 @@ setup_nonroot_user() { local current_uid=$(id -u "$CLAUDE_USER") local current_gid=$(id -g "$CLAUDE_USER") + # Handle UID=0 case (host user is root) + if [ "$CLAUDE_UID" = "0" ]; then + echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID 1000 for security." + echo "[entrypoint] Container runs as non-root claude user but files will be owned by root on host." + CLAUDE_UID=1000 + # Also use fallback GID if it was 0 + if [ "$CLAUDE_GID" = "0" ]; then + CLAUDE_GID=1000 + fi + fi + if [ "$CLAUDE_GID" != "$current_gid" ]; then [ "$VERBOSE" = "true" ] && echo "[entrypoint] updating $CLAUDE_USER GID: $current_gid -> $CLAUDE_GID" if getent group "$CLAUDE_GID" >/dev/null 2>&1; then From e9e14e0a358ca9f78062609c2a363cd04dc45890 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:34:00 -0700 Subject: [PATCH 2/8] fix: handle UID=0 and GID=0 independently for security MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Separate UID=0 and GID=0 checks to prevent security bypass - Fix case where host user has UID≠0 but GID=0 (would assign root group) - Remove inaccurate warning message about file ownership - Addresses Cursor BugBot security vulnerability report 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docker-entrypoint.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 2022435..3cd328e 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -62,12 +62,13 @@ setup_nonroot_user() { # Handle UID=0 case (host user is root) if [ "$CLAUDE_UID" = "0" ]; then echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID 1000 for security." - echo "[entrypoint] Container runs as non-root claude user but files will be owned by root on host." CLAUDE_UID=1000 - # Also use fallback GID if it was 0 - if [ "$CLAUDE_GID" = "0" ]; then - CLAUDE_GID=1000 - fi + fi + + # Handle GID=0 case (host user in root group) + if [ "$CLAUDE_GID" = "0" ]; then + echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID 1000 for security." + CLAUDE_GID=1000 fi if [ "$CLAUDE_GID" != "$current_gid" ]; then From 232b0ea1c8c4ed33f5bb4c9bbacb7cbd777f2795 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:38:06 -0700 Subject: [PATCH 3/8] fix: add explicit github_token to claude-code-review action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add github_token parameter to prevent OIDC token exchange errors - Fixes 401 Unauthorized - Invalid OIDC token error in claude-review CI - Action was trying to use GitHub App auth instead of direct token auth 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/workflows/claude-code-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml index 3b24156..88bd60f 100644 --- a/.github/workflows/claude-code-review.yml +++ b/.github/workflows/claude-code-review.yml @@ -38,6 +38,7 @@ jobs: uses: anthropics/claude-code-action@beta with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4) # model: "claude-opus-4-20250514" From 35db5ef3143f66af6e142e2b0888a68bd00ee387 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:40:02 -0700 Subject: [PATCH 4/8] docs: add OIDC token fix to dev log MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- DEV-LOGS.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/DEV-LOGS.md b/DEV-LOGS.md index e9ef513..25771e4 100644 --- a/DEV-LOGS.md +++ b/DEV-LOGS.md @@ -5,6 +5,20 @@ ## Issue Analysis: 2025-06-23 +### [bug-fixed] Claude Code Review OIDC token authentication error + +**Problem**: CI failing with "Invalid OIDC token" after changing permissions to write. + +**Solution**: Added explicit `github_token: ${{ secrets.GITHUB_TOKEN }}` to force direct token auth. + +**Cause**: Write permissions trigger GitHub App auth by default, but no App configured. + +**Status**: ✅ **COMPLETED** + +--- + +## Issue Analysis: 2025-06-23 + ### [enhancement-completed] Claude Code Review workflow simplification **Problem**: Overcomplicated workflow with manual duplicate detection using GitHub CLI. From c0e985f81f6a7609a8f20d2bb8a2ba53fbee4217 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:42:48 -0700 Subject: [PATCH 5/8] refactor: remove redundant comments in UID/GID handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove obvious comments that don't add value - Add missing dev log entry for root user handling fix 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- DEV-LOGS.md | 14 ++++++++++++++ docker-entrypoint.sh | 2 -- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/DEV-LOGS.md b/DEV-LOGS.md index 25771e4..43be890 100644 --- a/DEV-LOGS.md +++ b/DEV-LOGS.md @@ -5,6 +5,20 @@ ## Issue Analysis: 2025-06-23 +### [bug-fixed] Root user (UID 0) handling in docker-entrypoint.sh + +**Problem**: `sudo claude-yolo` fails with "usermod: UID '0' already exists" error. + +**Solution**: Detect UID=0 and GID=0 cases independently, use fallback UID/GID 1000. + +**Security Fix**: Prevent container user getting root group when host has GID=0 but UID≠0. + +**Status**: ✅ **COMPLETED** - PR #22 + +--- + +## Issue Analysis: 2025-06-23 + ### [bug-fixed] Claude Code Review OIDC token authentication error **Problem**: CI failing with "Invalid OIDC token" after changing permissions to write. diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 3cd328e..cb3c4d8 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -59,13 +59,11 @@ setup_nonroot_user() { local current_uid=$(id -u "$CLAUDE_USER") local current_gid=$(id -g "$CLAUDE_USER") - # Handle UID=0 case (host user is root) if [ "$CLAUDE_UID" = "0" ]; then echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID 1000 for security." CLAUDE_UID=1000 fi - # Handle GID=0 case (host user in root group) if [ "$CLAUDE_GID" = "0" ]; then echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID 1000 for security." CLAUDE_GID=1000 From 21a2739033e7539d41e6040ab2de3504e0224ae0 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:44:39 -0700 Subject: [PATCH 6/8] feat: dynamic fallback UID/GID selection for root users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace hardcoded 1000 fallback with dynamic search - Find first available UID/GID starting from 1000 - Prevents collision with existing container users/groups - More robust handling of edge cases 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docker-entrypoint.sh | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index cb3c4d8..edce355 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -60,13 +60,23 @@ setup_nonroot_user() { local current_gid=$(id -g "$CLAUDE_USER") if [ "$CLAUDE_UID" = "0" ]; then - echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID 1000 for security." - CLAUDE_UID=1000 + # Find first available UID starting from 1000 + fallback_uid=1000 + while getent passwd "$fallback_uid" >/dev/null 2>&1; do + fallback_uid=$((fallback_uid + 1)) + done + echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID $fallback_uid for security." + CLAUDE_UID=$fallback_uid fi if [ "$CLAUDE_GID" = "0" ]; then - echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID 1000 for security." - CLAUDE_GID=1000 + # Find first available GID starting from 1000 + fallback_gid=1000 + while getent group "$fallback_gid" >/dev/null 2>&1; do + fallback_gid=$((fallback_gid + 1)) + done + echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID $fallback_gid for security." + CLAUDE_GID=$fallback_gid fi if [ "$CLAUDE_GID" != "$current_gid" ]; then From 4dfc33dc7279d1b3538fac1aed5baba04fd433bf Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:46:50 -0700 Subject: [PATCH 7/8] simplify: revert to hardcoded 1000 fallback for root users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use UID/GID 1000 fallback for predictable file ownership - Existing usermod logic handles UID collision properly - Most host users are UID 1000, so this provides correct file ownership - Simpler than dynamic search while achieving the goal 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docker-entrypoint.sh | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index edce355..cb3c4d8 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -60,23 +60,13 @@ setup_nonroot_user() { local current_gid=$(id -g "$CLAUDE_USER") if [ "$CLAUDE_UID" = "0" ]; then - # Find first available UID starting from 1000 - fallback_uid=1000 - while getent passwd "$fallback_uid" >/dev/null 2>&1; do - fallback_uid=$((fallback_uid + 1)) - done - echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID $fallback_uid for security." - CLAUDE_UID=$fallback_uid + echo "[entrypoint] WARNING: Host user is root (UID=0). Using fallback UID 1000 for security." + CLAUDE_UID=1000 fi if [ "$CLAUDE_GID" = "0" ]; then - # Find first available GID starting from 1000 - fallback_gid=1000 - while getent group "$fallback_gid" >/dev/null 2>&1; do - fallback_gid=$((fallback_gid + 1)) - done - echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID $fallback_gid for security." - CLAUDE_GID=$fallback_gid + echo "[entrypoint] WARNING: Host user is in root group (GID=0). Using fallback GID 1000 for security." + CLAUDE_GID=1000 fi if [ "$CLAUDE_GID" != "$current_gid" ]; then From 088402fb118fcac1a0b6db41833f25b72376e758 Mon Sep 17 00:00:00 2001 From: Eric Wang Date: Mon, 23 Jun 2025 04:51:01 -0700 Subject: [PATCH 8/8] docs: clarify root cause and solution for UID 0 handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Explain why UID 0 can't be reassigned (root user exists) - Clarify security fix prevents root group assignment - Note that 1000 fallback provides proper file ownership 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- DEV-LOGS.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DEV-LOGS.md b/DEV-LOGS.md index 43be890..1efc724 100644 --- a/DEV-LOGS.md +++ b/DEV-LOGS.md @@ -9,9 +9,11 @@ **Problem**: `sudo claude-yolo` fails with "usermod: UID '0' already exists" error. -**Solution**: Detect UID=0 and GID=0 cases independently, use fallback UID/GID 1000. +**Root Cause**: Can't reassign existing UID 0 (root) to claude user. -**Security Fix**: Prevent container user getting root group when host has GID=0 but UID≠0. +**Security Fix**: Handle UID=0 and GID=0 independently to prevent root group assignment. + +**Solution**: Use fallback UID/GID 1000 for proper file ownership with existing collision handling. **Status**: ✅ **COMPLETED** - PR #22