fix: use local dist key for bundle verification in config update polling - #152
Merged
encodeous merged 2 commits intoSep 5, 2026
Merged
Conversation
checkForConfigUpdates was reading n.CentralCfg.Dist.Key, which may be a zero-value placeholder (AAAAAAAAAAAAAAAAAAAAAA==). This happens because BundleConfig re-marshals the CentralCfg after unmarshalling the source central.yaml, serializing the zero-value DistributionCfg.Key field when it was not explicitly set. Using this zero-value key for bundle decryption always fails with chacha20poly1305: message authentication failed. Fix: prefer the local (node-level) dist key from node.yaml, falling back to the central key for backward compatibility, and returning an error if neither key is valid. Fixes #NNN
Owner
|
I think the real issue here is that we don't warn the user when the config's pubkey is not the same as the key used to seal the config. (this is not an error however, since we want the user to be able to rotate keys) I'm thinking of reworking the local dist config in the near future. It feels a little inconsistent to me. |
encodeous
force-pushed
the
fix/dist-key-zero-value-fallback
branch
from
September 5, 2026 13:49
9302d1c to
df81f2c
Compare
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.
Problem
When central distribution is configured via
central.yaml'sdist.repos(without an explicitdist.key), the daemon's config update polling fails repeatedly with:This affects any node whose daemon was freshly started with a central config that has
dist.repos. The WireGuard data plane comes up and nodes handshake correctly, but the daemon never applies new config revisions, making automatic distribution non-functional.Reproduction Steps
Create a
central.yamlwithdist.reposbut nodist.key:Seal with a dist key pair:
Start the daemon on a node with
node.yamlcontaining:Observe daemon logs — the initial OSS download succeeds (central.yaml is written), but every 10-second poll cycle logs:
The recovered
central.yamlon disk showsdist.key: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=(zero-value placeholder).Root Cause
The issue has two contributing factors:
1. BundleConfig serializes a zero-value Dist.Key
In
state/distribution.go:68,BundleConfigunmarshals the sourcecentral.yaml, updates the timestamp, and re-marshals:DistributionCfg.Keyhas typeNyPublicKey([32]byte). ItsMarshalText()always produces a non-empty base64 string (AAAAAAAAAAAAAAAAAAAAAA==for zero-value), so it cannot be omitted byyaml:",omitempty". Since the sourcecentral.yamltypically only containsdist.repos(the signing key is specified via CLI-k), the re-marshaled config embeds a zero-value key into the bundle.2. checkForConfigUpdates uses central config's key
In
core/nylon_distribution.go:67, the config update loop reads the key from the central config:This key was recovered from the bundle via
UnbundleConfig, which deserializes the YAML containingAAAAAAAAAAAAAAAAAAAAAA==back into 32 zero bytes. Using this zero-value key to decrypt the ChaCha20-Poly1305 sealed bundle always fails.The correct key is available from the node-level config (
n.LocalCfg.Dist.Key), which was used successfully for the initial OSS fetch inreadCentralConfig().Fix
In
checkForConfigUpdates, prefer the local (node-level) dist key fromnode.yaml, falling back to the central key for backward compatibility, and return an error if no valid key is available.This is safe because:
n.LocalCfgis always populated fromnode.yamlinNewNylondist.keyincentral.yamlTesting
go build ./...— compiles cleanlygo test ./...— all tests pass