Skip to content

fix: make Docker images backward compatible with runAsUser: 1000#8102

Merged
buger merged 1 commit intomasterfrom
fix/dockerfile-chown-compat-master
Apr 20, 2026
Merged

fix: make Docker images backward compatible with runAsUser: 1000#8102
buger merged 1 commit intomasterfrom
fix/dockerfile-chown-compat-master

Conversation

@buger
Copy link
Copy Markdown
Member

@buger buger commented Apr 20, 2026

Summary

  • Remove --chown=65532:65532 from non-FIPS Dockerfile builds to restore backward compatibility with helm charts using runAsUser: 1000
  • Files are made world-readable via chmod -R a+rX
  • FIPS/DHI builds still get proper 65532 ownership via NONROOT_CHOWN build arg

Test plan

  • Gateway starts with runAsUser: 1000 (old helm default)
  • Gateway starts with runAsUser: 65532
  • FIPS image still has proper nonroot ownership

🤖 Generated with Claude Code

- Remove --chown=65532:65532 from COPY for non-FIPS builds
- Add chmod -R a+rX so files are world-readable regardless of uid
- FIPS/DHI builds pass NONROOT_CHOWN=true for proper nonroot ownership

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@buger buger requested a review from a team as a code owner April 20, 2026 16:48
@github-actions
Copy link
Copy Markdown
Contributor

🚨 Jira Linter Failed

Commit: 270c3e2
Failed at: 2026-04-20 16:49:01 UTC

The Jira linter failed to validate your PR. Please check the error details below:

🔍 Click to view error details
failed to validate branch and PR title rules: branch name 'fix/dockerfile-chown-compat-master' must contain a valid Jira ticket ID (e.g., ABC-123)

Next Steps

  • Ensure your branch name contains a valid Jira ticket ID (e.g., ABC-123)
  • Verify your PR title matches the branch's Jira ticket ID
  • Check that the Jira ticket exists and is accessible

This comment will be automatically deleted once the linter passes.

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Apr 20, 2026

This PR adjusts the Docker image build process to restore backward compatibility for environments that use runAsUser: 1000, a common setting in older Helm chart deployments. The change makes file ownership conditional, addressing a regression caused by previously hardcoding the user to 65532.

Files Changed Analysis

  • ci/Dockerfile.distroless: The COPY instruction no longer hardcodes --chown=65532:65532. Instead, a new build argument NONROOT_CHOWN (defaulting to false) is introduced. The RUN command now makes gateway files world-readable (chmod -R a+rX) and only changes ownership to 65532:65532 if NONROOT_CHOWN is explicitly set to true.
  • .github/workflows/release.yml: The release workflow has been updated to pass NONROOT_CHOWN=true as a build argument for all FIPS and DHI image builds, ensuring these specific images retain the stricter file ownership while standard images become more flexible.

Architecture & Impact Assessment

What this PR accomplishes:
This PR fixes a runtime permission issue in Docker images that broke compatibility with Kubernetes deployments specifying runAsUser: 1000. It allows standard gateway images to run under different user IDs while maintaining stricter security for FIPS/DHI-compliant images.

Key technical changes introduced:

  1. Conditional File Ownership: The Dockerfile now uses a build argument (NONROOT_CHOWN) to conditionally apply chown to the /opt/tyk-gateway directory.
  2. Default World-Readable Permissions: For standard builds, files are made world-readable to allow execution by non-root users without matching file ownership.
  3. CI Workflow Specialization: The release workflow is modified to enable the strict chown behavior only for designated FIPS and DHI builds.

Affected system components:

  • The Docker image build process for the Tyk Gateway.
  • The GitHub Actions release workflow.
  • The runtime behavior of the final Docker container, specifically its compatibility with Kubernetes SecurityContext settings.

Build Logic Flow:

graph TD
    A[Start Docker Build] --> B{NONROOT_CHOWN == true?};
    B --|Yes (FIPS/DHI Build)|--> C[Set ownership to 65532:65532];
    B --|No (Standard Build)|--> D[Keep default ownership];
    C --> E[Make files world-readable];
    D --> E;
    E --> F[Final Image];
Loading

Scope Discovery & Context Expansion

The scope of this change is narrowly focused on the container image packaging and CI/CD process. It does not alter the gateway's application logic. The primary impact is external, affecting how operators deploy and manage the Tyk Gateway container in secured environments like Kubernetes. The changes directly address feedback from users of the Tyk Helm chart who experienced breaking changes after recent image updates. No further code exploration is necessary as the impact is confined to the build artifacts.

Metadata
  • Review Effort: 1 / 5
  • Primary Label: bug

Powered by Visor from Probelabs

Last updated: 2026-04-20T16:51:46.064Z | Triggered by: pr_opened | Commit: 270c3e2

💡 TIP: You can chat with Visor using /visor ask <your question>

@github-actions
Copy link
Copy Markdown
Contributor

API Changes

no api changes detected

@probelabs
Copy link
Copy Markdown
Contributor

probelabs bot commented Apr 20, 2026

Security Issues (1)

Severity Location Issue
🟡 Warning ci/Dockerfile.distroless:14-15
The Dockerfile now makes all files in `/opt/tyk-gateway/` world-readable (`a+rX`) for all build types, including FIPS. For FIPS builds, which are intended to be more secure and run with a known non-root user (65532), this is an unnecessary relaxation of file permissions. This change weakens the security posture of the FIPS image by violating the principle of least privilege, as the files remain readable by any user, even after ownership is correctly set.
💡 SuggestionThe permission-altering commands should be conditional. For FIPS builds (when `NONROOT_CHOWN` is true), only `chown` should be executed. For non-FIPS builds, `chmod` can be used to ensure compatibility with arbitrary user IDs. This prevents unnecessarily permissive files in security-hardened images.
🔧 Suggested Fix
RUN dpkg -i /${BUILD_PACKAGE_NAME}_*${TARGETARCH}.deb && rm /*.deb \
    && if [ "$NONROOT_CHOWN" = "true" ]; then \
         chown -R 65532:65532 /opt/tyk-gateway/; \
       else \
         chmod -R a+rX /opt/tyk-gateway/; \
       fi

Security Issues (1)

Severity Location Issue
🟡 Warning ci/Dockerfile.distroless:14-15
The Dockerfile now makes all files in `/opt/tyk-gateway/` world-readable (`a+rX`) for all build types, including FIPS. For FIPS builds, which are intended to be more secure and run with a known non-root user (65532), this is an unnecessary relaxation of file permissions. This change weakens the security posture of the FIPS image by violating the principle of least privilege, as the files remain readable by any user, even after ownership is correctly set.
💡 SuggestionThe permission-altering commands should be conditional. For FIPS builds (when `NONROOT_CHOWN` is true), only `chown` should be executed. For non-FIPS builds, `chmod` can be used to ensure compatibility with arbitrary user IDs. This prevents unnecessarily permissive files in security-hardened images.
🔧 Suggested Fix
RUN dpkg -i /${BUILD_PACKAGE_NAME}_*${TARGETARCH}.deb && rm /*.deb \
    && if [ "$NONROOT_CHOWN" = "true" ]; then \
         chown -R 65532:65532 /opt/tyk-gateway/; \
       else \
         chmod -R a+rX /opt/tyk-gateway/; \
       fi
\n\n ### Architecture Issues (1)
Severity Location Issue
🟠 Error ci/Dockerfile.distroless:13-16
The `chown` command executed in the first (`deb`) stage of this multi-stage build is ineffective. The `COPY --from=deb` instruction in the final stage does not preserve file ownership from the source stage; it creates the files as `root` (UID 0) by default. As a result, the `NONROOT_CHOWN` build argument and the conditional `chown` logic do not achieve the stated goal of setting file ownership to `65532:65532` in FIPS/DHI builds. The files in the final image will be owned by `root:root` in all cases. This makes the conditional logic dead code and the Dockerfile misleading.
💡 SuggestionThe `chmod -R a+rX` command correctly enables running the container with an arbitrary user ID. If `root` ownership in the final image is acceptable for all build variants, the simplest solution is to remove the conditional `chown` logic from the `RUN` command on line 16, and remove the `ARG NONROOT_CHOWN` declaration on line 13. Consequently, the `NONROOT_CHOWN` build arguments added in `.github/workflows/release.yml` should also be removed. If conditional ownership is a strict requirement, a different implementation strategy that correctly sets ownership in the final image is needed.

Performance Issues (1)

Severity Location Issue
🟡 Warning ci/Dockerfile.distroless:14-16
The `RUN` command now includes `chmod -R` and a conditional `chown -R` on `/opt/tyk-gateway/`. These recursive file system operations can be slow if the directory contains a large number of files, potentially increasing the Docker image build time. For FIPS builds, this change results in two separate recursive traversals of the directory, which is inefficient compared to a single operation.
💡 SuggestionTo optimize build time, consider setting the required file permissions and ownership within the `.deb` package itself. This would avoid running `chmod -R` and `chown -R` during every image build, moving the overhead to the packaging stage which is typically run less frequently.

Powered by Visor from Probelabs

Last updated: 2026-04-20T16:51:01.317Z | Triggered by: pr_opened | Commit: 270c3e2

💡 TIP: You can chat with Visor using /visor ask <your question>

@buger buger merged commit 9c1789c into master Apr 20, 2026
38 of 53 checks passed
@buger buger deleted the fix/dockerfile-chown-compat-master branch April 20, 2026 17:16
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.

1 participant