Skip to content

feat: add PSA restricted compliance — securityContext, remove SYS_PTRACE#45

Open
will-corrigan wants to merge 8 commits into
hatchet-dev:mainfrom
will-corrigan:feat/psa-restricted-compliance
Open

feat: add PSA restricted compliance — securityContext, remove SYS_PTRACE#45
will-corrigan wants to merge 8 commits into
hatchet-dev:mainfrom
will-corrigan:feat/psa-restricted-compliance

Conversation

@will-corrigan
Copy link
Copy Markdown

@will-corrigan will-corrigan commented Mar 21, 2026

Description

Adds configurable pod-level and container-level securityContext to all Hatchet deployments and jobs, enabling Kubernetes Pod Security Standards restricted profile compliance. Removes hardcoded SYS_PTRACE capability from setup job containers.

All defaults are backward-compatible — existing deployments are unaffected. Security hardening is opt-in via values.

Type of change

  • New feature (non-breaking change which adds functionality)

What's Changed

Added

  • podSecurityContext and containerSecurityContext values for hatchet-api and hatchet-frontend charts
  • Applied to deployments (api, engine, frontend) and jobs (setup, migration, seed, worker-token)
  • shareProcessNamespace as a configurable value (default: true for backward compatibility)
  • Templates use toYaml pattern (matching cert-manager/Grafana convention) so users can pass any securityContext field
  • Changelog entries for hatchet-api and hatchet-frontend

Removed

  • Hardcoded SYS_PTRACE capability from all 4 setup job containers (not used by the codebase — no references in Go code or docker-compose)

Backward compatibility

  • podSecurityContext and containerSecurityContext default to {} (empty) — no security context is applied unless the user opts in
  • shareProcessNamespace defaults to true (matching existing behavior)
  • Old securityContext.enabled / securityContext.runAsUser / securityContext.fsGroup values still work
  • The only behavioral change is the removal of SYS_PTRACE, which was blocking pod creation on clusters with PSA baseline enforce

Opting into PSA restricted

Requires hatchet-dev/hatchet#3356 which creates a non-root user (UID 1000) in the Docker images. Once both are merged:

podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000
  seccompProfile:
    type: RuntimeDefault

containerSecurityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: false
  capabilities:
    drop:
      - ALL
  seccompProfile:
    type: RuntimeDefault

shareProcessNamespace: false

Testing

  • helm lint passes on all 4 charts
  • helm template renders correctly with default values (backward compatible) and restricted values
  • Verified rendered output matches main exactly with default values (minus SYS_PTRACE removal)
  • Checkov security scan passes on PSA-critical checks

… backward compat

- Add containerSecurityContext to hatchet-api deployment template
- Add podSecurityContext/containerSecurityContext defaults to hatchet-api values
- Preserve old securityContext.enabled conditional in both deployment templates
  so existing users with securityContext.enabled: true are not broken
- Mark old securityContext values as deprecated in favor of podSecurityContext
- Switch all templates from individual field references to toYaml pattern
  (matches cert-manager/Grafana convention, lets users add any field)
- Remove runAsUser: 0 and runAsNonRoot: false from podSecurityContext
  defaults — these explicitly set root. Default now only sets
  seccompProfile: RuntimeDefault
- Change seccompProfileType flat field to proper nested
  seccompProfile.type structure
- Preserve old securityContext.enabled conditional in deployment
  templates for backward compatibility
When quickstartJob.enabled=false, the setup job renders a fallback
"empty" alpine container. This container was missing the
containerSecurityContext block, causing PSA restricted violations.
Apply the same toYaml pattern used by all other containers.
Users upgrading should not have shareProcessNamespace silently change
from true to false. Keep the existing behavior as default, let users
opt into false for PSA restricted compliance.
The previous defaults (drop ALL capabilities, seccompProfile, etc.)
would be breaking changes for users upgrading from the current chart.
Default to empty ({}) which matches existing behavior, and document
the restricted profile values in comments for users who want to opt in.
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