Skip to content

fix: use Protocol Context encryption for all records so peers can decrypt (#87, #88)#89

Merged
LiranCohen merged 1 commit into
mainfrom
fix/anchor-context-encryption
Feb 26, 2026
Merged

fix: use Protocol Context encryption for all records so peers can decrypt (#87, #88)#89
LiranCohen merged 1 commit into
mainfrom
fix/anchor-context-encryption

Conversation

@LiranCohen

Copy link
Copy Markdown
Contributor

Summary

Two critical fixes that unblock the real-world two-machine E2E flow.

Problem

When tracing the exact user scenario (meshd up --create on Machine A, meshd up --anchor on Machine B), we discovered that no WireGuard tunnel can form because:

  1. The anchor encrypts its own records with Protocol Path encryption (derived from the anchor's root key). Peers only have the shared context key. They cannot decrypt the anchor's node, nodeInfo, or endpoint records, so they cannot discover the anchor's mesh IP or network endpoints.

  2. Undecryptable nodes pollute the network map. When a node record can't be decrypted, nodeRecordToNode produces a Node with no mesh IP, no addresses, and no endpoints. WireGuard gets a peer entry it can't route traffic to.

Fix

#87: Protocol Context encryption everywhere

Call site Before After
network create -> RegisterNode (anchor self) Protocol Path (anchor root key) Protocol Context
network create -> WriteNodeInfo (anchor self) Protocol Path Protocol Context
peer add -> RegisterNode (peer node) Protocol Path Protocol Context
meshd up (anchor) -> endpoint writes Protocol Path (useContextEncryption = false) Protocol Context (useContextEncryption = true)
meshd up (anchor) -> engine config UseContextEncryption: false UseContextEncryption: true

The anchor derives the context key from its root key via HKDF (this already works in EncryptionKeyManager.resolveContextPrivateKey). No new key delivery or storage needed.

#88: Skip ghost peers in network map

In buildMapResponse, peers with no valid mesh IP are now skipped. They remain in c.nodes for auto key delivery tracking but are not injected into the WireGuard network map.

Verification

  • go build ./... -- zero errors
  • go vet ./... -- zero warnings
  • go test ./... -count=1 -race -- all tests pass

Fixes #87
Fixes #88

…rypt (#87, #88)

The anchor was writing its own node, nodeInfo, and endpoint records with
Protocol Path encryption (derived from the anchor's root key). Peers only
have the shared context key and cannot decrypt Protocol Path records from
a different root key. This meant peers could not read the anchor's mesh
IP or endpoints, preventing WireGuard tunnels from forming.

Fix:
- network create: write anchor's node and nodeInfo with context encryption
- peer add: write peer's node record with context encryption
- meshd up (anchor): enable context encryption for endpoint writes
- meshd up (anchor): pass UseContextEncryption to engine config so
  STUN-discovered endpoint updates also use context encryption

Also skip undecryptable peers in buildMapResponse (#88). When a node
record cannot be decrypted, the resulting Node has no mesh IP and no
endpoints. These ghost peers pollute the WireGuard network map. Now they
are filtered out of the map while still being tracked in the nodes map
for auto key delivery purposes.

Fixes #87
Fixes #88
@LiranCohen LiranCohen merged commit 45e5245 into main Feb 26, 2026
2 checks passed
@LiranCohen LiranCohen deleted the fix/anchor-context-encryption branch February 26, 2026 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: skip undecryptable nodes in network map instead of injecting ghost peers fix: anchor must write own records with Protocol Context encryption

1 participant