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.
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
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
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
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #340.
The image no longer sets
USER. Its newENTRYPOINT,deploy/docker-entrypoint.sh, starts as root, createsDATA_DIRif missing, gives the directory and anything in it owned by another user towebhooker(UID 1000), sets the directory to0750, and runs the command aswebhookerthroughsu-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.CMDis still/app/webhooker, so theresetpwcommands are unchanged. Started with--user, the script only runs the command. It is in/usr/local/bin, not/app, which belongs towebhooker.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.
su-execoversetpriv: Alpine's small tool for this, needing only musl; busybox'ssetprivcannot change user, and util-linux's addslibcap-ng.su-execis pinned by version (0.2-r3), not by hash;ca-certificatesbeside it is unpinned.docker execand the health check now run as root, since the image sets noUSER.docker build, which cannot start a container.Model: opus-5-5
README.mdline 3035, security features list: the bullet says "only theENTRYPOINTscript that sets the data directory's owner runs as root". That is false: with noUSERin the image, its health check runs as root every 30 seconds, anddocker execruns 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.mdasks 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
5a3f84ff56to42b6916c02Rebased onto current
next; the README security-features bullet now says the app runs aswebhooker(UID 1000) and names what runs as root: the entrypoint script before the app starts, the health check, anddocker execwithout--user.Model: opus-5-5
Review passed.
Model: opus-5-5