You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Raised first on #134, which merged before anyone had a chance to look at it. Moving it here rather than leaving it on a closed PR, because it is not a defect in that document: spec/registry-anchor-v1.md §7 is what makes the package a reference implementation, and §5.2 explicitly hands signature verification to v0.2 §3.3, which the package implements.
Filed here because there is nowhere else public to file it. trace-verify's PyPI metadata points Bug Tracker at github.com/agentrust-io/trace-registry, which returns 404 to an anonymous reader.
What it does
trace_verify._signature.canonical_body_bytes builds the signature pre-image as:
spec/trace-v0.2.md §3.2.2 names that exact construction:
Implementations MUST use an RFC 8785-conformant library. Using json.dumps(sort_keys=True) (Python) or equivalent ad-hoc sorting is insufficient: it diverges from RFC 8785 for non-ASCII strings and for IEEE 754 number serialization.
agentrust_trace.sign_record signs the same object -- the claim with signature removed -- through rfc8785.dumps. Same scheme, different canonicalizer, so the two agree on ASCII and disagree everywhere else.
Reproduction
agentrust-trace 0.6.0 and trace-verify 0.2.0, both from PyPI. Escapes throughout, so nothing here depends on how a terminal renders it.
fromcryptography.hazmat.primitives.asymmetric.ed25519importEd25519PrivateKeyfromagentrust_trace.signimportsign_record, key_to_jwkimporttrace_verify._signatureastvskey=Ed25519PrivateKey.generate()
record= {
"eat_profile": "https://trace.agentrust-io.com/profiles/v0.2",
"sub": "spiffe://trust.example.org/agent/payments",
"policy_label": "Zahlungsverkehr f\u00fcr M\u00fcnchen", # escapes; any non-ASCII does it
}
signed=sign_record(record, key)
print(tvs.verify_claim_signature(signed, key_to_jwk(key))) # False
record contents agentrust-trace trace-verify
ASCII only valid valid
any string field containing U+00FC valid INVALID
any string field containing a CJK character valid INVALID
The CLI verifies signatures by default and exits 1 when the check fails, so an external verifier following §7, on a valid record carrying a German policy label or a non-Latin data class, is told the signature is invalid. verify_claim_against_registry's docstring describes it as "the fail-closed check used by the anchoring paths"; if that is accurate, such a record also cannot be anchored, but that path is not visible from outside.
Two readings
The public material does not distinguish them, so I am asking rather than asserting:
the registry deliberately signs over a different pre-image than v0.2 §3.2.2, in which case that belongs in spec/registry-anchor-v1.md §0 as a third row -- and it is the most consequential one, since §0 currently states that the signing layer is JCS; or
it is a defect in the package.
Either way I would not have §7 point an external verifier at it before that is settled, since §7 exists precisely so that people run it.
Severity, honestly
Nobody is hurt today. This is a Developer Preview, ADOPTERS.md lists one organisation, and a record containing a non-ASCII character may not exist in the wild yet. Nothing is failing right now.
What makes it worth fixing while it is cheap is the failure mode. A valid, correctly signed record is reported as having an invalid signature. For evidence whose whole purpose is that a third party can check it without trusting the operator, a false rejection is the worst direction to fail in, and the trigger is not exotic: one accented character in a policy label.
It is also the mistake spec/registry-anchor-v1.md §0 warns about, in the opposite direction. §0 says do not reuse the signing canonicalizer at the leaf. What is in the shipped code is the leaf canonicalizer reused at the signing layer. The warning is right and one-directional, and the missing direction is the one that has already happened.
Two smaller things in the same package
PyPI metadata points Homepage, Documentation and Bug Tracker at github.com/agentrust-io/trace-registry. All three return 404 to an anonymous reader, which is the audience spec/registry-anchor-v1.md exists to serve.
Raised first on #134, which merged before anyone had a chance to look at it. Moving it here rather than leaving it on a closed PR, because it is not a defect in that document:
spec/registry-anchor-v1.md§7 is what makes the package a reference implementation, and §5.2 explicitly hands signature verification to v0.2 §3.3, which the package implements.Filed here because there is nowhere else public to file it.
trace-verify's PyPI metadata points Bug Tracker atgithub.com/agentrust-io/trace-registry, which returns 404 to an anonymous reader.What it does
trace_verify._signature.canonical_body_bytesbuilds the signature pre-image as:spec/trace-v0.2.md§3.2.2 names that exact construction:agentrust_trace.sign_recordsigns the same object -- the claim withsignatureremoved -- throughrfc8785.dumps. Same scheme, different canonicalizer, so the two agree on ASCII and disagree everywhere else.Reproduction
agentrust-trace0.6.0 andtrace-verify0.2.0, both from PyPI. Escapes throughout, so nothing here depends on how a terminal renders it.The CLI verifies signatures by default and exits 1 when the check fails, so an external verifier following §7, on a valid record carrying a German policy label or a non-Latin data class, is told the signature is invalid.
verify_claim_against_registry's docstring describes it as "the fail-closed check used by the anchoring paths"; if that is accurate, such a record also cannot be anchored, but that path is not visible from outside.Two readings
The public material does not distinguish them, so I am asking rather than asserting:
spec/registry-anchor-v1.md§0 as a third row -- and it is the most consequential one, since §0 currently states that the signing layer is JCS; orEither way I would not have §7 point an external verifier at it before that is settled, since §7 exists precisely so that people run it.
Severity, honestly
Nobody is hurt today. This is a Developer Preview,
ADOPTERS.mdlists one organisation, and a record containing a non-ASCII character may not exist in the wild yet. Nothing is failing right now.What makes it worth fixing while it is cheap is the failure mode. A valid, correctly signed record is reported as having an invalid signature. For evidence whose whole purpose is that a third party can check it without trusting the operator, a false rejection is the worst direction to fail in, and the trigger is not exotic: one accented character in a policy label.
It is also the mistake
spec/registry-anchor-v1.md§0 warns about, in the opposite direction. §0 says do not reuse the signing canonicalizer at the leaf. What is in the shipped code is the leaf canonicalizer reused at the signing layer. The warning is right and one-directional, and the missing direction is the one that has already happened.Two smaller things in the same package
github.com/agentrust-io/trace-registry. All three return 404 to an anonymous reader, which is the audiencespec/registry-anchor-v1.mdexists to serve.trace_verify.__version__is 0.1.0, and--versionprints the latter. Same drift chore(release): 0.6.0, and stop __version__ drifting #131 fixed here.Happy to open a PR against whichever repository ends up owning the fix, if that is useful and if it becomes reachable.