Skip to content

security: add non-root users to token-spy and dashboard containers#431

Open
reo0603 wants to merge 1 commit intoLight-Heart-Labs:mainfrom
reo0603:security/container-non-root-users
Open

security: add non-root users to token-spy and dashboard containers#431
reo0603 wants to merge 1 commit intoLight-Heart-Labs:mainfrom
reo0603:security/container-non-root-users

Conversation

@reo0603
Copy link
Contributor

@reo0603 reo0603 commented Mar 19, 2026

Summary

Adds non-root user (UID 1000) to token-spy and dashboard Dockerfiles to follow container security best practices. Containers should not run as root to minimize attack surface.

Changes

token-spy

  • Add dreamer system user (UID 1000)
  • Set ownership of /app directory
  • Switch to non-root user before CMD

dashboard

  • Add dreamer user and group (UID/GID 1000)
  • Configure nginx for non-root operation:
    • Set ownership of nginx directories (html, cache, logs, conf.d)
    • Create and own nginx.pid file
    • Remove user directive from nginx.conf (runs as current user)
  • Switch to non-root user before ENTRYPOINT

Security Impact

Both containers now run as UID 1000 (dreamer) instead of root, reducing the attack surface if a container is compromised.

Testing

  • Dockerfiles build successfully
  • No functional changes to application logic
  • Follows Alpine Linux conventions (adduser/addgroup)

Related

Copy link
Collaborator

@Lightheartdevs Lightheartdevs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: Needs Work (same issue as prior review)

The core Dockerfile changes are correct, but the upgrade-breaking permission bug we flagged previously is still present and unaddressed.

The problem

token-spy/compose.yaml mounts ./data/token-spy:/app/data as a bind mount. On existing installs, this host directory is owned by root:root (created by Docker running as root). The Dockerfile's chown -R dreamer:nogroup /app only affects the image layer — bind mounts override it. When the container starts as dreamer (UID 1000), it gets permission denied writing to /app/data.

This will break every existing token-spy install on upgrade with no clear error message.

How to fix

Add an entrypoint wrapper that checks/fixes ownership before dropping privileges:

COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
#!/bin/sh
# Fix ownership of bind-mounted data directory
if [ "$(stat -c '%u' /app/data 2>/dev/null)" != "$(id -u)" ]; then
    chown -R dreamer:nogroup /app/data 2>/dev/null || true
fi
exec "$@"

Or at minimum, document the migration step: sudo chown -R 1000:1000 ./data/token-spy

What's good

  • Dashboard Dockerfile changes are thorough (nginx dirs, pid file, conf fixup)
  • UID 1000 is a reasonable choice

Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants