Skip to content

Fixes #420: Harden Helm chart security defaults - #434

Open
rohanmalhotracodes wants to merge 2 commits into
truefoundry:mainfrom
rohanmalhotracodes:helm
Open

Fixes #420: Harden Helm chart security defaults#434
rohanmalhotracodes wants to merge 2 commits into
truefoundry:mainfrom
rohanmalhotracodes:helm

Conversation

@rohanmalhotracodes

@rohanmalhotracodes rohanmalhotracodes commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Hardens the TrueForge Helm deployment so the server container no longer runs as root by default. The chart now renders restricted pod/container security contexts and mounts /tmp as writable storage so readOnlyRootFilesystem: true works.

Closes #420

Changes

  • Added non-root runtime user 10001:10001 in Dockerfile and Dockerfile.dev
  • Added secure default podSecurityContext and container securityContext
  • Added default /tmp emptyDir volume mount for writable temp storage
  • Added chart render coverage for the Deployment security context
  • Added Helm chart CI checks for chart changes
  • Updated chart README with the new security defaults

How was this tested?

  • pnpm build
  • pnpm test
  • pnpm typecheck
  • pnpm lint:ci
  • pnpm chart:deps
  • pnpm chart:lint
  • pnpm chart:template
  • pnpm test:chart-security

Before
main-before

After
helm-after

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
Changes default pod security posture and container user for all Helm/Docker deploys; misconfiguration could break workloads that assumed root or a writable root FS, though /tmp is explicitly provided.

Overview
Hardens Kubernetes deployments by default: the Helm chart now ships restricted pod and container security contexts (non-root UID/GID 10001, dropped capabilities, read-only root filesystem) and always mounts a writable /tmp emptyDir so the server can run under those constraints.

Production and dev Docker images match that runtime: they set HOME=/tmp, create user 10001:10001, and run the Node process as that user instead of root.

CI gains path-gated chart-checks (Helm deps + lint when chart/Dockerfile paths change) and folds the result into the aggregate check job. Chart README documents the new defaults and the /tmp mount.

Reviewed by Cursor Bugbot for commit 4663963. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4663963

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chiragjn chiragjn self-assigned this Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't need to test this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the custom chart security-context test and wiring.

{{- with .Values.extraVolumes }}
volumes:
- name: tmp
emptyDir: {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

  1. let's have default values for in resources in values.yaml
resources:
  requests:
    cpu: 100m
    memory: 256Mi
    ephemeral-storage: 256Mi
  limits:
    cpu: 200m
    memory: 512Mi
    ephemeral-storage: 512Mi

and let's make this empty dir size equal to resources.limits.ephemeral-storage if it is not undefined

Comment thread Dockerfile
STANDALONE=false \
HOST=0.0.0.0
HOST=0.0.0.0 \
HOME=/tmp

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

ideally I don't want to change HOME,
rather the code should take care to always use platform specific tmp dir to write to

Let's look at all code and see if something is writing outside of /tmp

Comment thread Dockerfile
&& npm cache clean --force

RUN groupadd --gid 10001 trueforge \
&& useradd --uid 10001 --gid trueforge --home-dir /tmp --no-create-home --shell /usr/sbin/nologin trueforge

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

related to above comment

Suggested change
&& useradd --uid 10001 --gid trueforge --home-dir /tmp --no-create-home --shell /usr/sbin/nologin trueforge
&& useradd --uid 10001 --gid trueforge

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.

Helm chart ships no default securityContext — server container runs as root with full capabilities

2 participants