Container sets its data directory's owner and mode itself #353

Merged
sneak merged 2 commits from issue-340-datadir-ownership into next 2026-09-29 13:05:17 +02:00
Collaborator

Closes #340.

The image no longer sets USER. Its new ENTRYPOINT, deploy/docker-entrypoint.sh, starts as root, creates DATA_DIR if missing, gives the directory and anything in it owned by another user to webhooker (UID 1000), sets the directory to 0750, and runs the command as webhooker through su-exec. An empty root-owned bind mount, or data left by another UID, now works as mounted; the app never runs as root and is still PID 1. CMD is still /app/webhooker, so the resetpw commands are unchanged. Started with --user, the script only runs the command. It is in /usr/local/bin, not /app, which belongs to webhooker.

README: the UID 1000 ownership block, the upaas pre-deploy commands and the restore ownership step are gone; the upaas volume bullet names only the path.

  • Judgement call: su-exec over setpriv: Alpine's small tool for this, needing only musl; busybox's setpriv cannot change user, and util-linux's adds libcap-ng.
  • Deviation: su-exec is pinned by version (0.2-r3), not by hash; ca-certificates beside it is unpinned.
  • Judgement call: each start reads every entry's owner but changes only entries owned by someone else.
  • docker exec and the health check now run as root, since the image sets no USER.
  • No automated test covers the script: the suite runs inside docker build, which cannot start a container.
  • A missing host directory under upaas is sneak/upaas#235.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/webhooker/issues/340. The image no longer sets `USER`. Its new `ENTRYPOINT`, `deploy/docker-entrypoint.sh`, starts as root, creates `DATA_DIR` if missing, gives the directory and anything in it owned by another user to `webhooker` (UID 1000), sets the directory to `0750`, and runs the command as `webhooker` through `su-exec`. An empty root-owned bind mount, or data left by another UID, now works as mounted; the app never runs as root and is still PID 1. `CMD` is still `/app/webhooker`, so the `resetpw` commands are unchanged. Started with `--user`, the script only runs the command. It is in `/usr/local/bin`, not `/app`, which belongs to `webhooker`. README: the UID 1000 ownership block, the upaas pre-deploy commands and the restore ownership step are gone; the upaas volume bullet names only the path. - Judgement call: `su-exec` over `setpriv`: Alpine's small tool for this, needing only musl; busybox's `setpriv` cannot change user, and util-linux's adds `libcap-ng`. - Deviation: `su-exec` is pinned by version (`0.2-r3`), not by hash; `ca-certificates` beside it is unpinned. - Judgement call: each start reads every entry's owner but changes only entries owned by someone else. - `docker exec` and the health check now run as root, since the image sets no `USER`. - No automated test covers the script: the suite runs inside `docker build`, which cannot start a container. - A missing host directory under upaas is https://git.eeqj.de/sneak/upaas/issues/235. Model: opus-5-5
clawbot added the needs-review label 2026-09-29 11:49:34 +02:00
clawbot self-assigned this 2026-09-29 11:49:34 +02:00
Author
Collaborator

README.md line 3035, security features list: the bullet says "only the ENTRYPOINT script that sets the data directory's owner runs as root". That is false: with no USER in the image, its health check runs as root every 30 seconds, and docker exec runs as root by default (the PR body says so itself). Acceptable: the bullet says the app runs as UID 1000 and names what else runs as root (the entrypoint script before the app starts, the health check, docker exec), or drops the "only" claim.

Judgement call: the version pin on su-exec (REPO_POLICIES.md asks for a hash pin, no exceptions) is disclosed in the PR body and follows the plan, so it is not raised as a finding here.

Model: opus-5-5

**`README.md` line 3035, security features list:** the bullet says "only the `ENTRYPOINT` script that sets the data directory's owner runs as root". That is false: with no `USER` in the image, its health check runs as root every 30 seconds, and `docker exec` runs as root by default (the PR body says so itself). Acceptable: the bullet says the app runs as UID 1000 and names what else runs as root (the entrypoint script before the app starts, the health check, `docker exec`), or drops the "only" claim. Judgement call: the version pin on `su-exec` (`REPO_POLICIES.md` asks for a hash pin, no exceptions) is disclosed in the PR body and follows the plan, so it is not raised as a finding here. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-09-29 12:25:17 +02:00
clawbot added 2 commits 2026-09-29 12:33:56 +02:00
The image now starts as root through deploy/docker-entrypoint.sh,
which creates DATA_DIR if it is missing, gives the directory and
anything in it owned by another user to webhooker, sets the directory
to 0750, and runs the command as webhooker with su-exec. An empty
root-owned bind mount, or data left by another uid, now works with no
step on the host. Started with --user, the script only runs the
command.

The README drops every instruction to create or chown the host
directory; the upaas volume bullet names only the path.

Model: opus-5-5
The security-features bullet said only the entrypoint script runs as
root. With no USER in the image, the health check and docker exec also
run as root; the bullet now names all three.

Model: opus-5-5
clawbot force-pushed issue-340-datadir-ownership from 5a3f84ff56 to 42b6916c02 2026-09-29 12:33:56 +02:00 Compare
Author
Collaborator

Rebased onto current next; the README security-features bullet now says the app runs as webhooker (UID 1000) and names what runs as root: the entrypoint script before the app starts, the health check, and docker exec without --user.

Model: opus-5-5

Rebased onto current `next`; the README security-features bullet now says the app runs as `webhooker` (UID 1000) and names what runs as root: the entrypoint script before the app starts, the health check, and `docker exec` without `--user`. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-09-29 12:34:03 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
sneak merged commit b79e4649a1 into next 2026-09-29 13:05:17 +02:00
sneak deleted branch issue-340-datadir-ownership 2026-09-29 13:05:17 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#353