SEP-2787 proposed-shape test vectors (v0)#2789
Conversation
Per the conformance-surface discussion in modelcontextprotocol#2787. Adds test-vectors/sep-2787/v0/ with 13 cases split into the two buckets the reviewer named in the thread. normative/ covers signed-envelope round-trips across HS256/ES256/RS256, the three args-commitment shapes (digest, ref, projection), tampering rejection on the planner_declared and issuer_asserted blocks, and IEEE-754 float rejection at the canonicalisation boundary. Nine cases, pass/fail against the SEP-2787 wire format today. verifier-policy/ covers TTL expiry past iat + exp + skew, unsupported-alg rejection (HS512), schema rejection of unknown args-commitment kinds, and HS256-against-ES256-verifier alg-mismatch. Four cases that become normative once the SEP names skew tolerance, alg whitelist, schema, and verifier alg-acceptance. _check_independent.py reads the fixtures from disk and walks the conformance dimensions with no reference to any implementation. Imports stdlib plus cryptography and rfc8785 only. Output is tagged NORMATIVE vs POLICY per bucket. Apache-2.0. Derived from tests/test_attestation_sep2787.py at commit 3d7af54 of vaaraio/vaara (branch feat/sep2787-reference-impl). SEP maintainers own the final normative artifact location.
|
This is useful as a fixture PR. One alignment point before these get treated as conformance vectors for #2787: As far as I can tell, these vectors target the proposed revised envelope shape: The SEP text in #2787 still defines the flatter v1 shape: top-level So I would mark this vector set as provisional until the SEP text lands the matching schema and canonicalization rules, or name it clearly as proposed-shape vectors rather than conformance for the current draft. Otherwise a second implementation could correctly implement the SEP text as written and fail these fixtures. |
|
Fair catch and accurate read. Renaming the set as proposed-shape rather than conformance for the current draft. README and PR body updated to call out the divergence between the SEP text as written (flat If useful, I can add a sibling |
Rename snake_case keys in proposed-shape envelope to camelCase, matching MCP convention adopted by soup-oss/modelcontextprotocol@48c739b1 in PR modelcontextprotocol#2787. issuer_asserted -> issuerAsserted planner_declared -> plannerDeclared payload_derived -> payloadDerived tool_calls -> toolCalls server_fingerprint -> serverFingerprint secret_version -> secretVersion exp_seconds -> expSeconds requested_capability -> requestedCapability projection_digest -> projectionDigest RFC 8785 JCS sorts keys alphabetically, so canonical bytes are recomputed across all 13 fixtures. HS256 and RS256 signatures regenerated deterministically. ES256 case is randomised; a fresh signature is stored. Independent walker passes 6/6 normative positive, 3/3 normative negative, 4/4 verifier-policy negative.
Walker: - drop the kind-discriminated args handler; ArgsRef and ArgsProjection self-discriminate by present fields - tampered-case logic checks that the recanonicalised present body fails signature verification (canonical_signing_input.bin remains the pre-tamper canonical that the signature was computed over) - case 10 uses wall clock for TTL evaluation; expected.json no longer carries verify_at_epoch - case 12 renamed to args-commitment-missing-discriminator; flag toolCalls whose args carries neither ref nor projection README: - drop the proposed-shape framing; SEP text adopted trust-surface enveloping - describe the v2 args union without the kind discriminator - spell out the canonical_signing_input.bin convention for tampered cases so independent implementers do not re-trip the same surprise MANIFEST: - refresh bucket list to match the v2 case directories - provenance points at vaaraio/vaara@5ea7cd3, tag sep2787-ref-v2, merged via vaaraio/vaara#151 Walker smoke test: 6/6 normative positive + 3/3 normative negative + 4/4 verifier-policy negative.
|
v0.40.0 shipped on vaaraio/vaara@1ac1d75; vaaraio/vaara#154 lands the streamable-HTTP proxy that emits the v2 envelope this PR targets. |
|
The v2 envelope changes are a clear improvement. Self-discriminating args without the kind enum is cleaner, and the One fixture-determinism point on case 10: I would keep an explicit Using wall clock in So the case can still be "TTL expired past skew," but the expiry decision should be driven by fixture data rather than |
Replace datetime.now() in the case-10 walker branch with an explicit verify_at_epoch field read from expected.json. A second implementation replaying the fixtures gets identical pass/fail regardless of when the walker runs, which is the determinism guarantee the vector set is supposed to provide. Per review feedback on modelcontextprotocol#2789.
|
Pushed 2147293: case 10's |
|
Vaara v0.42.0 ships the post-execution complement to these vectors: the execution receipt layer ( |
Status: proposed-shape, not conformance for current SEP-2787 draft.
These vectors target the revised envelope shape proposed in the four-proposal comment on #2787:
planner_declared/issuer_asserted/payload_derivedtrust-surface blocks, explicit args-commitment kinds (digest / ref / projection), JCS canonicalisation, IEEE-754 float rejection at the canonicalisation boundary.The SEP text in #2787 still describes a flatter v1 shape (top-level
iss/sub/intent,toolCalls[*].argsas a string, sorted-key no-whitespace canonicalisation, optionalack). A second implementer reading the SEP as-is would correctly implement v1 and fail these fixtures.Treat as provisional until the SEP text adopts matching schema and canonicalisation rules. Sibling
v1-currentvector set against the SEP text as written is on offer if useful.Adds
test-vectors/sep-2787/v0/per the conformance-surface discussion in #2787. Depends on #2787.The bundle splits into two directories per the reviewer's distinction in the thread.
normative/covers signed-envelope round-trips across HS256/ES256/RS256, the three args-commitment shapes (digest, ref, projection), tampering rejection on the planner_declared and issuer_asserted blocks, and IEEE-754 float rejection at the canonicalisation boundary. Nine cases. Pass/fail against the SEP-2787 wire format today.verifier-policy/covers TTL expiry past iat + exp + skew, unsupported-alg rejection (HS512), schema rejection of unknown args-commitment kinds, and HS256-against-ES256-verifier alg-mismatch. Four cases. Become normative once the SEP names skew tolerance, alg whitelist, schema, and verifier alg-acceptance._check_independent.pyreads the fixtures from disk and walks the conformance dimensions with no reference to any implementation. Imports stdlib pluscryptographyandrfc8785only. Output is tagged NORMATIVE vs POLICY per bucket. Local run reports 6/6 normative positive, 3/3 normative negative, 4/4 policy matching default policy.Provenance
Apache-2.0. Derived from
tests/test_attestation_sep2787.pyat vaaraio/vaara@3d7af54 (tagsep2787-ref-v0, merged via vaaraio/vaara#139). SEP maintainers own the final normative artifact location, including whether this lives here, at a sibling path, or in a separate repo.Acceptance gate
One independent implementation reads these fixtures and produces the same canonical bytes and signature verification results for every NORMATIVE case.