fix(trustedagents): add ed25519 signature verification for runtime-fetched allowlist (PILOT-135)#4
Merged
Conversation
…tched allowlist (PILOT-135) fetchOnce() at runtime.go:51-76 previously loaded the trusted-agents JSON from GitHub raw with HTTPS as the sole integrity check. A compromised host, BGP hijack, or forged TLS cert could inject malicious node IDs into the allowlist. This commit adds VerifyAndStripSig() which: - Accepts unsigned JSON when no signature field is present (backward compatible — existing unsigned lists still work, with a WARN log). - Verifies an ed25519 signature when the field IS present, rejecting the fetch on mismatch (fallback to embedded list). - Reports an error when a signature exists but embeddedPubKey is still the zero-value placeholder (not yet configured). The embedded public key is a 32-byte zero placeholder; the operator replaces it when signing infrastructure is deployed. Once the real key is embedded and the JSON is signed, verification becomes mandatory. Tests: - Backward compat: unsigned JSON still accepted - Bad signature: rejected - Signature present, key not configured: rejected - Valid signature: accepted (end-to-end with fresh keypair) Closes PILOT-135
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Collaborator
Author
🦜 Matthew PR Check — #4 PILOT-135Status
VerdictCLEAN — all CI green, no blockers, MERGEABLE. Adds ed25519 signature verification for runtime-fetched allowlist JSON with backward-compatible unsigned fallback. |
Collaborator
Author
🦜 Matthew Explains — #4 PILOT-135What this doesAdds How it works
Files
|
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.
What failed
fetchOnce()atruntime.go:51-76fetched the trusted-agents JSON from GitHub raw with HTTPS as the sole integrity check. A compromised host, BGP hijack, or forged TLS cert could inject malicious node IDs into the allowlist. The embedded list fallback only triggers on HTTP-level failure — a successful malicious fetch bypasses it.Why this fix
Adds
VerifyAndStripSig()which checks an optional ed25519"signature"field in the fetched JSON:The embedded public key is a 32-byte zero placeholder. Once the operator generates a key pair and adds signatures to the JSON, verification becomes mandatory.
Verification
go build ./...— cleango vet ./...— cleango test ./... -count=3— all 23 tests pass (consistent across 3 runs)Files changed
data.goruntime.gozz_fetch_test.goCloses PILOT-135