Skip to content

feat(attestation): add SEP-2787 reference implementation (proposed shape)#139

Merged
vaaraio merged 3 commits into
mainfrom
feat/sep2787-reference-impl
May 26, 2026
Merged

feat(attestation): add SEP-2787 reference implementation (proposed shape)#139
vaaraio merged 3 commits into
mainfrom
feat/sep2787-reference-impl

Conversation

@vaaraio
Copy link
Copy Markdown
Owner

@vaaraio vaaraio commented May 26, 2026

Summary

Adds vaara.attestation.sep2787: reference implementation of the SEP-2787 Tool Call Attestation envelope (modelcontextprotocol/modelcontextprotocol#2787), proposed shape. The module implements the four schema changes Vaara raised in the v1 draft thread:

  • Fact-source labels. Envelope fields are grouped under three trust-surface blocks: planner_declared (intent, tool name and server bindings the agent planner claims), issuer_asserted (iss, sub, iat, exp, nonce, secret_version, alg, set by the attestation issuer at signing time), and payload_derived (args_digest / args_ref / args_projection, deterministically derived from the request payload). The signature is the binding output and lives at the envelope root.
  • Three-way args shape. Replaces the v1 draft's overloaded args: string (inline JSON + magic "resource: " prefix) with an explicit tagged union: ArgsDigest (commitment only, payload stays local), ArgsRef (URL plus digest), ArgsProjection (redacted projection plus its own digest).
  • RFC 8785 (JCS) canonicalization. Replaces the v1 "sorted keys, no whitespace" rule with a normative reference to RFC 8785, plus IEEE-754 float rejection at the boundary (matching the OVERT Protocol Profile 1.0 numeric discipline).
  • Scope: request attestation only. The v1 optional ack field crosses the pre-execution / post-execution boundary and is removed here. Execution receipts belong in a separate extension composed on top.

Supports HS256, ES256, RS256 signing per the v1 draft. Coexists with the existing OVERT 1.0 implementation in vaara.attestation.overt. See docs/sep2787-overt-mapping.md for the field-level mapping between the two envelopes.

Scope boundaries and extension points

Two concerns from the v1 thread are intentionally out of scope for this reference implementation and belong in follow-up extensions composed on top:

  • Multi-server tool_calls partial-execution semantics. The shared issuer_asserted.nonce covers the whole envelope as a signed pre-execution plan. Per-server execution outcomes (which legs ran, which short-circuited, which got a reject from the server verifier) are the domain of the post-execution receipt extension, not the request attestation.
  • Additional trust surfaces. The v1 thread named six potential fact sources (planner, issuer, MCP server verifier, tool/application result, policy engine, payload-derived). The three blocks shipped here cover the surfaces present at issuance time. Server-verifier-asserted, tool-result-asserted, and policy-engine-asserted facts arrive after issuance and are scoped to the same follow-up receipt extension.

Test plan

  • 16 new unit tests in tests/test_attestation_sep2787.py covering all three signing algorithms, all three args-commitment shapes, tampering rejection, canonicalization invariants, and TTL handling
  • Existing attestation suite (OVERT, IAP, S3P, TEE, transparency log) continues to pass: 77 tests total
  • Ruff clean on all touched files
  • attestation optional extra updated with rfc8785>=0.1.4
  • CHANGELOG (Unreleased) updated

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced SEP-2787 tool-call attestation envelope with support for HS256, ES256, and RS256 signing algorithms and JCS canonicalization.
    • Added attestation envelope emission and verification functionality.
  • Documentation

    • Added comprehensive mapping guide between OVERT 1.0 and SEP-2787 attestation standards.

Review Change Stack

Adds vaara.attestation.sep2787 implementing the SEP-2787 Tool Call
Attestation envelope (modelcontextprotocol/modelcontextprotocol#2787)
with the four schema changes Vaara raised in the v1 draft thread:
fact-source labels (three trust-surface blocks), three-way args shape
(ArgsDigest / ArgsRef / ArgsProjection), RFC 8785 (JCS) canonicalization
with IEEE-754 float rejection, and request-attestation-only scope
(the v1 optional ack field is excluded and belongs in a separate
extension). Supports HS256, ES256, RS256 signing per the v1 draft.

Coexists with the existing OVERT 1.0 implementation. See
docs/sep2787-overt-mapping.md for the field-level mapping between the
two envelopes.

16 unit tests covering all three signing algorithms, all three
args-commitment shapes, tampering rejection, canonicalization
invariants, and TTL handling. Ruff-clean.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Warning

Review limit reached

@vaaraio, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 37 minutes and 26 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7bded5ad-047f-4cf8-acaf-95968e23b209

📥 Commits

Reviewing files that changed from the base of the PR and between 22c9fe5 and 7172ae2.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • docs/sep2787-overt-mapping.md
  • tests/test_attestation_sep2787.py
📝 Walkthrough

Walkthrough

This PR introduces a complete reference implementation of the SEP-2787 tool-call attestation envelope standard, including typed dataclass models, JCS canonicalization utilities, HS256/ES256/RS256 signing support, emit/verify orchestration, and comprehensive test coverage. Documentation mapping SEP-2787 fields to the existing OVERT standard is included.

Changes

SEP-2787 Attestation Implementation

Layer / File(s) Summary
SEP-2787 Data Model & Types
src/vaara/attestation/_sep2787_types.py
Defines ArgsDigest, ArgsRef, ArgsProjection union (ArgsCommitment); ToolCallBinding with name, server fingerprint, and args commitment; PlannerDeclared with intent and tool-call tuples; IssuerAsserted with issuer identity, time, nonce, and algorithm; Attestation envelope with to_dict() serialization and helper converters.
Signing Algorithms
src/vaara/attestation/_sep2787_signing.py
Implements HS256 (HMAC-SHA256 hex, constant-time comparison), ES256 (ECDSA P-256 DER→64-byte raw r||s format), and RS256 (RSA PKCS#1 v1.5 SHA-256) signing and verification with hex-encoded signatures.
Canonicalization & Utilities
src/vaara/attestation/_sep2787_canonical.py
Provides canonical_json (RFC 8785 JCS with float rejection), now_iso8601 and new_nonce generators, iso8601_to_epoch parser, and make_args_digest and make_args_projection helpers that compute SHA-256 digests over canonical payloads.
Attestation Emission & Verification
src/vaara/attestation/_sep2787_emit.py
emit_attestation() validates algorithm/intent/tool-calls, constructs IssuerAsserted, derives payload_derived, canonicalizes envelope, and signs using selected algorithm. verify_attestation() reconstructs canonical payload, verifies signature, and enforces TTL with clock skew tolerance.
Public Module API & Exports
src/vaara/attestation/sep2787.py, src/vaara/attestation/__init__.py
Public sep2787 module with comprehensive docstring re-exports types, canonicalization, and attestation operations via __all__; package-level exports with aliased names (e.g., SEP2787Attestation, sep2787_emit_attestation).
Documentation & Configuration
docs/sep2787-overt-mapping.md, CHANGELOG.md, pyproject.toml
Field-by-field OVERT-to-SEP-2787 mapping table noting direct matches, divergences, and canonicalization differences; changelog entries for implementation and test coverage; added rfc8785>=0.1.4 to attestation optional dependency.
Test Suite
tests/test_attestation_sep2787.py
End-to-end round trips for HS256/ES256/RS256; tampering rejection (planner and issuer blocks); args shape preservation; canonical JSON (float rejection, key sorting, Unicode); TTL expiry; input validation; serialization; cross-algorithm verification failure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops with JCS precision,
Signing tokens with cryptographic vision—
HS256, ES256, RS256 shine bright,
SEP-2787 envelopes sealed tight! 🐰✨
No floats allowed in our canonical way,
TTL's checked—everything's in sway!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically summarizes the main change: adding a SEP-2787 reference implementation to the attestation module.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sep2787-reference-impl

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
docs/sep2787-overt-mapping.md (1)

64-64: ⚡ Quick win

Consider making the COMPLIANCE.md reference a proper link.

Line 64 references "Vaara COMPLIANCE.md" as plain text while the preceding lines use proper links. For better navigation and consistency, consider using a relative Markdown link format.

📝 Suggested improvement
-- Vaara COMPLIANCE.md "Position relative to open runtime-attestation standards"
+- [Vaara COMPLIANCE.md](../COMPLIANCE.md) "Position relative to open runtime-attestation standards"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/sep2787-overt-mapping.md` at line 64, Replace the plain text reference
"Vaara COMPLIANCE.md" with a proper relative Markdown link to the COMPLIANCE.md
file (for example, [Vaara COMPLIANCE.md](./COMPLIANCE.md)) so it matches the
surrounding link style; update the string where "Vaara COMPLIANCE.md" appears in
docs/sep2787-overt-mapping.md to the relative link format to restore consistent
navigation.
tests/test_attestation_sep2787.py (1)

49-59: ⚡ Quick win

Rename helper to reflect its general purpose.

The _emit_hs256 helper is used for all signing algorithms (HS256, ES256, RS256), not just HS256. The current name is misleading and could cause confusion during maintenance.

♻️ Rename to `_emit_attestation`
-def _emit_hs256(**overrides) -> Attestation:
+def _emit_attestation(**overrides) -> Attestation:
     kwargs = dict(
         planner_declared=_planner(),
         iss="issuer://test",

Then update all call sites (lines 63, 72, 79, 84, 102, 128, 157, 170, 174, 179, 184, 195) to use the new name.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_attestation_sep2787.py` around lines 49 - 59, Rename the helper
function `_emit_hs256` to `_emit_attestation` and update all call sites to
match; specifically change the function definition `def _emit_hs256(**overrides)
-> Attestation:` to `def _emit_attestation(**overrides) -> Attestation:` and
update every invocation that currently calls `_emit_hs256(...)` (the calls
referenced in the review: lines corresponding to the original occurrences at 63,
72, 79, 84, 102, 128, 157, 170, 174, 179, 184, 195) to call
`_emit_attestation(...)` instead so the name reflects it supports
HS256/ES256/RS256; ensure any imports or local references use the new name and
run tests to verify no reference errors remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_attestation_sep2787.py`:
- Around line 156-161: Add a test (e.g., test_ttl_clock_skew_tolerance) that
uses _emit_hs256(exp_seconds=60) to build env, read the attestation issue time
via env.issuer_asserted.iat, then assert verify_attestation(env,
verifying_material=HS_SECRET, now=iat + 60 + small_offset) returns True for a
now within the implementation's clock skew tolerance and that
verify_attestation(...) returns False for now = iat + 60 + tolerance + 1; use
the actual tolerance constant from the implementation (e.g.,
CLOCK_SKEW_TOLERANCE or TTL_SKEW) when computing offsets and reference
verify_attestation, _emit_hs256, env.issuer_asserted.iat and HS_SECRET to locate
the relevant code.

---

Nitpick comments:
In `@docs/sep2787-overt-mapping.md`:
- Line 64: Replace the plain text reference "Vaara COMPLIANCE.md" with a proper
relative Markdown link to the COMPLIANCE.md file (for example, [Vaara
COMPLIANCE.md](./COMPLIANCE.md)) so it matches the surrounding link style;
update the string where "Vaara COMPLIANCE.md" appears in
docs/sep2787-overt-mapping.md to the relative link format to restore consistent
navigation.

In `@tests/test_attestation_sep2787.py`:
- Around line 49-59: Rename the helper function `_emit_hs256` to
`_emit_attestation` and update all call sites to match; specifically change the
function definition `def _emit_hs256(**overrides) -> Attestation:` to `def
_emit_attestation(**overrides) -> Attestation:` and update every invocation that
currently calls `_emit_hs256(...)` (the calls referenced in the review: lines
corresponding to the original occurrences at 63, 72, 79, 84, 102, 128, 157, 170,
174, 179, 184, 195) to call `_emit_attestation(...)` instead so the name
reflects it supports HS256/ES256/RS256; ensure any imports or local references
use the new name and run tests to verify no reference errors remain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a58b47ed-9187-4894-a2f8-4bf217fdda9f

📥 Commits

Reviewing files that changed from the base of the PR and between ac8327b and 22c9fe5.

📒 Files selected for processing (10)
  • CHANGELOG.md
  • docs/sep2787-overt-mapping.md
  • pyproject.toml
  • src/vaara/attestation/__init__.py
  • src/vaara/attestation/_sep2787_canonical.py
  • src/vaara/attestation/_sep2787_emit.py
  • src/vaara/attestation/_sep2787_signing.py
  • src/vaara/attestation/_sep2787_types.py
  • src/vaara/attestation/sep2787.py
  • tests/test_attestation_sep2787.py

Comment thread tests/test_attestation_sep2787.py
Comment thread tests/test_attestation_sep2787.py Fixed
vaaraio and others added 2 commits May 26, 2026 16:43
- Rename the test helper _emit_hs256 to _emit_attestation. It builds
  envelopes for all three signing algorithms, not only HS256, so the
  HS256-only name is misleading.
- Add test_ttl_clock_skew_tolerance_window covering the verifier's
  default 30-second skew window: a 60-second TTL with iat + 75 still
  verifies, iat + 91 does not.
- Switch the optional-dependency probe from a try/import block to
  importlib.util.find_spec. Eliminates the CodeQL unused-import
  finding on rfc8785 without changing skip semantics.
- Convert the docs/sep2787-overt-mapping.md reference to COMPLIANCE.md
  into a relative markdown link.
@vaaraio vaaraio merged commit 3e3b08d into main May 26, 2026
12 checks passed
@vaaraio vaaraio deleted the feat/sep2787-reference-impl branch May 26, 2026 14:11
vaaraio added a commit that referenced this pull request May 26, 2026
…v0.36 sub-cell (#144)

Adds a third attacker family to the cross-model held-out fold and
ships a v8 classifier that trains on the v035 + v036 TM/PE union and
keeps v036 DE both legs plus the full v037 Llama-3.3 leg as the new
held-out evaluation. Closes the worst sub-cell from v0.36 by 12.9 pp
on the same 700 Claude DE entries (26.0% under v7 to 38.9% under v8),
covers a third attacker family at 85.8% overall recall, and holds
in-distribution at 86.6% on v035 TEST with FPR inside the prior
confidence interval.

Generation provenance: 900 entries from
RedHatAI/Llama-3.3-70B-Instruct-FP8-dynamic on AMD-backed MI300X
SR-IOV under rocm/vllm:latest, three parallel category generators, 22
minutes wall clock, droplet poweroff post-rsync. 13 schema-invalid TM
entries dropped, 887 valid (TM 287, PE 300, DE 300).

v8 production bundle ships at
src/vaara/data/adversarial_classifier_v8.joblib. v7 retained on disk
for cross-eval reproducibility. Threshold unchanged at 0.9006.

Also bundles the MIT AI Risk Repository v4 position document and the
SEP-2787 Tool Call Attestation reference implementation that landed
on main via PR #139. Both fit the v0.37 ship window and add one clean
line each to the validator stack and the public taxonomy positioning.

Full methodology, chain of custody, ship gate, and named limits in
bench/vaara-bench-v0.37.md.

Co-authored-by: vaaraio <267591518+vaaraio@users.noreply.github.com>
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.

2 participants