What the chart enforces
Pod-level hardening is rendered into every workload the chart installs. The defaults come from the chart’s templates andvalues.yaml. Chart-managed selector labels and component labels are silently dropped from per-engine podLabels and similar user surfaces so user input cannot detach selectors. Security contexts can still be overridden through the documented value surfaces. Treat the table below as the install-time baseline, not as an immutable contract.
The engine pod additionally sets
fsGroup: 3473 (with fsGroupChangePolicy: OnRootMismatch) so the data PVC’s group ownership matches the engine UID.
Memlock-setup sidecar
WhenengineSpec.memlockSetup: true and podSecurityContext.runAsNonRoot: true, the chart injects a memlock-setup sidecar container that raises the engine pod’s memlock limit. The sidecar runs as UID 0 because it issues a prlimit(2) against the engine container. The pod enables shareProcessNamespace: true so the sidecar can see the engine’s PID. It drops all capabilities except SYS_RESOURCE. When your node hosts already provide a memlock limit of at least 8 GiB, disable it with memlockSetup: false and configure the nodes yourself. See Engine node requirements.
Install-time validation
The chart shipshelm/values.schema.json. helm install and helm upgrade reject wrong types and pattern violations on selected known fields, including postgresql.host, postgresql.database, postgresql.schema, customEngineConfig.instance.id, and the engine name. The schema is intentionally permissive, so unknown value paths are not rejected. This is install-time validation, not an admission webhook. It runs only when the chart is being applied, not on subsequent edits to the rendered objects.
What the chart does not enforce
Network isolation between pods
Thefirebolt-instance Helm chart emits no NetworkPolicy objects. All pod-to-pod and pod-to-external traffic is governed by whatever the cluster’s CNI and NetworkPolicy controller already enforce. In a default Kubernetes install with no NetworkPolicy controller, every pod can reach every other pod on every port.
This is a deliberate scoping decision. NetworkPolicy semantics depend on the CNI plugin (Calico, Cilium, Antrea, etc.), the cluster’s default-allow vs. default-deny posture, and the chart-vs-platform ownership boundary for security primitives. Encoding any of those assumptions into chart-emitted NetworkPolicy objects would either be a no-op with no controller installed or actively wrong for the deployment target.
Platform teams should apply NetworkPolicy objects covering at least the allowed flows below. Recommended selectors:
Allowed flows
Cross-engine traffic (replicas of different engines), gateway-to-metadata, and gateway-to-PostgreSQL are not required by any chart-emitted control flow and should be denied.
tls.gateway.enabled and tls.engine.enabled change what’s carried on the “External clients → Gateway” and “Gateway → Engine pods” flows above from plaintext HTTP to TLS; they don’t change which flows are required. See TLS.
Namespace-level resource ceilings
AResourceQuota capping the aggregate of requests.cpu, requests.memory, pod count, and PVC size across all engines in a namespace is a platform concern. The chart applies per-engine resources.requests and resources.limits from your values, but does not emit a ResourceQuota and does not validate the per-engine resources block against a Helm-side maximum. The per-namespace budget is a deployment-target decision (test cluster vs. multi-tenant production).
Image provenance and supply-chain attestation
The chart pulls whatever image you supply viaengineSpec.image.repository, metadata.image.repository, and the equivalent tag values. The chart does not validate signatures, attestations, or SBOMs. If image-policy enforcement is required, use a cluster-level admission controller such as Kyverno or Sigstore Policy Controller.
Admission-time enforcement
The chart has no controller and no admission webhook. Oncehelm install has rendered the manifests, subsequent edits to the resulting objects (engine StatefulSet pod template, metadata Deployment, gateway Deployment) are not reconciled back to the chart-rendered state. Platform teams that need drift correction should treat the firebolt-instance install as input to GitOps (Argo CD, Flux) and rely on the GitOps controller for drift.
The Firebolt Kubernetes Operator provides continuous reconciliation and admission-time validation natively. When drift correction or admission-time guardrails are a primary requirement, see the operator upgrade path.
Secrets handling
Bundled PostgreSQL
Whenpostgresql.credentials.existingSecret is empty, the chart generates a Secret named <release>-metadata-postgres-creds on first helm install:
- The Secret holds three base64-encoded keys:
username,password, anddatabase. - The password is sourced (in order): an explicit
postgresql.passwordvalue, the existing Secret’spasswordkey on ahelm upgrade, or a freshly generated 24-character alphanumeric value (randAlphaNum 24) on a clean install. - The chart never rotates the password.
- The Metadata Service Deployment loads the credentials by mounting the Secret at
postgresql.credentials.mountPath. - When
postgresql.local_enabled: true, the bundled PostgreSQL StatefulSet also reads this generated Secret.
postgresql.local_enabled: false with postgresql.credentials.existingSecret.
External PostgreSQL
For external databases, usepostgresql.credentials.existingSecret. See External PostgreSQL. Inline postgresql.password also works but leaks the password into helm get values.
External object storage
Object-storage credentials for engines are not represented as Helm values. The chart passescustomEngineConfig.storage into the engine config and relies on the engine pod’s workload identity for cloud credentials:
- AWS: IRSA or AWS Pod Identity.
- Azure: Microsoft Entra Workload ID.
- Google Cloud: Workload Identity Federation for GKE.
managed_table_storage: s3 with aws.endpoint), the engine authenticates with the AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY you inject via engineSpec.extraEnv (from a Secret in production); see S3-compatible storage.
TLS to PostgreSQL is not exposed
The chart does not currently exposesslmode or a CA-bundle mount for the Metadata Service’s PostgreSQL connection. Encrypt the PostgreSQL connection at the network layer (VPC peering, sidecar TLS proxy, or service-mesh mTLS) until the chart grows native support.
Authentication and TLS
auth.enabled, auth.signingKeys, and tls.{gateway,engine} are each provisioned by exactly one of an existing Secret you create yourself, or a chart-rendered cert-manager Certificate. The chart never generates or accepts a literal admin password. See Authentication and TLS for the full setup, including signing-key rotation and the cert-manager option.
When engine query-listener TLS is enabled (tls.engine.enabled), the gateway’s upstream connection and its active engine health check both switch to TLS along with it; kubelet’s own probes against the engine’s dedicated health port continue over plain HTTP.
See also
- Authentication: enabling engine authentication and JWT signing key rotation.
- TLS: enabling TLS on the gateway and engine listeners.
- Monitoring: metrics surface and Prometheus Operator integration.
- Operator upgrade path: when continuous admission, drift correction, and CR-status surfaces are required.
SECURITY.md: vulnerability reporting policy for this repository.