Kubernetes Security Context#
Overview#
The dify-helm chart applies Kubernetes security contexts at both the pod level (podSecurityContext) and the container level (containerSecurityContext) for each component. Configuration is entirely driven by values.yaml; all deployment templates conditionally render the security context only when the corresponding value is non-empty or has enabled: true.
Per-Component Defaults#
| Component | podSecurityContext | containerSecurityContext |
|---|---|---|
| api | fsGroup: 1001 | runAsUser: 1001 |
| worker | fsGroup: 1001 | runAsUser: 1001 |
| beat | fsGroup: 1001 | runAsUser: 1001 |
| proxy (nginx) | fsGroup: 101, fsGroupChangePolicy: "Always" | runAsUser: 101 |
| web | {} (no defaults) | {} (no defaults) |
| sandbox | {} (no defaults) | {} (no defaults) |
| ssrfProxy | {} (no defaults) | {} (no defaults) |
| pluginDaemon | {} (no defaults) | {} (no defaults) |
Sources:
Key observations:
api,worker, andbeatrun as UID/GID 1001 (standard non-root application user).proxyuses UID/GID 101, matching the default nginx user ID. ThefsGroupChangePolicy: "Always"forces recursive ownership change on mounted volumes .web,sandbox,ssrfProxy, andpluginDaemonship with empty objects β no security context is applied by default, and non-root/privilege configuration must be added explicitly by the operator.
Template Pattern#
Every deployment template follows the same conditional rendering pattern:
- Pod-level: the
securityContextblock is emitted only when.Values.<component>.podSecurityContextis non-empty (truthy). For components with anenabledkey, that key is stripped before rendering via Helm'somitfunction. See sandbox-deployment.yaml lines 61β64 for a representative example. - Container-level: same pattern β emitted only when
.Values.<component>.containerSecurityContextis non-empty. See sandbox-deployment.yaml lines 92β95.
This pattern is identical across all eight deployment templates (api, worker, beat, proxy, web, sandbox, ssrfProxy, pluginDaemon).
Configuring Non-Root Execution (sandbox and others)#
For components with no defaults (sandbox, web, ssrfProxy, pluginDaemon), operators must supply the security context explicitly. A typical non-root configuration in values.yaml would be:
sandbox:
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containerSecurityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
There are no chart-level guard rails for these components β if neither podSecurityContext nor containerSecurityContext is set, the pod inherits the container image's default (which may be root). See the sandbox values and sandbox deployment template for the exact conditionals.
Source References#
| File | Purpose |
|---|---|
charts/dify/values.yaml | All per-component security context defaults |
charts/dify/templates/sandbox-deployment.yaml | Example of conditional securityContext template pattern |