vouch-protocol 2.0.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. {vouch_protocol-2.0.1/vouch_protocol.egg-info → vouch_protocol-2.1.0}/PKG-INFO +26 -16
  2. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/README.md +16 -14
  3. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/pyproject.toml +25 -5
  4. vouch_protocol-2.1.0/tests/test_agent_enroll.py +302 -0
  5. vouch_protocol-2.1.0/tests/test_authority_state.py +464 -0
  6. vouch_protocol-2.1.0/tests/test_authority_state_vectors.py +77 -0
  7. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_cli_init.py +25 -0
  8. vouch_protocol-2.1.0/tests/test_cli_root.py +266 -0
  9. vouch_protocol-2.1.0/tests/test_data_integrity.py +258 -0
  10. vouch_protocol-2.1.0/tests/test_delegation_attenuation.py +30 -0
  11. vouch_protocol-2.1.0/tests/test_disconnected_edge.py +239 -0
  12. vouch_protocol-2.1.0/tests/test_dtn_pads.py +429 -0
  13. vouch_protocol-2.1.0/tests/test_examples_robotics.py +397 -0
  14. vouch_protocol-2.1.0/tests/test_halos_evidence.py +161 -0
  15. vouch_protocol-2.1.0/tests/test_hardware_seam.py +183 -0
  16. vouch_protocol-2.1.0/tests/test_hybrid.py +601 -0
  17. vouch_protocol-2.1.0/tests/test_intent_recheck.py +151 -0
  18. vouch_protocol-2.1.0/tests/test_mint_contributor_credential.py +95 -0
  19. vouch_protocol-2.1.0/tests/test_orbital_accumulator.py +192 -0
  20. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_conformance.py +135 -2
  21. vouch_protocol-2.1.0/tests/test_robot_consent.py +200 -0
  22. vouch_protocol-2.1.0/tests/test_robot_handover.py +118 -0
  23. vouch_protocol-2.1.0/tests/test_robot_odd.py +128 -0
  24. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_pq.py +71 -2
  25. vouch_protocol-2.1.0/tests/test_robot_root_identity.py +177 -0
  26. vouch_protocol-2.1.0/tests/test_robot_swarm.py +103 -0
  27. vouch_protocol-2.1.0/tests/test_robot_teleop.py +180 -0
  28. vouch_protocol-2.1.0/tests/test_root_of_trust.py +403 -0
  29. vouch_protocol-2.1.0/tests/test_root_of_trust_vectors.py +70 -0
  30. vouch_protocol-2.1.0/tests/test_ros2_action_gate.py +467 -0
  31. vouch_protocol-2.1.0/tests/test_runtime_vectors.py +56 -0
  32. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_signer_vc.py +43 -9
  33. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_status_list.py +107 -0
  34. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/__init__.py +778 -694
  35. vouch_protocol-2.1.0/vouch/attenuation.py +287 -0
  36. vouch_protocol-2.1.0/vouch/authority_state.py +697 -0
  37. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/cli.py +634 -3
  38. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/conformance.py +85 -31
  39. vouch_protocol-2.1.0/vouch/data_integrity.py +184 -0
  40. vouch_protocol-2.1.0/vouch/data_integrity_hybrid.py +379 -0
  41. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/heartbeat.py +30 -0
  42. vouch_protocol-2.1.0/vouch/integrations/mcp/__init__.py +5 -0
  43. vouch_protocol-2.1.0/vouch/integrations/mcp/server.py +1222 -0
  44. vouch_protocol-2.1.0/vouch/integrations/mlflow.py +101 -0
  45. vouch_protocol-2.1.0/vouch/integrations/openai.py +198 -0
  46. vouch_protocol-2.1.0/vouch/integrations/safetensors.py +126 -0
  47. vouch_protocol-2.1.0/vouch/intent_recheck.py +241 -0
  48. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reasoning.py +8 -0
  49. vouch_protocol-2.1.0/vouch/robotics/__init__.py +634 -0
  50. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/_signing.py +12 -4
  51. vouch_protocol-2.1.0/vouch/robotics/_verify.py +43 -0
  52. vouch_protocol-2.1.0/vouch/robotics/accumulator.py +147 -0
  53. vouch_protocol-2.1.0/vouch/robotics/bundle.py +128 -0
  54. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/conformance.py +159 -19
  55. vouch_protocol-2.1.0/vouch/robotics/consent.py +309 -0
  56. vouch_protocol-2.1.0/vouch/robotics/dtn_revocation.py +265 -0
  57. vouch_protocol-2.1.0/vouch/robotics/edge_trust.py +255 -0
  58. vouch_protocol-2.1.0/vouch/robotics/freshness.py +173 -0
  59. vouch_protocol-2.1.0/vouch/robotics/geoscope.py +214 -0
  60. vouch_protocol-2.1.0/vouch/robotics/halos.py +231 -0
  61. vouch_protocol-2.1.0/vouch/robotics/handover.py +194 -0
  62. vouch_protocol-2.1.0/vouch/robotics/hardware.py +352 -0
  63. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/identity.py +3 -1
  64. vouch_protocol-2.1.0/vouch/robotics/localization.py +284 -0
  65. vouch_protocol-2.1.0/vouch/robotics/odd.py +241 -0
  66. vouch_protocol-2.1.0/vouch/robotics/orbital.py +164 -0
  67. vouch_protocol-2.1.0/vouch/robotics/perception_consensus.py +182 -0
  68. vouch_protocol-2.1.0/vouch/robotics/pq.py +182 -0
  69. vouch_protocol-2.1.0/vouch/robotics/presence.py +206 -0
  70. vouch_protocol-2.1.0/vouch/robotics/quorum_trust.py +269 -0
  71. vouch_protocol-2.1.0/vouch/robotics/root_identity.py +201 -0
  72. vouch_protocol-2.1.0/vouch/robotics/swarm.py +201 -0
  73. vouch_protocol-2.1.0/vouch/robotics/teleop.py +233 -0
  74. vouch_protocol-2.1.0/vouch/root_of_trust.py +671 -0
  75. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/signer.py +74 -21
  76. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/status_list.py +190 -0
  77. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/trust_check.py +75 -3
  78. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/vc.py +21 -7
  79. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/verifier.py +17 -0
  80. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0/vouch_protocol.egg-info}/PKG-INFO +26 -16
  81. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch_protocol.egg-info/SOURCES.txt +50 -0
  82. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch_protocol.egg-info/requires.txt +10 -1
  83. vouch_protocol-2.0.1/tests/test_data_integrity.py +0 -102
  84. vouch_protocol-2.0.1/tests/test_hybrid.py +0 -282
  85. vouch_protocol-2.0.1/vouch/data_integrity.py +0 -130
  86. vouch_protocol-2.0.1/vouch/data_integrity_hybrid.py +0 -214
  87. vouch_protocol-2.0.1/vouch/integrations/mcp/__init__.py +0 -5
  88. vouch_protocol-2.0.1/vouch/integrations/mcp/server.py +0 -267
  89. vouch_protocol-2.0.1/vouch/robotics/__init__.py +0 -299
  90. vouch_protocol-2.0.1/vouch/robotics/pq.py +0 -146
  91. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/LICENSE +0 -0
  92. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/MANIFEST.in +0 -0
  93. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/setup.cfg +0 -0
  94. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_accountability.py +0 -0
  95. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_attribution.py +0 -0
  96. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_audio_bridge.py +0 -0
  97. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_audit_trail.py +0 -0
  98. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_auditor.py +0 -0
  99. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_autosign.py +0 -0
  100. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_behavioral_attestation.py +0 -0
  101. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_bridge.py +0 -0
  102. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_budget.py +0 -0
  103. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_c2pa_formats.py +0 -0
  104. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_cache.py +0 -0
  105. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_canary.py +0 -0
  106. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_caveats.py +0 -0
  107. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_conformance.py +0 -0
  108. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_credential_gate.py +0 -0
  109. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_deliberation.py +0 -0
  110. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_dx_sugar.py +0 -0
  111. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_fastapi_credential_gate.py +0 -0
  112. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_fleet.py +0 -0
  113. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_git_workflow.py +0 -0
  114. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_grade.py +0 -0
  115. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_hasura_integration.py +0 -0
  116. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_heartbeat.py +0 -0
  117. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_hybrid_interop.py +0 -0
  118. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_jcs.py +0 -0
  119. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_jcs_interop.py +0 -0
  120. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_liveness_conformance.py +0 -0
  121. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_media_badge.py +0 -0
  122. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_media_native.py +0 -0
  123. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_merkle.py +0 -0
  124. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_multikey.py +0 -0
  125. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_nonce.py +0 -0
  126. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_proof_of_integration.py +0 -0
  127. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_provenance.py +0 -0
  128. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_quorum.py +0 -0
  129. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reasoning.py +0 -0
  130. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_receipts.py +0 -0
  131. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_recovery.py +0 -0
  132. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation.py +0 -0
  133. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation_aggregate.py +0 -0
  134. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation_disputes.py +0 -0
  135. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation_ledger.py +0 -0
  136. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation_policy.py +0 -0
  137. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_reputation_portability.py +0 -0
  138. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_revocation.py +0 -0
  139. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_access.py +0 -0
  140. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_custody.py +0 -0
  141. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_embodiment.py +0 -0
  142. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_fusion.py +0 -0
  143. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_handshake_blackbox_passport.py +0 -0
  144. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_identity.py +0 -0
  145. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_lease_quorum.py +0 -0
  146. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_lifecycle.py +0 -0
  147. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_liveness_revocation.py +0 -0
  148. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_perception.py +0 -0
  149. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_provenance_capability.py +0 -0
  150. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_safety_record.py +0 -0
  151. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_robot_wear.py +0 -0
  152. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_scan.py +0 -0
  153. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_secure_key_custody.py +0 -0
  154. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_security_hardening.py +0 -0
  155. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_shield_guard.py +0 -0
  156. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_threshold.py +0 -0
  157. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_tool_registry.py +0 -0
  158. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_transparency.py +0 -0
  159. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_transport.py +0 -0
  160. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_transport_http_rendezvous.py +0 -0
  161. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_transport_rendezvous.py +0 -0
  162. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_transport_udna_sdk.py +0 -0
  163. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_trifecta.py +0 -0
  164. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_trust_check.py +0 -0
  165. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_trust_entropy.py +0 -0
  166. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_validator_server.py +0 -0
  167. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_vc.py +0 -0
  168. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/tests/test_verifier_vc.py +0 -0
  169. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/accountability.py +0 -0
  170. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/agent.py +0 -0
  171. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/async_verifier.py +0 -0
  172. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/attribution.py +0 -0
  173. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/attribution_cli.py +0 -0
  174. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/audio.py +0 -0
  175. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/audit_trail.py +0 -0
  176. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/auditor.py +0 -0
  177. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/autosign.py +0 -0
  178. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/behavioral_attestation.py +0 -0
  179. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/bridge/__init__.py +0 -0
  180. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/bridge/audio_routes.py +0 -0
  181. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/bridge/config.py +0 -0
  182. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/bridge/server.py +0 -0
  183. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/budget.py +0 -0
  184. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/cache.py +0 -0
  185. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/canary.py +0 -0
  186. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/caveats.py +0 -0
  187. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/config.py +0 -0
  188. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/credential.py +0 -0
  189. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/deliberation.py +0 -0
  190. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/did_web.py +0 -0
  191. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/fleet.py +0 -0
  192. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/gate.py +0 -0
  193. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/grade.py +0 -0
  194. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/_common.py +0 -0
  195. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/a2a.py +0 -0
  196. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/adk.py +0 -0
  197. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/amnesia.py +0 -0
  198. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/autogen/__init__.py +0 -0
  199. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/autogpt/__init__.py +0 -0
  200. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/autogpt/commands.py +0 -0
  201. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/claude-code/settings.hooks.json +0 -0
  202. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/crewai/__init__.py +0 -0
  203. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/crewai/tool.py +0 -0
  204. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/fastapi.py +0 -0
  205. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/google.py +0 -0
  206. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/goose.py +0 -0
  207. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/hasura/__init__.py +0 -0
  208. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/hasura/webhook.py +0 -0
  209. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/langchain/__init__.py +0 -0
  210. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/langchain/tool.py +0 -0
  211. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/langgraph.py +0 -0
  212. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/n8n.py +0 -0
  213. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/streamlit/__init__.py +0 -0
  214. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/streamlit/seal.py +0 -0
  215. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/integrations/vertex_ai/__init__.py +0 -0
  216. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/jcs.py +0 -0
  217. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/keys.py +0 -0
  218. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/keystore.py +0 -0
  219. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/kms.py +0 -0
  220. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/liveness_conformance.py +0 -0
  221. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/mcp_guard.py +0 -0
  222. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/media/__init__.py +0 -0
  223. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/media/badge.py +0 -0
  224. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/media/c2pa.py +0 -0
  225. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/media/native.py +0 -0
  226. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/merkle.py +0 -0
  227. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/metrics.py +0 -0
  228. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/multikey.py +0 -0
  229. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/nonce.py +0 -0
  230. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/onboard.py +0 -0
  231. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/proof_of_integration.py +0 -0
  232. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/provenance.py +0 -0
  233. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/quorum.py +0 -0
  234. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/ratelimit.py +0 -0
  235. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/receipts.py +0 -0
  236. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/recovery.py +0 -0
  237. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/registry.py +0 -0
  238. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation.py +0 -0
  239. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation_aggregate.py +0 -0
  240. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation_disputes.py +0 -0
  241. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation_ledger.py +0 -0
  242. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation_policy.py +0 -0
  243. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/reputation_portability.py +0 -0
  244. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/revocation.py +0 -0
  245. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/access.py +0 -0
  246. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/blackbox.py +0 -0
  247. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/capability.py +0 -0
  248. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/custody.py +0 -0
  249. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/embodiment.py +0 -0
  250. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/fusion.py +0 -0
  251. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/handshake.py +0 -0
  252. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/lease.py +0 -0
  253. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/lifecycle.py +0 -0
  254. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/liveness.py +0 -0
  255. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/passport.py +0 -0
  256. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/perception.py +0 -0
  257. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/physical_quorum.py +0 -0
  258. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/provenance.py +0 -0
  259. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/revocation.py +0 -0
  260. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/safety_record.py +0 -0
  261. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/robotics/wear.py +0 -0
  262. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/scan/__init__.py +0 -0
  263. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/scan/detector.py +0 -0
  264. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/scan/patterns.py +0 -0
  265. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/seal.py +0 -0
  266. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/__init__.py +0 -0
  267. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/demo.py +0 -0
  268. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/flight_recorder.py +0 -0
  269. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/permissions.py +0 -0
  270. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/shield.py +0 -0
  271. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/shield/trust_registry.py +0 -0
  272. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/ssrf.py +0 -0
  273. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/status_list_fetcher.py +0 -0
  274. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/threshold.py +0 -0
  275. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/tool_registry.py +0 -0
  276. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transparency.py +0 -0
  277. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/__init__.py +0 -0
  278. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/base.py +0 -0
  279. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/did_key.py +0 -0
  280. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/envelope.py +0 -0
  281. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/http_rendezvous.py +0 -0
  282. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/http_transport.py +0 -0
  283. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/manager.py +0 -0
  284. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/rendezvous.py +0 -0
  285. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/transport/udna.py +0 -0
  286. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/trifecta.py +0 -0
  287. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/trust_entropy.py +0 -0
  288. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/validator_server.py +0 -0
  289. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch/verification.py +0 -0
  290. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch_protocol.egg-info/dependency_links.txt +0 -0
  291. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch_protocol.egg-info/entry_points.txt +0 -0
  292. {vouch_protocol-2.0.1 → vouch_protocol-2.1.0}/vouch_protocol.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vouch-protocol
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: The Identity & Reputation Standard for AI Agents
5
5
  Author-email: Vouch Protocol Contributors <hello@vouch-protocol.com>
6
6
  License: Apache License 2.0
@@ -236,7 +236,7 @@ Requires-Dist: pyyaml>=6.0; extra == "goose"
236
236
  Provides-Extra: autogen
237
237
  Requires-Dist: pyautogen>=0.2.0; extra == "autogen"
238
238
  Provides-Extra: mcp
239
- Requires-Dist: mcp>=0.1.0; extra == "mcp"
239
+ Requires-Dist: mcp>=1.2.0; extra == "mcp"
240
240
  Provides-Extra: vertex
241
241
  Requires-Dist: google-cloud-aiplatform>=1.0.0; extra == "vertex"
242
242
  Provides-Extra: streamlit
@@ -265,6 +265,14 @@ Requires-Dist: Pillow>=10.0.0; extra == "media"
265
265
  Requires-Dist: base58>=2.1.0; extra == "media"
266
266
  Requires-Dist: qrcode>=7.4.0; extra == "media"
267
267
  Requires-Dist: c2pa-python>=0.5.0; extra == "media"
268
+ Provides-Extra: openvla
269
+ Requires-Dist: torch>=2.2.0; extra == "openvla"
270
+ Requires-Dist: transformers==4.40.1; extra == "openvla"
271
+ Requires-Dist: tokenizers==0.19.1; extra == "openvla"
272
+ Requires-Dist: timm==0.9.10; extra == "openvla"
273
+ Requires-Dist: accelerate>=0.25.0; extra == "openvla"
274
+ Requires-Dist: huggingface-hub>=0.23.0; extra == "openvla"
275
+ Requires-Dist: Pillow>=10.0.0; extra == "openvla"
268
276
  Provides-Extra: dev
269
277
  Requires-Dist: pytest>=7.0.0; extra == "dev"
270
278
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
@@ -348,7 +356,7 @@ Vouch Protocol v1.0 aligns directly with the open standard:
348
356
  - **Verifiable Credentials** as the credential format (replacing v0.x JWS tokens).
349
357
  - **Data Integrity proofs** with the `eddsa-jcs-2022` cryptosuite (no JOSE, no Base64-wrapped payload, the credential remains human-readable JSON).
350
358
  - **Multikey verification methods** in DID Documents (algorithm-agnostic, ML-DSA-44 ready).
351
- - **Hybrid post-quantum profile** (`hybrid-eddsa-mldsa44-jcs-2026`) as an optional add-on for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 timelines.
359
+ - **Post-quantum profile** as a Data Integrity proof set: the credential carries two independent proofs, `eddsa-jcs-2022` and `mldsa44-jcs-2024`, an optional add-on for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 timelines.
352
360
  - **Three-way cross-implementation interop** verified across Python, TypeScript, and Go.
353
361
 
354
362
  Credentials are issued with `Signer.sign()` and checked with `Verifier.verify()`. See the Specification at [vouch-protocol.com/specs/SPEC/](https://vouch-protocol.com/specs/SPEC/) for the full specification.
@@ -377,6 +385,7 @@ Vouch is not one tool, it is a set of them. Here is the whole map.
377
385
  - **Identity Sidecar** keeps signing keys out of the model's context, so a prompt injection cannot read them.
378
386
  - **Vouch Shield** a runtime check that inspects every tool call against your rules, like a customs officer at the door.
379
387
  - **Continuous trust** heartbeats and session vouchers, so trust is a live signal that has to be renewed, not a badge that is issued once and trusted forever.
388
+ - **Authority freshness** a signed authority state with a counter that only goes up, so a state change (a fraud signal, a suspended mandate) collapses the acceptable freshness window to now for a high-consequence action, even when time-decay trust still passes. See [docs/authority-freshness.md](docs/authority-freshness.md).
380
389
 
381
390
  ### Framework integrations (new in v1.6.2)
382
391
  Standalone packages that drop Vouch into the agent framework you already use. Each one issues a verifiable credential for a tool call, with optional delegation back to a human principal.
@@ -394,7 +403,7 @@ The standalone **`vouch-mcp`** package above ships alongside these in v1.6.2.
394
403
  Python, TypeScript, and Go are the full reference implementations. A Rust core with idiomatic Swift, JVM (Java and Kotlin), .NET, and C wrappers shares one codebase, so every language produces byte-identical output, verified against shared test vectors. A WebAssembly build is included for the browser and the edge. See the table further down for status per language.
395
404
 
396
405
  ### Robots and embodied agents
397
- A robot is an agent with a body, so identity and accountability matter even more once it can cause physical harm. The `vouch.robotics` module ships six capabilities on the same `eddsa-jcs-2022` credentials as the rest of Vouch: hardware-rooted identity (bound to a TPM or secure element, so it cannot be cloned to other hardware), model and config provenance (re-signable on every OTA update), physical capability scope (force, speed, a tighter cap near humans, allowed zones, and shift windows, checked before each actuation, with narrow-only delegation), a robot-to-robot trust handshake, an encrypted tamper-evident black box with a verifiable kill switch, and a scannable offline passport. All six are implemented in Python, TypeScript, Go, and the Rust core, which flows to the Swift, Kotlin/JVM, .NET, C/C++, and WebAssembly wrappers, so a robotics credential signed in one language verifies in every other. Fourteen further capabilities round out the set: a living-trust heartbeat (a signed per-interval motion summary whose trust decays unless it is renewed in-envelope), two-level credential revocation (per-credential status lists and whole-DID kill), an accountable safety record (a tamper-evident incident ledger summarized into a portable signed record), signed perception provenance (each captured sensor frame's hash bound to the robot's key and hash-linked, so a robot can prove what its sensors saw and a substituted frame is detectable), an offline delegation lease (a short-lived, scope-bounded grant a disconnected robot verifies and acts on with no network call, nesting across vendors), a physical quorum (a cryptographic two-person rule requiring M of N attested approvers for a high-consequence action), lifecycle credentials (ownership transfer that chains into a verifiable chain of custody, key rotation that forms a key history, and a signed decommission that retires the robot), a regulatory conformance profile (a machine-checkable mapping from a robot's credentials to the clauses of ISO 10218 and 15066, the EU Machinery Regulation, the EU AI Act, and UL 3300, with a deterministic checker and a signed conformance attestation), post-quantum signing by default (robot credentials sign with the hybrid classical-plus-ML-DSA-44 cryptosuite, with backward-compatible verification, so a robot stays unforgeable across its decade-long life), and cross-embodiment identity continuity (an agent identity that moves between robot bodies, with an embodiment credential re-binding to each body's hardware root and a continuity chain that proves the same accountable agent persisted, plus a fork check), a physical custody handoff chain (a signed record of who accepted custody of a task or object at each hop across human and robot actors, so an incident traces to the exact hop and an attested condition localizes damage to the holder responsible), bounded infrastructure access (an operator-signed grant naming a resource, its permitted operations, an optional zone, and a time window, which a robot pairs with a signed request the resource authorizes offline, so a robot can open a door or dock at a charger with a tamper-evident, attributable, shrink-only record), fused-sensor provenance (a signed attestation binding a robot's fused world model to the exact set of input frame hashes and the fusion method that produced it, so a manipulated fusion result or a dropped input is detectable and every fused input traces to a frame the robot recorded), and wear and degradation attestation (a robot signs its own wear level bound to its identity and hash-linked over time, and a deterministic rule narrows its physical capability scope as it degrades, so a worn robot operates inside a tighter, verifiable envelope than the static limit it shipped with), implemented across the same languages and pinned by the shared interop vector. See [docs/robotics.md](docs/robotics.md) and the defensive disclosures PAD-064 through PAD-070, PAD-076 through PAD-084, and PAD-087 through PAD-092.
406
+ A robot is an agent with a body, so identity and accountability matter even more once it can cause physical harm. The `vouch.robotics` module ships six capabilities on the same `eddsa-jcs-2022` credentials as the rest of Vouch: hardware-rooted identity (bound to a TPM or secure element, so it cannot be cloned to other hardware), model and config provenance (re-signable on every OTA update), physical capability scope (force, speed, a tighter cap near humans, allowed zones, and shift windows, checked before each actuation, with narrow-only delegation), a robot-to-robot trust handshake, an encrypted tamper-evident black box with a verifiable kill switch, and a scannable offline passport. All six are implemented in Python, TypeScript, Go, and the Rust core, which flows to the Swift, Kotlin/JVM, .NET, C/C++, and WebAssembly wrappers, so a robotics credential signed in one language verifies in every other. Fifteen further capabilities round out the set: a living-trust heartbeat (a signed per-interval motion summary whose trust decays unless it is renewed in-envelope), two-level credential revocation (per-credential status lists and whole-DID kill), an accountable safety record (a tamper-evident incident ledger summarized into a portable signed record), signed perception provenance (each captured sensor frame's hash bound to the robot's key and hash-linked, so a robot can prove what its sensors saw and a substituted frame is detectable), an offline delegation lease (a short-lived, scope-bounded grant a disconnected robot verifies and acts on with no network call, nesting across vendors), a physical quorum (a cryptographic two-person rule requiring M of N attested approvers for a high-consequence action), lifecycle credentials (ownership transfer that chains into a verifiable chain of custody, key rotation that forms a key history, and a signed decommission that retires the robot), a regulatory conformance profile (a machine-checkable mapping from a robot's credentials to the clauses of ISO 10218 and 15066, the EU Machinery Regulation, the EU AI Act, and UL 3300, with a deterministic checker and a signed conformance attestation), post-quantum signing by default (robot credentials carry a proof set with an Ed25519 proof and an ML-DSA-44 proof, with backward-compatible verification, so a robot stays unforgeable across its decade-long life), and cross-embodiment identity continuity (an agent identity that moves between robot bodies, with an embodiment credential re-binding to each body's hardware root and a continuity chain that proves the same accountable agent persisted, plus a fork check), a physical custody handoff chain (a signed record of who accepted custody of a task or object at each hop across human and robot actors, so an incident traces to the exact hop and an attested condition localizes damage to the holder responsible), bounded infrastructure access (an operator-signed grant naming a resource, its permitted operations, an optional zone, and a time window, which a robot pairs with a signed request the resource authorizes offline, so a robot can open a door or dock at a charger with a tamper-evident, attributable, shrink-only record), fused-sensor provenance (a signed attestation binding a robot's fused world model to the exact set of input frame hashes and the fusion method that produced it, so a manipulated fusion result or a dropped input is detectable and every fused input traces to a frame the robot recorded), wear and degradation attestation (a robot signs its own wear level bound to its identity and hash-linked over time, and a deterministic rule narrows its physical capability scope as it degrades, so a worn robot operates inside a tighter, verifiable envelope than the static limit it shipped with), and bystander-consent evidence (a robot binds the basis for capturing people, an explicit token, posted notice, a legitimate interest, or a redaction it applied, to the capture itself by its hash, holding only hashes and never anyone's identifying data, and a bystander can sign consent bound to one capture so it cannot be replayed to another), implemented across the same languages and pinned by the shared interop vector. See [docs/robotics.md](docs/robotics.md) and the defensive disclosures PAD-064 through PAD-070, PAD-076 through PAD-084, and PAD-087 through PAD-094.
398
407
 
399
408
  ### Inside your AI tools
400
409
  - **Claude Skill**, **OpenAI Custom GPT**, and **Gemini Gem** packages that teach your AI assistant how to add Vouch to your code, running on your own AI subscription.
@@ -440,7 +449,7 @@ AI agents are making real-world API calls with **ZERO cryptographic proof** of:
440
449
  - **Data Integrity proofs** (`eddsa-jcs-2022` cryptosuite, no JOSE/JWS dependency)
441
450
  - **Decentralized Identifiers** (`did:web`, `did:key`)
442
451
  - **Multikey verification methods** (algorithm-agnostic, post-quantum ready)
443
- - **Hybrid post-quantum profile** (optional Ed25519 + ML-DSA-44 composite, `hybrid-eddsa-mldsa44-jcs-2026`)
452
+ - **Post-quantum profile** (optional proof set: `eddsa-jcs-2022` + `mldsa44-jcs-2024`)
444
453
  - **Human-readable JSON** (proof attaches as a sibling object, no Base64-wrapped opaque payload)
445
454
  - **Framework-agnostic** (works with MCP, LangChain, CrewAI, AutoGPT, AutoGen, Vertex AI)
446
455
  - **Cross-language interop** (Python, TypeScript, Go, byte-identical canonical form)
@@ -491,15 +500,15 @@ flowchart TB
491
500
  subgraph CRYPTO["Cryptographic Proof"]
492
501
  JCS["JCS canonicalization (RFC 8785)"]
493
502
  DEFAULT["eddsa-jcs-2022<br/>(Ed25519, default)"]
494
- HYBRID["hybrid-eddsa-mldsa44-jcs-2026<br/>(Ed25519 + ML-DSA-44, optional)"]
503
+ PQ["mldsa44-jcs-2024<br/>(ML-DSA-44, optional second proof)"]
495
504
  end
496
505
  IDENTITY --> FORMAT
497
506
  FORMAT --> CRYPTO
498
507
  JCS --> DEFAULT
499
- JCS --> HYBRID
508
+ JCS --> PQ
500
509
  ```
501
510
 
502
- **Trust = Verifiable Credentials + Data Integrity + Decentralized Identifiers + Multikey, with optional hybrid post-quantum signatures.** The same math that secures SSL/TLS, plus the standardized primitives that secure verifiable credentials elsewhere on the web, applied to AI agents.
511
+ **Trust = Verifiable Credentials + Data Integrity + Decentralized Identifiers + Multikey, with an optional post-quantum proof set.** The same math that secures SSL/TLS, plus the standardized primitives that secure verifiable credentials elsewhere on the web, applied to AI agents.
503
512
 
504
513
  ---
505
514
 
@@ -515,7 +524,7 @@ flowchart TB
515
524
  | **Audit trail format** | ✅ (VC standardized) | ❌ (custom) |
516
525
  | **standards-aligned** | ✅ (`eddsa-jcs-2022` Data Integrity) | ❌ |
517
526
  | **Multikey verification methods** | ✅ (algorithm-agnostic) | ❌ |
518
- | **Hybrid post-quantum signatures** | ✅ (`hybrid-eddsa-mldsa44-jcs-2026`) | ❌ |
527
+ | **Post-quantum signatures** | ✅ (`mldsa44-jcs-2024` proof set) | ❌ |
519
528
  | **Cross-implementation interop tests** | ✅ (Python, TypeScript, Go) | ❌ |
520
529
  | **Security best practices** | ✅ (built-in) | ⚠️ (easy to mess up) |
521
530
 
@@ -612,18 +621,19 @@ Works with all major AI frameworks out-of-the-box:
612
621
  - **Reputation Scoring**: track agent behavior over time
613
622
  - **Revocation Registry**: blacklist compromised keys
614
623
  - **Redis Caching**: production-scale verification
615
- - **Hybrid Post-Quantum Profile**: optional Ed25519 + ML-DSA-44 composite signatures (`hybrid-eddsa-mldsa44-jcs-2026`) for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 migration timelines
624
+ - **Post-Quantum Profile**: an optional proof set carrying an `eddsa-jcs-2022` proof and an `mldsa44-jcs-2024` proof for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 migration timelines
616
625
 
617
- ### Hybrid Post-Quantum Example
626
+ ### Post-Quantum Example
618
627
 
619
628
  ```python
620
- # Optional v1.0 profile, requires `pip install pqcrypto`
629
+ # Optional profile, requires `pip install pqcrypto`
621
630
  credential = signer.sign_hybrid(intent={
622
631
  'action': 'submit_clinical_finding',
623
632
  'target': 'trial:NCT00000001',
624
633
  'resource': 'https://fda-submissions.example.com/api/findings',
625
634
  })
626
- # Carries both Ed25519 and ML-DSA-44 signatures over the same JCS canonical form.
635
+ # The credential's `proof` is an array of two independent Data Integrity proofs,
636
+ # eddsa-jcs-2022 and mldsa44-jcs-2024, over the same document.
627
637
  # Verification REQUIRES both to validate.
628
638
  ```
629
639
 
@@ -668,7 +678,7 @@ To keep this space free from patent capture, the project publishes **61 defensiv
668
678
 
669
679
  - [Quick Start](https://github.com/vouch-protocol/vouch#quick-start)
670
680
  - [Vouch Specification (v1.6 normative)](https://vouch-protocol.com/specs/)
671
- - [Hybrid Post-Quantum Implementation Guide](https://github.com/vouch-protocol/vouch/blob/main/docs/hybrid-pq-implementation-guide.md)
681
+ - [Post-Quantum Implementation Guide](https://github.com/vouch-protocol/vouch/blob/main/docs/hybrid-pq-implementation-guide.md)
672
682
  - [Protocol Specification (developer guide)](https://github.com/vouch-protocol/vouch/blob/main/docs/vouch_guide.md)
673
683
  - [Integration Guides](https://github.com/vouch-protocol/vouch/tree/main/vouch/integrations)
674
684
  - [Threat Model and Security Considerations](https://github.com/vouch-protocol/vouch/blob/main/docs/THREAT_MODEL.md)
@@ -691,7 +701,7 @@ To keep this space free from patent capture, the project publishes **61 defensiv
691
701
 
692
702
  - [x] **Verifiable Credentials + Data Integrity** (`eddsa-jcs-2022` cryptosuite)
693
703
  - [x] **Multikey verification methods** (algorithm-agnostic, multibase + multicodec)
694
- - [x] **Hybrid post-quantum profile** (`hybrid-eddsa-mldsa44-jcs-2026`, NIST CNSA 2.0 / NSM-10 aligned)
704
+ - [x] **Post-quantum profile** (`eddsa-jcs-2022` + `mldsa44-jcs-2024` proof set, NIST CNSA 2.0 / NSM-10 aligned)
695
705
  - [x] **Three-language reference implementation** (Python, TypeScript, Go) with byte-identical canonical form via RFC 8785 JCS, verified against shared test vectors
696
706
  - [x] **Specification drafted** and submitted to the open standards group for incubation
697
707
  - [x] **55 Prior Art Disclosures** (CC0 defensive publications)
@@ -753,7 +763,7 @@ Contributions welcome. See [CONTRIBUTING.md](https://github.com/vouch-protocol/v
753
763
 
754
764
  **Areas where help is most useful:**
755
765
  - [ ] Additional framework integrations (Haystack, Semantic Kernel, LlamaIndex, others)
756
- - [ ] Cross-implementation interop test vectors (additional edge cases for JCS, VC, hybrid PQ)
766
+ - [ ] Cross-implementation interop test vectors (additional edge cases for JCS, VC, post-quantum proof sets)
757
767
  - [ ] Tutorials and worked examples for regulated-sector deployments
758
768
  - [ ] Independent security review and audit
759
769
  - [ ] Reference implementations in additional languages (Rust, Java, .NET)
@@ -66,7 +66,7 @@ Vouch Protocol v1.0 aligns directly with the open standard:
66
66
  - **Verifiable Credentials** as the credential format (replacing v0.x JWS tokens).
67
67
  - **Data Integrity proofs** with the `eddsa-jcs-2022` cryptosuite (no JOSE, no Base64-wrapped payload, the credential remains human-readable JSON).
68
68
  - **Multikey verification methods** in DID Documents (algorithm-agnostic, ML-DSA-44 ready).
69
- - **Hybrid post-quantum profile** (`hybrid-eddsa-mldsa44-jcs-2026`) as an optional add-on for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 timelines.
69
+ - **Post-quantum profile** as a Data Integrity proof set: the credential carries two independent proofs, `eddsa-jcs-2022` and `mldsa44-jcs-2024`, an optional add-on for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 timelines.
70
70
  - **Three-way cross-implementation interop** verified across Python, TypeScript, and Go.
71
71
 
72
72
  Credentials are issued with `Signer.sign()` and checked with `Verifier.verify()`. See the Specification at [vouch-protocol.com/specs/SPEC/](https://vouch-protocol.com/specs/SPEC/) for the full specification.
@@ -95,6 +95,7 @@ Vouch is not one tool, it is a set of them. Here is the whole map.
95
95
  - **Identity Sidecar** keeps signing keys out of the model's context, so a prompt injection cannot read them.
96
96
  - **Vouch Shield** a runtime check that inspects every tool call against your rules, like a customs officer at the door.
97
97
  - **Continuous trust** heartbeats and session vouchers, so trust is a live signal that has to be renewed, not a badge that is issued once and trusted forever.
98
+ - **Authority freshness** a signed authority state with a counter that only goes up, so a state change (a fraud signal, a suspended mandate) collapses the acceptable freshness window to now for a high-consequence action, even when time-decay trust still passes. See [docs/authority-freshness.md](docs/authority-freshness.md).
98
99
 
99
100
  ### Framework integrations (new in v1.6.2)
100
101
  Standalone packages that drop Vouch into the agent framework you already use. Each one issues a verifiable credential for a tool call, with optional delegation back to a human principal.
@@ -112,7 +113,7 @@ The standalone **`vouch-mcp`** package above ships alongside these in v1.6.2.
112
113
  Python, TypeScript, and Go are the full reference implementations. A Rust core with idiomatic Swift, JVM (Java and Kotlin), .NET, and C wrappers shares one codebase, so every language produces byte-identical output, verified against shared test vectors. A WebAssembly build is included for the browser and the edge. See the table further down for status per language.
113
114
 
114
115
  ### Robots and embodied agents
115
- A robot is an agent with a body, so identity and accountability matter even more once it can cause physical harm. The `vouch.robotics` module ships six capabilities on the same `eddsa-jcs-2022` credentials as the rest of Vouch: hardware-rooted identity (bound to a TPM or secure element, so it cannot be cloned to other hardware), model and config provenance (re-signable on every OTA update), physical capability scope (force, speed, a tighter cap near humans, allowed zones, and shift windows, checked before each actuation, with narrow-only delegation), a robot-to-robot trust handshake, an encrypted tamper-evident black box with a verifiable kill switch, and a scannable offline passport. All six are implemented in Python, TypeScript, Go, and the Rust core, which flows to the Swift, Kotlin/JVM, .NET, C/C++, and WebAssembly wrappers, so a robotics credential signed in one language verifies in every other. Fourteen further capabilities round out the set: a living-trust heartbeat (a signed per-interval motion summary whose trust decays unless it is renewed in-envelope), two-level credential revocation (per-credential status lists and whole-DID kill), an accountable safety record (a tamper-evident incident ledger summarized into a portable signed record), signed perception provenance (each captured sensor frame's hash bound to the robot's key and hash-linked, so a robot can prove what its sensors saw and a substituted frame is detectable), an offline delegation lease (a short-lived, scope-bounded grant a disconnected robot verifies and acts on with no network call, nesting across vendors), a physical quorum (a cryptographic two-person rule requiring M of N attested approvers for a high-consequence action), lifecycle credentials (ownership transfer that chains into a verifiable chain of custody, key rotation that forms a key history, and a signed decommission that retires the robot), a regulatory conformance profile (a machine-checkable mapping from a robot's credentials to the clauses of ISO 10218 and 15066, the EU Machinery Regulation, the EU AI Act, and UL 3300, with a deterministic checker and a signed conformance attestation), post-quantum signing by default (robot credentials sign with the hybrid classical-plus-ML-DSA-44 cryptosuite, with backward-compatible verification, so a robot stays unforgeable across its decade-long life), and cross-embodiment identity continuity (an agent identity that moves between robot bodies, with an embodiment credential re-binding to each body's hardware root and a continuity chain that proves the same accountable agent persisted, plus a fork check), a physical custody handoff chain (a signed record of who accepted custody of a task or object at each hop across human and robot actors, so an incident traces to the exact hop and an attested condition localizes damage to the holder responsible), bounded infrastructure access (an operator-signed grant naming a resource, its permitted operations, an optional zone, and a time window, which a robot pairs with a signed request the resource authorizes offline, so a robot can open a door or dock at a charger with a tamper-evident, attributable, shrink-only record), fused-sensor provenance (a signed attestation binding a robot's fused world model to the exact set of input frame hashes and the fusion method that produced it, so a manipulated fusion result or a dropped input is detectable and every fused input traces to a frame the robot recorded), and wear and degradation attestation (a robot signs its own wear level bound to its identity and hash-linked over time, and a deterministic rule narrows its physical capability scope as it degrades, so a worn robot operates inside a tighter, verifiable envelope than the static limit it shipped with), implemented across the same languages and pinned by the shared interop vector. See [docs/robotics.md](docs/robotics.md) and the defensive disclosures PAD-064 through PAD-070, PAD-076 through PAD-084, and PAD-087 through PAD-092.
116
+ A robot is an agent with a body, so identity and accountability matter even more once it can cause physical harm. The `vouch.robotics` module ships six capabilities on the same `eddsa-jcs-2022` credentials as the rest of Vouch: hardware-rooted identity (bound to a TPM or secure element, so it cannot be cloned to other hardware), model and config provenance (re-signable on every OTA update), physical capability scope (force, speed, a tighter cap near humans, allowed zones, and shift windows, checked before each actuation, with narrow-only delegation), a robot-to-robot trust handshake, an encrypted tamper-evident black box with a verifiable kill switch, and a scannable offline passport. All six are implemented in Python, TypeScript, Go, and the Rust core, which flows to the Swift, Kotlin/JVM, .NET, C/C++, and WebAssembly wrappers, so a robotics credential signed in one language verifies in every other. Fifteen further capabilities round out the set: a living-trust heartbeat (a signed per-interval motion summary whose trust decays unless it is renewed in-envelope), two-level credential revocation (per-credential status lists and whole-DID kill), an accountable safety record (a tamper-evident incident ledger summarized into a portable signed record), signed perception provenance (each captured sensor frame's hash bound to the robot's key and hash-linked, so a robot can prove what its sensors saw and a substituted frame is detectable), an offline delegation lease (a short-lived, scope-bounded grant a disconnected robot verifies and acts on with no network call, nesting across vendors), a physical quorum (a cryptographic two-person rule requiring M of N attested approvers for a high-consequence action), lifecycle credentials (ownership transfer that chains into a verifiable chain of custody, key rotation that forms a key history, and a signed decommission that retires the robot), a regulatory conformance profile (a machine-checkable mapping from a robot's credentials to the clauses of ISO 10218 and 15066, the EU Machinery Regulation, the EU AI Act, and UL 3300, with a deterministic checker and a signed conformance attestation), post-quantum signing by default (robot credentials carry a proof set with an Ed25519 proof and an ML-DSA-44 proof, with backward-compatible verification, so a robot stays unforgeable across its decade-long life), and cross-embodiment identity continuity (an agent identity that moves between robot bodies, with an embodiment credential re-binding to each body's hardware root and a continuity chain that proves the same accountable agent persisted, plus a fork check), a physical custody handoff chain (a signed record of who accepted custody of a task or object at each hop across human and robot actors, so an incident traces to the exact hop and an attested condition localizes damage to the holder responsible), bounded infrastructure access (an operator-signed grant naming a resource, its permitted operations, an optional zone, and a time window, which a robot pairs with a signed request the resource authorizes offline, so a robot can open a door or dock at a charger with a tamper-evident, attributable, shrink-only record), fused-sensor provenance (a signed attestation binding a robot's fused world model to the exact set of input frame hashes and the fusion method that produced it, so a manipulated fusion result or a dropped input is detectable and every fused input traces to a frame the robot recorded), wear and degradation attestation (a robot signs its own wear level bound to its identity and hash-linked over time, and a deterministic rule narrows its physical capability scope as it degrades, so a worn robot operates inside a tighter, verifiable envelope than the static limit it shipped with), and bystander-consent evidence (a robot binds the basis for capturing people, an explicit token, posted notice, a legitimate interest, or a redaction it applied, to the capture itself by its hash, holding only hashes and never anyone's identifying data, and a bystander can sign consent bound to one capture so it cannot be replayed to another), implemented across the same languages and pinned by the shared interop vector. See [docs/robotics.md](docs/robotics.md) and the defensive disclosures PAD-064 through PAD-070, PAD-076 through PAD-084, and PAD-087 through PAD-094.
116
117
 
117
118
  ### Inside your AI tools
118
119
  - **Claude Skill**, **OpenAI Custom GPT**, and **Gemini Gem** packages that teach your AI assistant how to add Vouch to your code, running on your own AI subscription.
@@ -158,7 +159,7 @@ AI agents are making real-world API calls with **ZERO cryptographic proof** of:
158
159
  - **Data Integrity proofs** (`eddsa-jcs-2022` cryptosuite, no JOSE/JWS dependency)
159
160
  - **Decentralized Identifiers** (`did:web`, `did:key`)
160
161
  - **Multikey verification methods** (algorithm-agnostic, post-quantum ready)
161
- - **Hybrid post-quantum profile** (optional Ed25519 + ML-DSA-44 composite, `hybrid-eddsa-mldsa44-jcs-2026`)
162
+ - **Post-quantum profile** (optional proof set: `eddsa-jcs-2022` + `mldsa44-jcs-2024`)
162
163
  - **Human-readable JSON** (proof attaches as a sibling object, no Base64-wrapped opaque payload)
163
164
  - **Framework-agnostic** (works with MCP, LangChain, CrewAI, AutoGPT, AutoGen, Vertex AI)
164
165
  - **Cross-language interop** (Python, TypeScript, Go, byte-identical canonical form)
@@ -209,15 +210,15 @@ flowchart TB
209
210
  subgraph CRYPTO["Cryptographic Proof"]
210
211
  JCS["JCS canonicalization (RFC 8785)"]
211
212
  DEFAULT["eddsa-jcs-2022<br/>(Ed25519, default)"]
212
- HYBRID["hybrid-eddsa-mldsa44-jcs-2026<br/>(Ed25519 + ML-DSA-44, optional)"]
213
+ PQ["mldsa44-jcs-2024<br/>(ML-DSA-44, optional second proof)"]
213
214
  end
214
215
  IDENTITY --> FORMAT
215
216
  FORMAT --> CRYPTO
216
217
  JCS --> DEFAULT
217
- JCS --> HYBRID
218
+ JCS --> PQ
218
219
  ```
219
220
 
220
- **Trust = Verifiable Credentials + Data Integrity + Decentralized Identifiers + Multikey, with optional hybrid post-quantum signatures.** The same math that secures SSL/TLS, plus the standardized primitives that secure verifiable credentials elsewhere on the web, applied to AI agents.
221
+ **Trust = Verifiable Credentials + Data Integrity + Decentralized Identifiers + Multikey, with an optional post-quantum proof set.** The same math that secures SSL/TLS, plus the standardized primitives that secure verifiable credentials elsewhere on the web, applied to AI agents.
221
222
 
222
223
  ---
223
224
 
@@ -233,7 +234,7 @@ flowchart TB
233
234
  | **Audit trail format** | ✅ (VC standardized) | ❌ (custom) |
234
235
  | **standards-aligned** | ✅ (`eddsa-jcs-2022` Data Integrity) | ❌ |
235
236
  | **Multikey verification methods** | ✅ (algorithm-agnostic) | ❌ |
236
- | **Hybrid post-quantum signatures** | ✅ (`hybrid-eddsa-mldsa44-jcs-2026`) | ❌ |
237
+ | **Post-quantum signatures** | ✅ (`mldsa44-jcs-2024` proof set) | ❌ |
237
238
  | **Cross-implementation interop tests** | ✅ (Python, TypeScript, Go) | ❌ |
238
239
  | **Security best practices** | ✅ (built-in) | ⚠️ (easy to mess up) |
239
240
 
@@ -330,18 +331,19 @@ Works with all major AI frameworks out-of-the-box:
330
331
  - **Reputation Scoring**: track agent behavior over time
331
332
  - **Revocation Registry**: blacklist compromised keys
332
333
  - **Redis Caching**: production-scale verification
333
- - **Hybrid Post-Quantum Profile**: optional Ed25519 + ML-DSA-44 composite signatures (`hybrid-eddsa-mldsa44-jcs-2026`) for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 migration timelines
334
+ - **Post-Quantum Profile**: an optional proof set carrying an `eddsa-jcs-2022` proof and an `mldsa44-jcs-2024` proof for regulated deployments aligning with NIST CNSA 2.0 / NSM-10 migration timelines
334
335
 
335
- ### Hybrid Post-Quantum Example
336
+ ### Post-Quantum Example
336
337
 
337
338
  ```python
338
- # Optional v1.0 profile, requires `pip install pqcrypto`
339
+ # Optional profile, requires `pip install pqcrypto`
339
340
  credential = signer.sign_hybrid(intent={
340
341
  'action': 'submit_clinical_finding',
341
342
  'target': 'trial:NCT00000001',
342
343
  'resource': 'https://fda-submissions.example.com/api/findings',
343
344
  })
344
- # Carries both Ed25519 and ML-DSA-44 signatures over the same JCS canonical form.
345
+ # The credential's `proof` is an array of two independent Data Integrity proofs,
346
+ # eddsa-jcs-2022 and mldsa44-jcs-2024, over the same document.
345
347
  # Verification REQUIRES both to validate.
346
348
  ```
347
349
 
@@ -386,7 +388,7 @@ To keep this space free from patent capture, the project publishes **61 defensiv
386
388
 
387
389
  - [Quick Start](https://github.com/vouch-protocol/vouch#quick-start)
388
390
  - [Vouch Specification (v1.6 normative)](https://vouch-protocol.com/specs/)
389
- - [Hybrid Post-Quantum Implementation Guide](https://github.com/vouch-protocol/vouch/blob/main/docs/hybrid-pq-implementation-guide.md)
391
+ - [Post-Quantum Implementation Guide](https://github.com/vouch-protocol/vouch/blob/main/docs/hybrid-pq-implementation-guide.md)
390
392
  - [Protocol Specification (developer guide)](https://github.com/vouch-protocol/vouch/blob/main/docs/vouch_guide.md)
391
393
  - [Integration Guides](https://github.com/vouch-protocol/vouch/tree/main/vouch/integrations)
392
394
  - [Threat Model and Security Considerations](https://github.com/vouch-protocol/vouch/blob/main/docs/THREAT_MODEL.md)
@@ -409,7 +411,7 @@ To keep this space free from patent capture, the project publishes **61 defensiv
409
411
 
410
412
  - [x] **Verifiable Credentials + Data Integrity** (`eddsa-jcs-2022` cryptosuite)
411
413
  - [x] **Multikey verification methods** (algorithm-agnostic, multibase + multicodec)
412
- - [x] **Hybrid post-quantum profile** (`hybrid-eddsa-mldsa44-jcs-2026`, NIST CNSA 2.0 / NSM-10 aligned)
414
+ - [x] **Post-quantum profile** (`eddsa-jcs-2022` + `mldsa44-jcs-2024` proof set, NIST CNSA 2.0 / NSM-10 aligned)
413
415
  - [x] **Three-language reference implementation** (Python, TypeScript, Go) with byte-identical canonical form via RFC 8785 JCS, verified against shared test vectors
414
416
  - [x] **Specification drafted** and submitted to the open standards group for incubation
415
417
  - [x] **55 Prior Art Disclosures** (CC0 defensive publications)
@@ -471,7 +473,7 @@ Contributions welcome. See [CONTRIBUTING.md](https://github.com/vouch-protocol/v
471
473
 
472
474
  **Areas where help is most useful:**
473
475
  - [ ] Additional framework integrations (Haystack, Semantic Kernel, LlamaIndex, others)
474
- - [ ] Cross-implementation interop test vectors (additional edge cases for JCS, VC, hybrid PQ)
476
+ - [ ] Cross-implementation interop test vectors (additional edge cases for JCS, VC, post-quantum proof sets)
475
477
  - [ ] Tutorials and worked examples for regulated-sector deployments
476
478
  - [ ] Independent security review and audit
477
479
  - [ ] Reference implementations in additional languages (Rust, Java, .NET)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vouch-protocol"
7
- version = "2.0.1"
7
+ version = "2.1.0"
8
8
  description = "The Identity & Reputation Standard for AI Agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -32,8 +32,9 @@ dependencies = [
32
32
  "cryptography",
33
33
  "pydantic>=2.0.0",
34
34
  "httpx>=0.24.0",
35
- # Hybrid post-quantum profile (Specification 13.2; W3C-aligned cryptosuite
36
- # `hybrid-eddsa-mldsa44-jcs-2026`). Bundled by default: pqcrypto ships
35
+ # Post-quantum profile (Specification 13.2): a Data Integrity proof set,
36
+ # an `eddsa-jcs-2022` proof plus an `mldsa44-jcs-2024` proof on the same
37
+ # credential. Bundled by default: pqcrypto ships
37
38
  # prebuilt wheels for all mainstream platforms (~80 KB, no compiler needed)
38
39
  # and the PQ story is core to Vouch, so we do not gate it behind an extra.
39
40
  "pqcrypto>=0.4.0",
@@ -46,7 +47,9 @@ crewai = ["crewai>=0.1.0"]
46
47
  langgraph = ["langgraph>=0.1.0"]
47
48
  goose = ["pyyaml>=6.0"]
48
49
  autogen = ["pyautogen>=0.2.0"]
49
- mcp = ["mcp>=0.1.0"]
50
+ # mcp 1.2 is the first release with the FastMCP high-level API; the server
51
+ # also supports mcp 2.x (the 2026-07-28 stateless protocol revision).
52
+ mcp = ["mcp>=1.2.0"]
50
53
  vertex = ["google-cloud-aiplatform>=1.0.0"]
51
54
  streamlit = ["streamlit>=1.0.0"]
52
55
 
@@ -67,7 +70,7 @@ aws = ["aioboto3>=12.0.0"]
67
70
  gcp = ["google-cloud-kms>=2.0.0"]
68
71
  azure = ["azure-keyvault-keys>=4.0.0"]
69
72
 
70
- # Hybrid post-quantum profile is now bundled by default (see required
73
+ # The post-quantum profile is bundled by default (see required
71
74
  # `dependencies` above). The `pq` extra is retained as a no-op alias so
72
75
  # `pip install 'vouch-protocol[pq]'` keeps working for anyone who already
73
76
  # wrote that into a Dockerfile or requirements.txt.
@@ -93,6 +96,23 @@ media = [
93
96
  "c2pa-python>=0.5.0",
94
97
  ]
95
98
 
99
+ # Real vision-language-action model (OpenVLA, open weights) for
100
+ # examples/robotics_openvla_gated_loop.py. Heavy: torch plus a ~16 GB 7B
101
+ # checkpoint, so it is never installed by default and is deliberately left out
102
+ # of `all` -- CI exercises the example's skip path instead. transformers,
103
+ # tokenizers, and timm are pinned to the versions OpenVLA's model card
104
+ # specifies, because the checkpoint ships its own modelling code
105
+ # (trust_remote_code) that is written against exactly those APIs.
106
+ openvla = [
107
+ "torch>=2.2.0",
108
+ "transformers==4.40.1",
109
+ "tokenizers==0.19.1",
110
+ "timm==0.9.10",
111
+ "accelerate>=0.25.0",
112
+ "huggingface-hub>=0.23.0",
113
+ "Pillow>=10.0.0",
114
+ ]
115
+
96
116
  # Development dependencies
97
117
  dev = [
98
118
  "pytest>=7.0.0",
@@ -0,0 +1,302 @@
1
+ """
2
+ Tests for the portable identity bundle and the one-command enroll and
3
+ root-anchored verify flow.
4
+
5
+ Covers the library layer (build_identity_bundle + verify_bundle, happy path and
6
+ a wrong pinned root) and the CLI (`vouch agent enroll` produces a bundle that
7
+ `vouch agent verify` accepts against the correct root and rejects against a
8
+ wrong one). Everything runs offline with did:key identities and a temp keystore,
9
+ no network and no passphrase prompts.
10
+ """
11
+
12
+ import json
13
+ import types
14
+
15
+ import pytest
16
+
17
+ from vouch import cli
18
+ from vouch.keys import KeyManager
19
+ from vouch.signer import Signer
20
+ from vouch.root_of_trust import (
21
+ ACTION_ISSUE_AGENT_IDENTITY,
22
+ IDENTITY_BUNDLE_TYPE,
23
+ build_agent_identity,
24
+ build_identity_bundle,
25
+ build_recognized_issuer,
26
+ build_root_of_trust,
27
+ generate_did_key_identity,
28
+ verify_bundle,
29
+ )
30
+
31
+
32
+ def _signer():
33
+ """A fresh did:key signer."""
34
+ return Signer.from_keypair(generate_did_key_identity())
35
+
36
+
37
+ def _read(path):
38
+ with open(path, "r") as f:
39
+ return json.load(f)
40
+
41
+
42
+ @pytest.fixture
43
+ def temp_keystore(tmp_path, monkeypatch):
44
+ """Point KeyManager at a temp directory for the duration of a test."""
45
+ key_dir = str(tmp_path / "keys")
46
+ orig_init = KeyManager.__init__
47
+ monkeypatch.setattr(
48
+ KeyManager, "__init__", lambda self, key_dir=key_dir: orig_init(self, key_dir)
49
+ )
50
+ return tmp_path
51
+
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # Library: build_identity_bundle + verify_bundle
55
+ # ---------------------------------------------------------------------------
56
+
57
+
58
+ def test_bundle_happy_path():
59
+ """Root recognizes issuer, issuer attests agent, bundle verifies to root."""
60
+ root = _signer()
61
+ issuer = _signer()
62
+ agent = _signer()
63
+
64
+ root_cred = build_root_of_trust(root, name="Vouch Machine Identity Root")
65
+ recognition = build_recognized_issuer(
66
+ root, issuer_did=issuer.did, recognized_actions=[ACTION_ISSUE_AGENT_IDENTITY]
67
+ )
68
+ identity = build_agent_identity(
69
+ issuer,
70
+ subject_did=agent.did,
71
+ attributes={"owner": "Acme", "model": "gpt-x", "capabilityClass": "shopping"},
72
+ )
73
+ action = agent.sign(
74
+ intent={"action": "buy", "target": "store", "resource": "https://store.example/item/1"}
75
+ )
76
+
77
+ bundle = build_identity_bundle(
78
+ identity=identity, recognition=recognition, action=action, root=root_cred
79
+ )
80
+ assert bundle["type"] == IDENTITY_BUNDLE_TYPE
81
+ assert bundle["vouchVersion"] == "1.0"
82
+ assert bundle["identity"] == identity
83
+ assert bundle["recognizedIssuer"] == recognition
84
+ assert bundle["action"] == action
85
+ assert bundle["root"] == root_cred
86
+
87
+ result = verify_bundle(bundle, trusted_root=root.did)
88
+ assert result.ok
89
+ assert result.agent_did == agent.did
90
+ assert result.issuer_did == issuer.did
91
+ assert result.root_did == root.did
92
+ assert result.attributes == {
93
+ "owner": "Acme",
94
+ "model": "gpt-x",
95
+ "capabilityClass": "shopping",
96
+ }
97
+ assert result.action is not None
98
+
99
+
100
+ def test_bundle_omits_optional_keys_when_none():
101
+ root = _signer()
102
+ issuer = _signer()
103
+ agent = _signer()
104
+ recognition = build_recognized_issuer(root, issuer_did=issuer.did)
105
+ identity = build_agent_identity(issuer, subject_did=agent.did, attributes={"owner": "Acme"})
106
+
107
+ bundle = build_identity_bundle(identity=identity, recognition=recognition)
108
+ assert "action" not in bundle
109
+ assert "root" not in bundle
110
+ assert verify_bundle(bundle, trusted_root=root.did).ok
111
+
112
+
113
+ def test_bundle_wrong_root_rejected():
114
+ """A bundle pinned to a root the verifier does not trust is rejected."""
115
+ root = _signer()
116
+ issuer = _signer()
117
+ agent = _signer()
118
+ recognition = build_recognized_issuer(root, issuer_did=issuer.did)
119
+ identity = build_agent_identity(issuer, subject_did=agent.did, attributes={"owner": "Acme"})
120
+ bundle = build_identity_bundle(identity=identity, recognition=recognition)
121
+
122
+ wrong_root = _signer()
123
+ result = verify_bundle(bundle, trusted_root=wrong_root.did)
124
+ assert not result.ok
125
+ assert result.reason == "recognized_issuer_not_from_root"
126
+
127
+
128
+ def test_verify_bundle_malformed():
129
+ assert verify_bundle({}, trusted_root="did:key:zabc").reason == "bad_bundle"
130
+ assert verify_bundle("nope", trusted_root="did:key:zabc").reason == "bad_bundle"
131
+ assert (
132
+ verify_bundle(
133
+ {"type": IDENTITY_BUNDLE_TYPE, "identity": 1, "recognizedIssuer": {}},
134
+ trusted_root="did:key:zabc",
135
+ ).reason
136
+ == "bad_bundle"
137
+ )
138
+
139
+
140
+ # ---------------------------------------------------------------------------
141
+ # CLI: agent enroll -> agent verify
142
+ # ---------------------------------------------------------------------------
143
+
144
+
145
+ def _init_root(temp_keystore, out_name, capsys):
146
+ """Mint a did:key identity via `root init` and return its DID."""
147
+ out = str(temp_keystore / out_name)
148
+ assert (
149
+ cli.cmd_root_init(
150
+ types.SimpleNamespace(
151
+ name="Root", scope=None, domain=None, out=out, reference=False, yes=True
152
+ )
153
+ )
154
+ == 0
155
+ )
156
+ capsys.readouterr()
157
+ return _read(out)["issuer"]
158
+
159
+
160
+ def test_cli_enroll_and_verify(temp_keystore, capsys):
161
+ # Root and issuer identities (both stored in the temp keystore).
162
+ root_did = _init_root(temp_keystore, "root.json", capsys)
163
+ issuer_did = _init_root(temp_keystore, "issuer.json", capsys)
164
+
165
+ # Root recognizes the issuer.
166
+ recognition_out = str(temp_keystore / "recognition.json")
167
+ assert (
168
+ cli.cmd_root_recognize(
169
+ types.SimpleNamespace(
170
+ issuer=issuer_did, actions=None, root_did=root_did, out=recognition_out
171
+ )
172
+ )
173
+ == 0
174
+ )
175
+ capsys.readouterr()
176
+
177
+ # Enroll an agent: generate a fresh agent DID, attest it, write the bundle.
178
+ bundle_out = str(temp_keystore / "identity-bundle.json")
179
+ rc = cli.cmd_agent_enroll(
180
+ types.SimpleNamespace(
181
+ agent_did=None,
182
+ issuer_did=issuer_did,
183
+ attr=["owner=Acme", "model=gpt-x"],
184
+ recognition=recognition_out,
185
+ action=None,
186
+ out=bundle_out,
187
+ yes=True,
188
+ )
189
+ )
190
+ assert rc == 0
191
+ out = capsys.readouterr().out
192
+ assert "Agent enrolled" in out
193
+ assert "Generated agent identity:" in out
194
+
195
+ bundle = _read(bundle_out)
196
+ assert bundle["type"] == IDENTITY_BUNDLE_TYPE
197
+ agent_did = bundle["identity"]["credentialSubject"]["id"]
198
+ assert bundle["identity"]["issuer"] == issuer_did
199
+
200
+ # Verify the bundle against the correct root.
201
+ rc = cli.cmd_agent_verify(
202
+ types.SimpleNamespace(
203
+ bundle=bundle_out, root=root_did, action_required="issueAgentIdentity"
204
+ )
205
+ )
206
+ assert rc == 0
207
+ out = capsys.readouterr().out
208
+ assert "Identity bundle verified" in out
209
+ assert agent_did in out
210
+ assert issuer_did in out
211
+ assert "Acme" in out
212
+
213
+ # Verify against a WRONG root: non-zero exit and a clear reason on stderr.
214
+ rc = cli.cmd_agent_verify(
215
+ types.SimpleNamespace(
216
+ bundle=bundle_out,
217
+ root="did:key:z6MkNotTheRealRootDidPinnedByAnHonestVerifier00",
218
+ action_required="issueAgentIdentity",
219
+ )
220
+ )
221
+ assert rc == 1
222
+ err = capsys.readouterr().err
223
+ assert "rejected" in err.lower()
224
+ assert "recognized_issuer_not_from_root" in err
225
+
226
+
227
+ def test_cli_enroll_verify_via_main(temp_keystore):
228
+ """Drive the flow through cli.main with argv lists, including a supplied DID."""
229
+ root_out = str(temp_keystore / "r.json")
230
+ issuer_out = str(temp_keystore / "i.json")
231
+ recognition_out = str(temp_keystore / "rec.json")
232
+ bundle_out = str(temp_keystore / "bundle.json")
233
+
234
+ assert cli.main(["root", "init", "--yes", "--out", root_out]) == 0
235
+ assert cli.main(["root", "init", "--yes", "--out", issuer_out]) == 0
236
+ root_did = _read(root_out)["issuer"]
237
+ issuer_did = _read(issuer_out)["issuer"]
238
+
239
+ assert (
240
+ cli.main(
241
+ [
242
+ "root",
243
+ "recognize",
244
+ "--issuer",
245
+ issuer_did,
246
+ "--root-did",
247
+ root_did,
248
+ "--out",
249
+ recognition_out,
250
+ ]
251
+ )
252
+ == 0
253
+ )
254
+
255
+ agent_did = "did:key:z6MkagentSubjectPlaceholderDidForTest000000000000"
256
+ assert (
257
+ cli.main(
258
+ [
259
+ "agent",
260
+ "enroll",
261
+ "--agent-did",
262
+ agent_did,
263
+ "--issuer-did",
264
+ issuer_did,
265
+ "--attr",
266
+ "owner=Acme",
267
+ "--recognition",
268
+ recognition_out,
269
+ "--out",
270
+ bundle_out,
271
+ ]
272
+ )
273
+ == 0
274
+ )
275
+ assert _read(bundle_out)["identity"]["credentialSubject"]["id"] == agent_did
276
+
277
+ # Correct root via --root.
278
+ assert cli.main(["agent", "verify", "--bundle", bundle_out, "--root", root_did]) == 0
279
+
280
+ # Root supplied through the VOUCH_TRUSTED_ROOT env var (no --root).
281
+ import os
282
+
283
+ os.environ["VOUCH_TRUSTED_ROOT"] = root_did
284
+ try:
285
+ assert cli.main(["agent", "verify", "--bundle", bundle_out]) == 0
286
+ finally:
287
+ del os.environ["VOUCH_TRUSTED_ROOT"]
288
+
289
+ # Wrong root: non-zero.
290
+ assert (
291
+ cli.main(
292
+ [
293
+ "agent",
294
+ "verify",
295
+ "--bundle",
296
+ bundle_out,
297
+ "--root",
298
+ "did:key:z6MkWrongRoot000000000000000000000000000000000000",
299
+ ]
300
+ )
301
+ == 1
302
+ )