Skip to content

fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD)#4831

Merged
lpcox merged 7 commits into
mainfrom
copilot/fix-passwd-synthesis-issue
Jun 13, 2026
Merged

fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD)#4831
lpcox merged 7 commits into
mainfrom
copilot/fix-passwd-synthesis-issue

Conversation

Copilot AI commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

On ARC/DinD runners the Docker daemon's root filesystem is often read-only or tmpfs-backed, so entrypoint.sh's runtime identity synthesis silently failed when appending to /host/etc/passwd and /host/etc/group. This caused capsh to fall back to numeric UID/GID — breaking threat-detection and requiring consumers to pre-seed the daemon's /etc/passwd as a workaround.

Changes

containers/agent/entrypoint.sh

  • When appending to /host/etc/passwd (or /host/etc/group) fails (EROFS), falls back to:

    1. Copying the existing file to /tmp/awf-etc/
    2. Appending the synthesized entry to the writable copy
    3. mount --binding the copy over the read-only original

    CAP_SYS_ADMIN is still held at this point in the entrypoint (dropped by capsh just before user code runs), so the bind-mount succeeds. The mount is container-scoped and cleaned up on exit.

    # read-only fallback path (new)
    SYNTH_ETC_DIR="/tmp/awf-etc"
    mkdir -p "${SYNTH_ETC_DIR}"
    cp /host/etc/passwd "${SYNTH_ETC_DIR}/passwd"
    echo "${PASSWD_ENTRY}" >> "${SYNTH_ETC_DIR}/passwd"
    chmod 644 "${SYNTH_ETC_DIR}/passwd"
    mount --bind "${SYNTH_ETC_DIR}/passwd" /host/etc/passwd

docs/chroot-mode.md

  • Updated the DinD Identity Synthesis section to describe the bind-mount fallback and the capability dependency.

When entrypoint.sh cannot append to /host/etc/passwd or /host/etc/group
because the filesystem is read-only (ARC/DinD with tmpfs-backed daemon
root), copy the existing file to /tmp/awf-etc/ and bind-mount it over
the read-only original after appending the synthesized entry.

CAP_SYS_ADMIN is still held at entrypoint time (dropped by capsh before
user code runs), so mount --bind succeeds. This replaces the [WARN] +
continue path that caused downstream capsh identity resolution failures.

Also update docs/chroot-mode.md to describe the new bind-mount fallback.

Closes #4829
Copilot AI changed the title [WIP] Fix passwd synthesis hard-fail on read-only /host/etc fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD) Jun 12, 2026
Copilot finished work on behalf of lpcox June 12, 2026 20:03
Copilot AI requested a review from lpcox June 12, 2026 20:03
@lpcox lpcox marked this pull request as ready for review June 12, 2026 21:23
Copilot AI review requested due to automatic review settings June 12, 2026 21:23
@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Documentation Preview

Documentation build failed for this PR. View logs.

Built from commit c32bbe3

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 improves chroot-mode identity synthesis on ARC/DinD runners by adding a bind-mount fallback when /host/etc/passwd and /host/etc/group are read-only, preventing capsh from falling back to numeric UID/GID and breaking identity-dependent features.

Changes:

  • Add a read-only fallback path in containers/agent/entrypoint.sh that writes synthesized passwd/group entries to /tmp/awf-etc/ and bind-mounts them over /host/etc/*.
  • Update chroot-mode documentation to describe the new bind-mount fallback and its CAP_SYS_ADMIN dependency.
Show a summary per file
File Description
containers/agent/entrypoint.sh Adds bind-mount fallback for passwd/group synthesis when /host/etc is read-only in ARC/DinD.
docs/chroot-mode.md Documents the new runtime bind-mount fallback behavior and capability requirement.

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment thread containers/agent/entrypoint.sh
Comment thread containers/agent/entrypoint.sh
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Add npm overrides for esbuild (0.28.1) and vite (8.0.16) to fix:
- GHSA-gv7w-rqvm-qjhr: esbuild RCE via NPM_CONFIG_REGISTRY
- GHSA-g7r4-m6w7-qqqr: esbuild arbitrary file read on Windows
- GHSA-j687-52p2-xcff: Astro XSS in define:vars
- GHSA-xr5h-phrj-8vxv: Astro server island replay attack

Remaining 5 moderate vulns are in yaml (deep transitive via @astrojs/check)
with no fix available yet.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox

lpcox commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts in this pull request

…nthesis-issue

# Conflicts:
#	docs-site/package-lock.json
#	docs-site/package.json

Copilot AI commented Jun 13, 2026

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved. The only conflicted files were docs-site/package.json and docs-site/package-lock.json — the resolution combines main's additions (@astrojs/mdx, yaml override, esbuild as direct dep, astro-mermaid ^2.0.2) with the branch's vite: 8.0.16 override. docs-site/package-lock.json was regenerated clean (0 vulnerabilities). All 2545 unit tests pass.

@github-actions

Copy link
Copy Markdown
Contributor

🔬 Smoke Test: Copilot PAT Auth — PASS

Test Result
GitHub MCP connectivity
GitHub.com HTTP ✅ 200
File write/read

PR: fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD)
Author: @Copilot | Assignees: @lpcox, @Copilot
Auth mode: PAT (COPILOT_GITHUB_TOKEN)

Overall: PASS

🔑 PAT report filed by Smoke Copilot PAT

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results:

  • GitHub MCP Testing: ✅
  • GitHub.com Connectivity: ✅
  • File Write/Read Test: ✅
  • BYOK Inference Test: ✅
    Running in direct BYOK mode (COPILOT_PROVIDER_API_KEY + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw)
    Status: PASS
    @Copilot @lpcox

🔑 BYOK (AOAI api-key) report filed by Smoke Copilot BYOK AOAI (api-key)

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test: Copilot BYOK ✅ PASS

Test Result
MCP Connectivity
GitHub.com (HTTP 200)
File Write/Read
BYOK Inference

Mode: Direct BYOK (COPILOT_PROVIDER_API_KEY) via api-proxy → api.githubcopilot.com
Author: @Copilot | Assignees: @lpcox, @Copilot

🔑 BYOK report filed by Smoke Copilot BYOK

@github-actions

Copy link
Copy Markdown
Contributor

✅ feat(api-proxy): implement OTLP fan-out to multiple endpoints
✅ fix(docker-host): pass through loopback TCP DOCKER_HOST for ARC/DinD orchestration
✅ GitHub title check
✅ File write/read
✅ Build
PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • registry.npmjs.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "registry.npmjs.org"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🔥 Smoke Test Results

Test Result
GitHub MCP connectivity ✅ PASS
GitHub.com HTTP connectivity ❓ Pre-step data not injected (template vars unresolved)
File write/read ❓ Pre-step data not injected (template vars unresolved)

PR: fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD)
Author: @Copilot | Assignees: @lpcox, @Copilot

Overall: INCONCLUSIVE — MCP test passed; 2 pre-computed tests had unresolved ${{ steps.smoke-data.outputs.* }} template variables.

📰 BREAKING: Report filed by Smoke Copilot

@github-actions

Copy link
Copy Markdown
Contributor

Chroot Version Comparison Results

Runtime Host Version Chroot Version Match?
Python Python 3.12.13 Python 3.12.3
Node.js v24.16.0 v22.22.3
Go go1.22.12 go1.22.12

Overall: ❌ NOT all tests passed

Python and Node.js versions differ between host and chroot environments. Go matches.

Tested by Smoke Chroot

@github-actions

Copy link
Copy Markdown
Contributor

Smoke Test Results — FAIL

Check Result Detail
Redis PING Connection timed out (port 6379 blocked by AWF iptables)
PostgreSQL pg_isready no response (port 5432 blocked by AWF iptables)
PostgreSQL SELECT 1 Connection timed out

Overall: FAIL

The AWF firewall explicitly blocks database/Redis ports (5432, 6379) via iptables DROP rules in setup-iptables.sh. host.docker.internal resolves correctly to 172.17.0.1, but traffic is blocked before reaching the services.

🔌 Service connectivity validated by Smoke Services

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Build Test Suite Results

Ecosystem Project Build/Install Tests Status
Bun elysia 1/1 passed ✅ PASS
Bun hono 1/1 passed ✅ PASS
C++ fmt N/A ✅ PASS
C++ json N/A ✅ PASS
Deno oak N/A 1/1 passed ✅ PASS
Deno std N/A 1/1 passed ✅ PASS
.NET hello-world N/A ✅ PASS
.NET json-parse N/A ✅ PASS
Go color 1/1 passed ✅ PASS
Go env 1/1 passed ✅ PASS
Go uuid 1/1 passed ✅ PASS
Java gson 1/1 passed ✅ PASS
Java caffeine 1/1 passed ✅ PASS
Node.js clsx 1/1 passed ✅ PASS
Node.js execa 1/1 passed ✅ PASS
Node.js p-limit 1/1 passed ✅ PASS
Rust fd 1/1 passed ✅ PASS
Rust zoxide 1/1 passed ✅ PASS

Overall: 8/8 ecosystems passed — ✅ PASS

Version info
  • Bun: 1.3.14
  • Deno: 2.8.3
  • Go: 1.22.12

Generated by Build Test Suite for issue #4831 ·

@github-actions

Copy link
Copy Markdown
Contributor
  • fix(entrypoint): bind-mount passwd/group synthesis fallback for read-only /host/etc (ARC/DinD)

Tests: ✅ MCP ✅ GitHub.com ✅ File write/read ✅ BYOK inference

Running in direct BYOK mode (AWF_AUTH_TYPE=github-oidc + AWF_AUTH_AZURE_* + COPILOT_PROVIDER_BASE_URL) via api-proxy → Azure OpenAI (Foundry, o4-mini-aw) authenticated via Microsoft Entra

Overall: PASS

cc @Copilot @lpcox

🪪 BYOK (AOAI Entra) report filed by Smoke Copilot BYOK AOAI (Entra)

@lpcox lpcox merged commit 7e5cb62 into main Jun 13, 2026
79 of 82 checks passed
@lpcox lpcox deleted the copilot/fix-passwd-synthesis-issue branch June 13, 2026 01:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ARC/DinD] Passwd synthesis hard-fails on read-only /host/etc (v0.25.65+)

3 participants