Repository navigation
Conversation
…penAgriNet/network-adapter#74] Adds networkofnetwork/: two OAN networks on one machine, federated. oanfed.py publish builds each network's Network Descriptor from its registry entry, signs it, and writes it with the JWKS that verifies it. nginx serves both as static files at the fixed paths /.well-known/openagrinet and /.well-known/jwks.json. Signature: Ed25519. Canonical form: RFC 8785 (JCS), covering every field except signature. Generated per-network material (keys, TLS, .env) stays out of git via networkofnetwork/.gitignore. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… descriptor [OpenAgriNet/network-adapter#74] - Governance key (keys/governance.key, mode 600) signs only the Network Descriptor. Operational keys come from the registry entry and are delegated by kid in the signed operationalKeys field; the JWKS publishes both. admit stores only delegated keys, so the governance key can never verify traffic. - canonical() is RFC 8785: UTF-16 key order; floats, unsafe integers and lone surrogates are refused. Signature algorithm Ed25519 (RFC 9864). - kid is the RFC 7638 thumbprint, so rotation needs no configuration. - Descriptor and JWKS validated against the contract before signing and on verify. publish refuses a non-increasing revision, a governance key that is also a traffic key, or a readable key file. It writes the JWKS before the descriptor, each atomically. - test_oanfed.py: 21 checks. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…/network-adapter#74] make e2e-descriptor publishes a new revision, fetches it over TLS through the front door as the peer would, tampers with the served files to confirm each forgery is refused, then restores what was served. Nothing is written to either registry.
…network-adapter#74] Adds an "Identity documents" folder: GET each network's /.well-known/openagrinet and /.well-known/jwks.json from its front door and check the Descriptor contract fields, the Ed25519 keys, and that the governance key is published but never delegated for traffic.
network.sh runs under set -e, so reading a missing .env exited make with no message. Check for the network's state first and name the fix.
Author
|
Closing; a new PR will follow. |
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.
Resolves OpenAgriNet/network-adapter#74 (parent OpenAgriNet/network-adapter#48).
What
networkofnetwork/stands up two OAN networks on one machine. For #74,make host-descriptor(bin/oanfed.py publish) builds each network's Network Descriptor from its registry entry, signs it, and writes it together with its JWKS. nginx serves both as static files at the fixed paths:GET https://{networkId}/.well-known/openagrinetGET https://{networkId}/.well-known/jwks.jsonThe open decision from #74
Ed25519. That is its fully-specified JOSE name (RFC 9864, which deprecatesEdDSA).signature. Keys are ordered by UTF-16 code units. Floats, integers above 2^53 and lone surrogates are refused, so every implementation rebuilds identical bytes.Keys (matches Trust and signatures / Trust and key lifecycle in the doc)
keys/governance.key, generated mode 600, never in the registrysignature.keyIdoperationalKeyskid= RFC 7638 thumbprint, so a rotated key gets a new kid without any configuration. The overlap comes from the registry entry, which already holds keys as a list withvalidUntil/status.admitstores only the delegated operational keys. The governance key can never pass a traffic check, and a key slipped into the JWKS without being delegated in the descriptor is ignored.Validation (before signing, and on verify)
The descriptor is checked against the contract table:
versionis1.0;networkIdis a lowercase DNS domain.name,operator.nameandstatus(Active/Suspended/Retired) are present;revisionis an integer ≥ 1.issuedAtis UTC and not in the future (5 min skew allowed);operatingProfileis non-empty.schemaPacksandservices.discoveryare https URLs;contactsandprojectionTtlare well-formed.The JWKS is checked too: no duplicate kids, Ed25519 keys are 32 bytes, and
alg/useare correct. The signer must not also be delegated for traffic, and every delegated kid must be published.publishrefuses to write when:It writes the JWKS before the descriptor, each atomically, so a peer never sees a descriptor whose key is not yet published.
Proof
python3 -m unittest networkofnetwork/bin/test_oanfed.py: 21 tests pass. They cover the JCS RFC 8785 vectors, tampering with every signed field, malformed signatures and JWKS, contract fields, revision rollback, key-file permissions, the key split, delegation-only admit, and revoked/expired/upcoming keys.publishagainst a live registry: the output verifies.Out of scope (sibling issues)
validUntil/status.Secrets
networks/(per-network keys, TLS,.env) is git-ignored..env.exampleholds only local demo defaults.