[Security] Run SMB connector dev container as non-root where feasible #27

Closed
opened 2026-07-11 12:51:19 +02:00 by zemion · 3 comments
Owner

Semgrep flags the SMB connector development Dockerfile for missing USER. Because Samba may require privileged behavior or capabilities for port 445, this needs a deliberate container design rather than a blind USER line.

Classification: container hardening / design decision.

Report evidence:

  • govoplan-files/dev/connectors/smb/Dockerfile:10.
  • Rule: dockerfile.security.missing-user-entrypoint.

Suggested next steps:

  • Decide whether the dev connector should bind an unprivileged port or document required capabilities.
  • If possible, run Samba under a non-root user with explicit volume permissions/capabilities.
  • If not feasible, document why and add a narrow scanner exception for this dev-only connector.

Baseline report directory: audit-reports/govoplan-full-20260711-1238

<!-- codex-audit-full-2026-07-11:files-smb-container-user --> Semgrep flags the SMB connector development Dockerfile for missing `USER`. Because Samba may require privileged behavior or capabilities for port 445, this needs a deliberate container design rather than a blind `USER` line. Classification: **container hardening / design decision**. Report evidence: - `govoplan-files/dev/connectors/smb/Dockerfile:10`. - Rule: `dockerfile.security.missing-user-entrypoint`. Suggested next steps: - Decide whether the dev connector should bind an unprivileged port or document required capabilities. - If possible, run Samba under a non-root user with explicit volume permissions/capabilities. - If not feasible, document why and add a narrow scanner exception for this dev-only connector. Baseline report directory: `audit-reports/govoplan-full-20260711-1238`
zemion added the
type
debt
priority
p2
status
ready
module/files
codex/ready
labels 2026-07-11 12:51:19 +02:00
zemion added the
area/security
audit/quick-fix
source/security-audit
labels 2026-07-11 16:08:32 +02:00
Author
Owner

Codex State: note

Summary

  • Reviewed dev/connectors/smb/Dockerfile and entrypoint.sh.
  • I did not change it in this batch because the container currently creates Samba users/passdb state at startup and exposes SMB port 445; blindly switching to non-root risks breaking the connector testbed.

Next

  • Treat this as a small design task: either redesign the dev container to serve Samba on an unprivileged internal port with writable runtime paths, or document why this root-only dev fixture is accepted and suppress the Trivy rule narrowly.
## Codex State: note ### Summary - Reviewed `dev/connectors/smb/Dockerfile` and `entrypoint.sh`. - I did not change it in this batch because the container currently creates Samba users/passdb state at startup and exposes SMB port `445`; blindly switching to non-root risks breaking the connector testbed. ### Next - Treat this as a small design task: either redesign the dev container to serve Samba on an unprivileged internal port with writable runtime paths, or document why this root-only dev fixture is accepted and suppress the Trivy rule narrowly.
Author
Owner

Implemented a non-root SMB dev-container attempt locally and leaving this open until runtime validation is possible.

Changes made:

  • dev/connectors/smb/Dockerfile now creates and switches to non-root govoplan:govoplan UID/GID 1000.
  • Container listener moved from privileged 445 to unprivileged 1445; compose still exposes the documented host endpoint 127.0.0.1:1445.
  • Runtime UID/GID mutation was removed from compose/entrypoint.
  • SMB_SHARE_NAME, SMB_USER, and SMB_PORT are validated before writing smb.conf.
  • Samba runtime/state/cache/private directories are image-owned by the non-root user.
  • The entrypoint attempts authenticated passdb setup and falls back to guest access if Samba refuses non-root passdb creation.
  • README now tells developers to create data/smb before compose starts so the bind mount is writable by UID 1000.

Validation run here:

  • sh -n dev/connectors/smb/entrypoint.sh
  • git diff --check -- dev/connectors/README.md dev/connectors/docker-compose.yml dev/connectors/smb/Dockerfile dev/connectors/smb/entrypoint.sh

Blocked validation here: neither docker nor podman is available in the Codex shell. Suggested runtime validation:

cd /mnt/DATA/git/govoplan-files/dev/connectors
mkdir -p data/smb data/webdav
docker compose rm -sf smb
docker compose up -d --build smb
docker compose logs --no-color smb
/mnt/DATA/git/govoplan-core/.venv/bin/python smoke.py --require-smb
Implemented a non-root SMB dev-container attempt locally and leaving this open until runtime validation is possible. Changes made: - `dev/connectors/smb/Dockerfile` now creates and switches to non-root `govoplan:govoplan` UID/GID `1000`. - Container listener moved from privileged `445` to unprivileged `1445`; compose still exposes the documented host endpoint `127.0.0.1:1445`. - Runtime UID/GID mutation was removed from compose/entrypoint. - `SMB_SHARE_NAME`, `SMB_USER`, and `SMB_PORT` are validated before writing `smb.conf`. - Samba runtime/state/cache/private directories are image-owned by the non-root user. - The entrypoint attempts authenticated passdb setup and falls back to guest access if Samba refuses non-root passdb creation. - README now tells developers to create `data/smb` before compose starts so the bind mount is writable by UID `1000`. Validation run here: - `sh -n dev/connectors/smb/entrypoint.sh` - `git diff --check -- dev/connectors/README.md dev/connectors/docker-compose.yml dev/connectors/smb/Dockerfile dev/connectors/smb/entrypoint.sh` Blocked validation here: neither `docker` nor `podman` is available in the Codex shell. Suggested runtime validation: ```bash cd /mnt/DATA/git/govoplan-files/dev/connectors mkdir -p data/smb data/webdav docker compose rm -sf smb docker compose up -d --build smb docker compose logs --no-color smb /mnt/DATA/git/govoplan-core/.venv/bin/python smoke.py --require-smb ```
Author
Owner

Runtime validation passed after the non-root SMB image iteration.

Validated by user on the Docker host:

  • container starts as uid=1000(govoplan) gid=1000(govoplan)
  • Samba passdb contains govoplan:1000:Linux User
  • signed SMB client session can list \\127.0.0.1\files and \\127.0.0.1\files\GovOPlaN
  • connector smoke passes:
    • OK dev-webdav browse/import GovOPlaN/webdav-live.txt
    • OK dev-nextcloud browse/import GovOPlaN/nextcloud-live.txt
    • OK dev-smb browse/import GovOPlaN/smb-live.txt
    • OK connector dev stack smoke checks passed

Implementation notes:

  • image runs as non-root govoplan:govoplan
  • container listens on unprivileged 1445
  • Samba account is seeded at image build time
  • runtime config is authenticated-only; no guest fallback
  • SMB signing is explicitly mandatory

Closing pending push.

Runtime validation passed after the non-root SMB image iteration. Validated by user on the Docker host: - container starts as `uid=1000(govoplan) gid=1000(govoplan)` - Samba passdb contains `govoplan:1000:Linux User` - signed SMB client session can list `\\127.0.0.1\files` and `\\127.0.0.1\files\GovOPlaN` - connector smoke passes: - `OK dev-webdav browse/import GovOPlaN/webdav-live.txt` - `OK dev-nextcloud browse/import GovOPlaN/nextcloud-live.txt` - `OK dev-smb browse/import GovOPlaN/smb-live.txt` - `OK connector dev stack smoke checks passed` Implementation notes: - image runs as non-root `govoplan:govoplan` - container listens on unprivileged `1445` - Samba account is seeded at image build time - runtime config is authenticated-only; no guest fallback - SMB signing is explicitly mandatory Closing pending push.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: add-ideas/govoplan-files#27
No description provided.