You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix a JSON-escaping gap in redaction, remove OCI dependency from a test
Found by an independent, adversarial pre-submission review agent with no
prior context of this branch's work - the highest-value kind of finding this
whole audit process was designed to surface.
The redaction gap
------------------
redactSensitiveValues does a literal strings.ReplaceAll of the raw configured
secret value against the already-JSON-marshaled manifest/resources text. Any
value containing a character JSON escapes - a double quote, a backslash, or a
control character such as a newline - never appears in that text as its raw
bytes, so the search matched nothing and the secret (readable, merely
re-escaped) shipped into state and plan output unredacted. Multi-line secrets
- the canonical case being a PEM private key or certificate - were affected on
every single apply, silently, independent of the map-orientation bug fixed in
the previous commit.
Reproduced directly before fixing: a value containing embedded newlines,
quotes and backslashes survived "redaction" fully readable in the manifest
attribute.
Fix: jsonEscapedForm returns what a value looks like once embedded in a JSON
string field - json.Marshal's own encoding, quotes stripped - and
redactSensitiveValues now searches for that instead of the raw value. For a
plain alphanumeric secret (everything the existing test suite already
covered) the escaped form is byte-identical to the raw value, so this is
purely additive. Verified the fix is real, not tautological, by reintroducing
the raw-value search and confirming all 7 new special-character test cases
fail against it before restoring the fix.
Confirmed every JSON-producing call site in this codebase (manifest,
resources, and this new lookup) uses plain json.Marshal, not a custom
HTML-safe-escaping-disabled encoder, so the escaping rules the lookup assumes
are exactly the rules the producers actually use - including Go's
HTML-escaping of <, >, & by default, which is otherwise easy to miss.
Also updated .changelog/1879.txt, which the review correctly flagged as
overclaiming ("Both are now fixed") before this commit closed the remaining
gap - it's accurate now.
The OCI-chart test dependency
-------------------------------
The same review flagged TestAccResourceRelease_manifestOCIChartUpgrade's
dependency on a third-party OCI registry (ghcr.io/berriai/litellm-helm) as
worth a second look. Investigating: this repo's own test-chart can't actually
exercise the ownership-metadata fix at all, because its _helpers.tpl already
sets app.kubernetes.io/managed-by itself - the dry-run and live sides agree
for a completely unrelated reason (both read the same chart template), so the
bug this fix addresses never has a chance to surface. That's exactly why the
real litellm-helm chart was needed in the first place: its ConfigMap has no
labels block of its own.
Added testdata/charts/bare-metadata, a two-file fixture chart whose ConfigMap
deliberately declares no labels, and a new fully-local, offline-safe
acceptance test using it. Confirmed non-tautological the same way: reverting
setDryRunOwnershipMetadata's label injection reproduces the exact original
"Provider produced inconsistent result after apply" failure against this
local chart; restoring it passes. The OCI-based test is kept alongside it
(still gated behind testing.Short(), so it never runs by default) for the
additional real-world-fidelity coverage a synthetic chart can't provide - not
a replacement, an addition.
Verification
------------
go build / vet / test -race clean, gofmt clean. All 23 acceptance tests from
this session's work pass together.
Claude-Session: https://claude.ai/code/session_01SNanSDUQNVBmGcTWZiQV1A
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
`resource/helm_release`: Fix `set_sensitive` values never actually being redacted from the `manifest` and `resources` attributes when `experiments.manifest` is enabled. `redactSensitiveValues` was handed a map keyed by attribute name with the real value discarded or replaced by a placeholder, so it searched the stored manifest for literal attribute names like `dbPassword` and never touched the actual secret text - which then flowed into Terraform state and plan output in the clear, on every apply, silently (no error, nothing visible without inspecting the state file directly). The `resources` attribute additionally had no redaction at all, independent of this bug. Both are now fixed: the real configured value is what gets searched for and hashed out, on both attributes, on every code path (read, and both create/update dry runs).
2
+
`resource/helm_release`: Fix `set_sensitive` values never actually being redacted from the `manifest` and `resources` attributes when `experiments.manifest` is enabled. `redactSensitiveValues` was handed a map keyed by attribute name with the real value discarded or replaced by a placeholder, so it searched the stored manifest for literal attribute names like `dbPassword` and never touched the actual secret text - which then flowed into Terraform state and plan output in the clear, on every apply, silently (no error, nothing visible without inspecting the state file directly). The `resources` attribute additionally had no redaction at all, independent of this bug. A separate gap in the same code path: the search compared the raw configured value against the already-JSON-encoded manifest text, so any value containing a character JSON escapes - a quote, a backslash, or a control character such as a newline, as in a multi-line PEM private key or certificate - was compared against the wrong bytes and left unredacted too. All three are now fixed: the real configured value, in the form it actually appears in the JSON text, is what gets searched for and hashed out, on both attributes, on every code path (read, and both create/update dry runs).
0 commit comments