✦ Sample Prompt
Update all Dockerfiles to run as a non-root user. For each Dockerfile:

1. Add a non-root user creation step after all package installations:
   RUN addgroup --system --gid 1001 appgroup && \
       adduser --system --uid 1001 --ingroup appgroup appuser
2. Set appropriate file permissions for the application directory:
   RUN chown -R appuser:appgroup /app
3. Add USER appuser before the CMD or ENTRYPOINT instruction
4. If the Dockerfile uses a multi-stage build, only add the USER directive
   in the final stage (the build stage can remain root)
5. Do not modify the CMD, ENTRYPOINT, or any application logic

If the Dockerfile already has a USER directive set to a non-root user,
skip that file.

The Problem

Running containers as root is a well-known security anti-pattern, if a container is compromised, the attacker has root access to the container's filesystem and potentially the host. Most compliance frameworks (SOC 2, FedRAMP, PCI-DSS) require non-root containers. Kubernetes Pod Security Standards enforce this at the cluster level.

Yet many Dockerfiles were written without a `USER` directive because the default is root and it "just works." Adding a non-root user requires careful placement in the Dockerfile, after package installations and file permissions are set, but before the `CMD` or `ENTRYPOINT`. Get it wrong and the container can't start.

What Tidra Does

  1. Finds all Dockerfiles and checks whether they already run as a non-root user
  2. For Dockerfiles running as root, adds user creation, file ownership, and USER directives in the correct order
  3. Handles multi-stage builds by only modifying the final runtime stage
  4. Creates PRs with clear descriptions of the security improvement

Before & After

diff
Dockerfile
@@ -5,4 +5,9 @@
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist
+
+ RUN addgroup --system --gid 1001 appgroup && \
+ adduser --system --uid 1001 --ingroup appgroup appuser
+ RUN chown -R appuser:appgroup /app
+ USER appuser
+
CMD ["node", "dist/index.js"]

Customization Tips

  • UID/GID: Some organizations standardize on specific UID/GID values. Update 1001 in the prompt to match your policy.
  • Alpine images: Alpine uses addgroup -S and adduser -S instead of --system. The prompt handles both, but verify if your images are Alpine-based.
  • Volume mounts: If your containers write to mounted volumes, ensure the mount permissions align with the non-root user.

Ready to run this across your repos?

Connect your Git provider and Tidra opens pull requests in every repo that needs them.