flux build kustomization and flux diff kustomization call maskSopsData on every
resource in the built output before printing it. Before this work, maskSopsData only
handled Secret resources — it would replace encrypted values with **SOPS** or strip
the .sops metadata block.
For non-Secret resources that are encrypted with SOPS (e.g. a HelmRelease whose
spec.values block is encrypted), the .sops top-level metadata block was left in
place. This caused two problems:
- Schema violation at apply time: The
.sopsfield is not part of the HelmRelease CRD schema. Leaving it in the built output meansflux diff kustomization(which does a server-side apply dry-run) fails with a validation error. - Unnecessary exposure: SOPS metadata (key fingerprints, recipients, encrypted MAC) should not appear in CLI output.
A related gap: there was no unit test and no golden-file test covering the
--decryption-provider / --decryption-secret flags on create kustomization.
Added an else branch to maskSopsData that handles every resource whose Kind is
not Secret. When a SOPS .sops block with an encrypted MAC (mac: ENC[…]) is
detected, it is stripped via yaml.FieldClearer. The encrypted field values themselves
(e.g. ENC[AES256_GCM,…] ciphertext) are intentionally left intact — they are already
opaque ciphertext, not plaintext, so there is nothing to redact.
File: internal/build/build.go — maskSopsData function (lines ~745–758)
Added TestMaskSopsDataNonSecret with two table-driven cases:
HelmRelease with sops metadata— verifies that the.sopsblock is stripped and encrypted values are preserved.HelmRelease without sops metadata— verifies that a resource without SOPS metadata passes through unchanged.
Also fixed a pre-existing broken duplicate test loop that had been left behind by a prior partial edit.
File: internal/build/build_test.go
Added a cmdTestCase entry to TestCreateKustomization that exercises:
flux create kustomization mysql \
--source=GitRepository/apps \
--path=./apps \
--decryption-provider=sops \
--decryption-secret=sops-age \
--namespace=flux-system \
--interval=1m \
--export
And a corresponding golden file verifying the generated spec.decryption block. Added
--interval=1m explicitly to avoid the resetCmdArgs() Cobra flag-state pollution
where a prior test zeroes out the shared createArgs.interval.
Files:
cmd/flux/create_kustomization_test.gocmd/flux/testdata/create_kustomization/with-sops-decryption.yaml
Added two test cases to TestBuildLocalKustomization that run the full Builder.Build()
pipeline and verify SOPS metadata is stripped from the output:
build helmrelease with sops metadata— builds a Kustomization directory containing a HelmRelease with a.sopsblock; asserts the.sopsfield is absent and theENC[…]values are preserved.build configmap with sops metadata— same for a SOPS-encrypted ConfigMap, closing the ConfigMap test-coverage gap identified in the plan.
Files:
cmd/flux/build_kustomization_test.gocmd/flux/testdata/build-kustomization/sops-helmrelease/kustomization.yamlcmd/flux/testdata/build-kustomization/sops-helmrelease/helmrelease.yamlcmd/flux/testdata/build-kustomization/sops-helmrelease-result.yamlcmd/flux/testdata/build-kustomization/sops-configmap/kustomization.yamlcmd/flux/testdata/build-kustomization/sops-configmap/configmap.yamlcmd/flux/testdata/build-kustomization/sops-configmap-result.yaml
- Consider masking encrypted field values for non-Secret resources
Currently the
ENC[…]ciphertext values in a HelmRelease are left in the output. This is intentional (ciphertext ≠ plaintext), but some teams may prefer all SOPS material to be redacted. A future change could replaceENC[…]values with**SOPS**for non-Secret resources as well.
-
Update
flux build kustomizationcommand documentation / examples to mention that SOPS-encrypted HelmRelease resources are handled safely. -
Integration test (cloud e2e in
tests/integration/) that provisions a real cluster with a SOPS-encrypted HelmRelease and verifies thatflux build kustomizationandflux diff kustomizationboth succeed.