Skip to content

chore: release v0.9.1#158

Merged
lroolle merged 4 commits intomainfrom
release/v0.9.0
Jan 9, 2026
Merged

chore: release v0.9.1#158
lroolle merged 4 commits intomainfrom
release/v0.9.0

Conversation

@lroolle
Copy link
Member

@lroolle lroolle commented Jan 9, 2026

Summary

  • Fix critical UID/GID permission denied on container startup
  • Update GitHub workflows for deva rebrand + rust profile
  • Add .deva.example config reference

Test Plan

  • Docker image builds triggered by v0.9.1 tag
  • Verify ghcr.io/thevibeworks/deva:v0.9.1 works
  • Verify ghcr.io/thevibeworks/deva:v0.9.1-rust works

Closes #157 follow-up


Generated with Claude Code

lroolle and others added 3 commits January 9, 2026 02:00
Replace broken selective find command with explicit directory whitelist
for container-managed directories. Fix execution order to run
setup_nonroot_user before ensure_agent_binaries.

- Fix regression from commit 5807889 causing "Permission denied" errors
- Whitelist approach: .npm-global, .local, .oh-my-zsh, .skills, .config, .cache, go
- Add comprehensive research doc on UID/GID handling patterns
- Add devlog documenting fix and industry validation
- release.yml: fix IMAGE_NAME ccyolo→deva, add rust profile build
- ci.yml: test deva.sh instead of deprecated claude.sh
- version-check.sh: check deva.sh version instead of claude.sh
- install.sh: update branding to deva Multi-Agent Environment
- Add .deva.example config reference file

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings January 9, 2026 10:08
@claude-yolo
Copy link
Contributor

claude-yolo bot commented Jan 9, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4e60f4067

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +107 to +108
build-args: |
BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Build rust image from a stale base tag

The rust image is always built from ghcr.io/thevibeworks/deva:latest, but in this workflow the base image is only tagged latest when is_default_branch is true and otherwise only gets the version tag. On tag-triggered releases, that means latest may still point at the previous release, so v0.9.1-rust can be built on an older base and miss the just-released fixes (e.g., entrypoint UID/GID changes). Consider using the tag-specific base (e.g., ${{ steps.meta.outputs.version }} or github.ref_name) or the digest from the base build so the rust image always matches the release tag.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR releases version 0.9.1 with a critical fix for Docker container UID/GID permission issues that prevented container startup, along with rebranding updates and GitHub workflow improvements.

  • Fixes critical permission denied errors caused by broken UID remapping in docker-entrypoint.sh
  • Updates GitHub workflows for deva rebrand and adds rust profile build support
  • Adds comprehensive documentation on UID/GID handling patterns and a reference configuration file

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
deva.sh Updates version from 0.9.0 to 0.9.1
CHANGELOG.md Documents all changes in this release including the critical UID/GID fix
docker-entrypoint.sh Implements whitelist approach for UID/GID remapping and fixes execution order
.github/workflows/release.yml Updates IMAGE_NAME to deva, adds rust profile build job, updates version update logic
.github/workflows/ci.yml Updates test commands to reference deva.sh instead of claude.sh
scripts/version-check.sh Updates all references from claude.sh to deva.sh for rebrand consistency
install.sh Updates branding text in header comment
docs/devlog/20260108-docker-uid-permission-fix.org New comprehensive devlog documenting the UID/GID fix investigation and implementation
docs/UID-GID-HANDLING-RESEARCH.md New research document covering industry patterns for UID/GID handling in containers
.deva.example New example configuration file demonstrating all supported directives

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

main() {
if [[ ! -f "claude.sh" ]] || [[ ! -f "CHANGELOG.md" ]]; then
if [[ ! -f "deva.sh" ]] || [[ ! -f "CHANGELOG.md" ]]; then
error "Must be run from claude-code-yolo root directory"
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message still references "claude-code-yolo" but should reference "deva" to be consistent with the rebrand. This affects the user experience when the script fails.

Suggested change
error "Must be run from claude-code-yolo root directory"
error "Must be run from deva root directory"

Copilot uses AI. Check for mistakes.
install.sh Outdated
YOLO_WRAPPER="claude-yolo"
DEVA_LAUNCHER="deva.sh"
DOCKER_IMAGE="ghcr.io/thevibeworks/deva:latest"
GITHUB_RAW="https://raw.githubusercontent.com/thevibeworks/claude-code-yolo/main"
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GitHub repository URL still references "claude-code-yolo" in the raw URL path. If the repository has been renamed to match the deva rebrand, this URL should be updated to reflect the new repository name. If the repository name hasn't changed, this is acceptable but may be confusing given the rebrand to "deva".

Suggested change
GITHUB_RAW="https://raw.githubusercontent.com/thevibeworks/claude-code-yolo/main"
GITHUB_RAW="https://raw.githubusercontent.com/thevibeworks/deva/main"

Copilot uses AI. Check for mistakes.
- version-check.sh: error message now says "deva" not "claude-code-yolo"
- install.sh: GITHUB_RAW URL points to renamed repo thevibeworks/deva
- release.yml: rust image uses version-specific base tag, not :latest

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude-yolo
Copy link
Contributor

claude-yolo bot commented Jan 9, 2026

Claude finished @lroolle's task in 1m 14s —— View job


Security Audit - PR #158 🔴 CRITICAL FINDINGS

Conducting paranoid security audit focusing on container boundaries, authentication flows, and privilege escalation vectors.

Security Audit Checklist

  • Analyze docker-entrypoint.sh UID/GID changes for privilege escalation
  • Review GitHub workflow changes for supply chain attacks
  • Examine authentication handling in deva.sh
  • Check container boundary enforcement
  • Validate shell injection protections
  • Assess configuration file security (.deva.example)
  • Review documentation for security implications
  • Identify blocking security issues
  • Document required tests before merge

🚨 BLOCKING SECURITY ISSUES

1. CRITICAL - Base Image Supply Chain Attack Vector

File: .github/workflows/release.yml:108

build-args: |
  BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}

Issue: Rust profile builds from ghcr.io/thevibeworks/deva:v0.9.1 but this tag hasn't been pushed yet. The workflow builds base first, but github.ref_name could reference stale/malicious tags.

Attack Vector:

  1. Attacker pushes malicious tag v0.9.1 before legitimate release
  2. Base image gets built with malicious content
  3. Rust profile inherits compromised base

Mitigation: Use specific digest from base build output instead of tag reference.

2. HIGH - Docker Socket Permission Escalation

File: docker-entrypoint.sh:248

chmod 666 /var/run/docker.sock 2>/dev/null || true

Issue: World-writable Docker socket = root access on host. Agent can:

  • Create privileged containers
  • Mount host filesystem (docker run -v /:/host)
  • Execute arbitrary commands as root via docker exec

Current State: Auto-mounted by default, disabled only with --no-docker flag.

3. MEDIUM - UID/GID Injection via Environment Variables

File: docker-entrypoint.sh:182-189

if [ "$DEVA_UID" = "0" ]; then
    echo "[entrypoint] WARNING: Host UID is 0. Using fallback 1000."
    DEVA_UID=1000
fi

Issue: Only blocks UID=0, allows other dangerous values:

  • DEVA_UID=-1 → Invalid UID causes usermod failures
  • DEVA_UID=999 → Could conflict with system users
  • DEVA_GID=0 (root group) → Blocked but late validation

4. MEDIUM - Whitelist chown Race Condition

File: docker-entrypoint.sh:223-231

for dir in .npm-global .local .oh-my-zsh .skills .config .cache go; do
    if [ -d "$DEVA_HOME/$dir" ] && [ ! -L "$DEVA_HOME/$dir" ]; then
        chown -R "$DEVA_UID:$DEVA_GID" "$DEVA_HOME/$dir" 2>/dev/null || true
    fi
done

Issue: Time-of-check vs time-of-use race. Attacker can:

  1. Create directory during check
  2. Replace with symlink to host path before chown
  3. Gain ownership of host files

🔶 HIGH-RISK FINDINGS

1. Configuration Injection Potential

File: .deva.example shows volume mounting capabilities:

VOLUME=$HOME/.ssh:/home/deva/.ssh:ro
VOLUME=$HOME/projects/shared:/home/deva/shared:ro

Risk: Users may inadvertently expose sensitive directories. Config parsing needs validation against dangerous paths (/etc, /proc, /sys).

2. Shell Injection in Version Detection

File: docker-entrypoint.sh:14

version=$($path --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)

Risk: If $path contains shell metacharacters, command injection possible. Low likelihood but worth sanitizing.


⚠️ REQUIRED SECURITY TESTS BEFORE MERGE

  1. Docker Socket Test: Verify --no-docker completely disables socket mounting
  2. UID/GID Validation: Test negative UIDs, extremely large values, non-numeric inputs
  3. Symlink Attack Test: Create symlink in whitelisted directory during chown operation
  4. Base Image Integrity: Verify rust profile builds use correct base image digest
  5. Container Escape Test: Verify no paths to escape container with default config

🔧 RECOMMENDED IMMEDIATE FIXES

  1. Fix Base Image Reference:

    # Use output from base build
    BASE_IMAGE: ${{ needs.build-and-push.outputs.digest }}
  2. Strengthen UID/GID Validation:

    # Validate numeric and reasonable range
    if ! [[ "$DEVA_UID" =~ ^[1-9][0-9]{2,4}$ ]]; then
        DEVA_UID=1000
    fi
  3. Atomic chown Operations:

    # Use temp directory + atomic move instead of in-place chown

This PR has CRITICAL security issues that must be addressed before merge. The Docker socket exposure and base image supply chain risks are unacceptable for production use.

@lroolle lroolle merged commit dc9d3a6 into main Jan 9, 2026
3 checks passed
@lroolle lroolle deleted the release/v0.9.0 branch January 9, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants