Skip to content

refactor: use DHI images for base docker image#2499

Open
wrycu wants to merge 21 commits intogetarcaneapp:mainfrom
wrycu:docker-hardened-image
Open

refactor: use DHI images for base docker image#2499
wrycu wants to merge 21 commits intogetarcaneapp:mainfrom
wrycu:docker-hardened-image

Conversation

@wrycu
Copy link
Copy Markdown

@wrycu wrycu commented May 3, 2026

Checklist

  • This PR is not opened from my fork’s main branch

What This PR Implements

Swaps the base image from Debian Trixie to the Docker Hardened Image of Debian Trixie.

#2494

Fixes:

Changes Made

  • Updates Dockerfile to use DHI

Testing Done

  • Development environment started: ./scripts/development/dev.sh start
  • Frontend verified at http://localhost:3000
  • Backend verified at http://localhost:3552
  • Manual testing completed (describe):
    • Build image, loaded, confirmed functionality by clicking around my docker containers, running scans, etc
  • No linting errors (e.g., just lint all)
  • Backend tests pass: just test backend

AI Tool Used (if applicable)

AI Tool: Notion AI
Assistance Level: Minor
What AI helped with: Queried about high-level approaches
I reviewed and edited all AI-generated output: Yes
I ran all required tests and manually verified changes: Yes

Additional Context

This additionally requires a new entry in docker compose and a new value in .env to share the Docker socket with the running user. It can be populated with echo "DOCKER_GID=$(stat -c '%g' /var/run/docker.sock)" >> .env and would be a group_add entry in the docker compose file. Other minor edits may be needed.

Disclaimer Greptiles Reviews use AI, make sure to check over its work.

To better help train Greptile on our codebase, if the comment is useful and valid Like the comment, if its not helpful or invalid Dislike

To have Greptile Re-Review the changes, mention greptileai.

Greptile Summary

This PR replaces the plain debian:trixie-slim base image with a Docker Hardened Image (DHI) variant for both the manager and agent containers. A new Dockerfile-dhi-base carefully assembles only the required runtime binaries and their shared libraries (via ldd) into the DHI base, avoiding bulk directory copies. The Go startup code gains ARCANE_DEFAULT_NONROOT support so the binary can automatically re-exec as UID 65532 without requiring operators to set PUID/PGID explicitly.

  • Dockerfile-dhi-base: New targeted build that installs packages into a Debian slim stage then copies only the needed binaries and their .so deps into the DHI base, preserving the hardened surface.
  • Manager Dockerfile: Sets ARCANE_DEFAULT_NONROOT=true so the application re-execs as 65532; uses USER 0:0 only for the mkdir/chown setup step, consistent with the re-exec pattern.
  • Agent Dockerfile: Switches to the same DHI base but is missing ARCANE_DEFAULT_NONROOT=true and the chown -R 65532:65532 step, leaving the agent running as root by default and creating an inconsistency with the manager image's hardening posture.

Confidence Score: 4/5

The manager image and Go-layer changes are solid, but the agent image ends up running as root by default because it lacks the env var that triggers the non-root re-exec.

The agent Dockerfile sets USER 0:0 for setup but never sets ARCANE_DEFAULT_NONROOT=true, so the binary's identity-switching logic stays disabled and the agent process remains root for its entire lifetime. The manager image correctly pairs USER 0:0 with ARCANE_DEFAULT_NONROOT=true. The inconsistency is a straightforward omission that leaves the agent without the hardening the PR intends to provide.

docker/Dockerfile-agent — missing ARCANE_DEFAULT_NONROOT=true and chown for /app/data.

Comments Outside Diff (1)

  1. docker/Dockerfile-agent, line 46-70 (link)

    P1 Agent runs as root by default — missing ARCANE_DEFAULT_NONROOT=true

    The manager Dockerfile sets ENV ARCANE_DEFAULT_NONROOT=true so that ApplyRequestedRuntimeIdentity automatically re-execs the binary as UID/GID 65532. The agent Dockerfile never sets this variable, so unless an operator manually passes PUID/PGID, the loadRuntimeIdentityRequestInternal function returns Enabled: false and the process continues as UID 0 — exactly the root context established by USER 0:0. Additionally, /app/data is created as root with no subsequent chown, so by default the agent image runs as root, defeating the hardening intent.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: docker/Dockerfile-agent
    Line: 46-70
    
    Comment:
    **Agent runs as root by default — missing `ARCANE_DEFAULT_NONROOT=true`**
    
    The manager `Dockerfile` sets `ENV ARCANE_DEFAULT_NONROOT=true` so that `ApplyRequestedRuntimeIdentity` automatically re-execs the binary as UID/GID 65532. The agent Dockerfile never sets this variable, so unless an operator manually passes `PUID`/`PGID`, the `loadRuntimeIdentityRequestInternal` function returns `Enabled: false` and the process continues as UID 0 — exactly the root context established by `USER 0:0`. Additionally, `/app/data` is created as root with no subsequent `chown`, so by default the agent image runs as root, defeating the hardening intent.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Codex

Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
docker/Dockerfile-agent:46-70
**Agent runs as root by default — missing `ARCANE_DEFAULT_NONROOT=true`**

The manager `Dockerfile` sets `ENV ARCANE_DEFAULT_NONROOT=true` so that `ApplyRequestedRuntimeIdentity` automatically re-execs the binary as UID/GID 65532. The agent Dockerfile never sets this variable, so unless an operator manually passes `PUID`/`PGID`, the `loadRuntimeIdentityRequestInternal` function returns `Enabled: false` and the process continues as UID 0 — exactly the root context established by `USER 0:0`. Additionally, `/app/data` is created as root with no subsequent `chown`, so by default the agent image runs as root, defeating the hardening intent.

Reviews (2): Last reviewed commit: "wut" | Re-trigger Greptile

@wrycu wrycu requested a review from a team May 3, 2026 18:54
Comment thread docker/Dockerfile Outdated
Comment thread docker/Dockerfile Outdated
Comment thread docker/Dockerfile Outdated
@wrycu wrycu removed their assignment May 3, 2026
Comment thread docker/Dockerfile Outdated
@kmendell kmendell changed the title Docker hardened image (DHI) refactor: use DHI images for base docker image May 4, 2026
@kmendell
Copy link
Copy Markdown
Member

kmendell commented May 4, 2026

I also tried this before, but due to dhi requireing credntials i chose against it. There is a distroless image you can pull for hardened images currently.

@wrycu
Copy link
Copy Markdown
Author

wrycu commented May 4, 2026

Oh, you're right. That kinda stinks.

You can drop creds in the CI workflow so it's only required for docker compose workflows.

Personally, I think the massive reduction in CVEs is worth the trade-off - especially since this is a control plane application.

@kmendell
Copy link
Copy Markdown
Member

kmendell commented May 4, 2026

Id rather just build a base image and then use that as the runtime, ill see what i can figure out, it may be a hot second as am busy , but heopfully this week.

@github-advanced-security

This comment was marked as off-topic.

@kmendell
Copy link
Copy Markdown
Member

kmendell commented May 5, 2026

I think i got it, but the other issue is dhi doesnt publish an armv7 manifest. So if we do this aracne wont support armv7 via container images anymore, unless i make it a static variant

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.

3 participants