Repository navigation
fix: an unreadable public value is refused, never answered from the secret namespace (r139) - #88
Merged
Conversation
…ecret namespace (r139) WorkspaceValue, ReadAuthority and Recheck read through workspaceValueLive. When the public read failed (a missing file carrier, a value delivered both inline and by file), workspaceValueLive discarded the error and returned whatever the secret namespace held under the same name. Review r139 probed this and got "secretvalue" back with a nil error. An authority read could pin, or a Recheck could pass, on a value from a delivery the host never made for that name. workspaceValueLive now goes through workspaceValueIfSetLive, which moves on to the secret namespace only when the public value is absent and returns any other failure. WorkspaceValue returns that failure as it is; ReadAuthority and Recheck wrap it under ErrAuthorityValueMissing / ErrAuthorityValueChanged with "cannot be read", so the refusal names the delivery's reason. The new test fails against the old code at the WorkspaceValue assertion. The listing doc comments now say what the code does: a live file carrier is listed by its path, so one naming an empty file is listed and then reads as absent. TestWorkspaceConfigurationKeysSeparatesAbsenceFromFailure covers that case and a value delivered both inline and by file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4 tasks done
This was referenced Oct 26, 2026
Merged
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #87, from review r139. m3 is a security fix; m1 brings doc comments and tests in line with the code.
m3: an unreadable public value is refused, never answered from the secret namespace.
WorkspaceValue,ReadAuthorityandRecheckall read throughworkspaceValueLive. When the public read failed, for example because a file carrier names a missing file or a value is delivered both inline and by file,workspaceValueLivethrew the error away and returned whatever the secret namespace held under the same name. r139 probed this: a missing public file carrier plusCODEFLY__WORKSPACE_SECRET_CONFIGURATION__PROBE_FB__BINDING=secretvaluemadeWorkspaceValue("probe-fb","BINDING")return"secretvalue"with a nil error. Through the same path,ReadAuthoritycould pin an authority value from a delivery the host never made for that name.Recheckcould also pass after the public delivery broke, as long as the secret namespace held the pinned value.workspaceValueLivenow goes throughworkspaceValueIfSetLive. That function moves on to the secret namespace only when the public value is absent, and returns every other failure. This is one lookup instead of two that disagreed.WorkspaceValuereturns the read failure as it is, pinned or not.ReadAuthoritywraps it asErrAuthorityValueMissing: <name> cannot be read: <cause>, andRecheckasErrAuthorityValueChanged: <name> cannot be read: <cause>. Both sentinel and cause stay reachable througherrors.Is, so every refusal names its reason. Absence keeps its existing messages.WorkspaceValueIfSetdoc no longer saysWorkspaceValuefolds an unreadable delivery into "not configured".m1: listing docs and tests. The
WorkspaceConfigurationKeysanddeliveredNamescomments now say that a live file carrier is listed by its path. A carrier naming an empty file is therefore listed, and then reads as absent. A missing file, or a value delivered both inline and by file, is listed and fails by name when read.TestWorkspaceConfigurationKeysSeparatesAbsenceFromFailuregains both cases.Fix or hack
Fix, at the owner. The bug was a second absent-or-failed classification in
workspaceValueLivethat disagreed with the oneworkspaceValueIfSetLivealready had. This PR deletes the second and reuses the first. It adds no new mechanism.Test plan
TestAnUnreadablePublicValueIsNeverAnsweredFromTheSecretNamespacereproduces r139's probe. It establishes the premise (the public read fails withErrFileCarrier, and the secret read returnssecretvalue). It then asserts thatWorkspaceValuefails withErrFileCarrier, that the result is not absence and does not contain the secret, thatReadAuthorityrefuses withErrAuthorityValueMissingplusErrFileCarrier, and thatRecheckon a pinned value whose public delivery broke refuses withErrAuthorityValueChangedplusErrFileCarriereven though the secret namespace holds the pinned value.for.goandauthority.goto main makes that test fail at theWorkspaceValueassertion, which gets a nil error../scripts/check-one-implementation.sh: ok (86 files)../scripts/security-posture.sh: SP-WC-01, SP-WC-05 ok.go test -race -count=1 ./...passes in the root and inworkcontext.workspaceValueLiveandRecheckare at 100%,ReadAuthority94.7%,WorkspaceValue91.7%.golangci-lint run ./...: 0 issues in both modules.go vetis clean.Behaviour change for callers
A caller of
WorkspaceValuewhose public delivery is broken now gets the read error instead of the secret namespace's value. That is the fix. In the repository, only the per-key accessors' own tests rely onWorkspaceValuereaching the secret namespace, and only when the public value is absent, which still works.release/0.4
#89 carries #87's two commits and this one onto
release/0.4(df5bd6a) withcherry-pick -x. All three apply with no conflicts.Not verified
🤖 Generated with Claude Code