Skip to content

feat: add agent_key_thumbprint scaffold to gateway.agent_identity - #474

Open
qubeena07 wants to merge 1 commit into
agentrust-io:mainfrom
qubeena07:feat/agent-key-thumbprint-scaffold
Open

feat: add agent_key_thumbprint scaffold to gateway.agent_identity#474
qubeena07 wants to merge 1 commit into
agentrust-io:mainfrom
qubeena07:feat/agent-key-thumbprint-scaffold

Conversation

@qubeena07

Copy link
Copy Markdown
Contributor

Summary

Closes #425.

SAGE wanted an offline check that a downstream signature came from the agent a TRACE Claim describes. Digging into it turned up that the issue's own premise does not hold on current code: the Agent Manifest binding carries no agent public key anywhere, and subject_source is a static config value today, not a live authenticated credential. There is no key material anywhere in the runtime to hash yet. This was confirmed and worked through together with the issue author in the comment thread, who agreed to the approach below.

Landed as a nullable, additive field instead. agent_key_thumbprint, an RFC 7638 JWK thumbprint rendered as sha256 hex, sits on AgentIdentityInfo and AgentIdentityOut and stays None today since no code path supplies agent key bytes.

The real behavior change is on the verifier side. verify_trace_claim now fails closed with AGENT_KEY_THUMBPRINT_UNBOUND_SUBJECT on any claim that carries the field while subject_source is not live authenticated, so a future producer cannot launder a config supplied identity into what looks like a hardware attested key binding. This check is unconditional, it runs whether or not the caller requests the existing agent manifest cross check.

Populating the field for real needs either an agent_manifest_sdk schema change carrying the agent's public key, or a live mTLS or challenge response credential wired into the binding. Both are out of scope here and stay tracked in the issue thread.

Changes

  • src/cmcp_runtime/audit/trace_claim.py: agent_key_thumbprint added to AgentIdentityInfo and AgentIdentityOut, threaded through generate_trace_claim.
  • src/cmcp_runtime/session/manager.py: pointer comment only, no behavior change, the field is not wired in yet.
  • src/cmcp_verify/verify.py: new AGENT_KEY_THUMBPRINT_UNBOUND_SUBJECT error and the subject binding check described above.
  • docs/spec/session-policy.md, docs/spec/verification-library.md, CHANGELOG.md: document the field and the verifier rule.
  • tests/unit/test_trace_claim.py, tests/unit/test_session_manager.py, tests/unit/test_verify.py: schema round trip, current always None invariant, and the three verifier cases (live authenticated passes, config sourced fails closed, absent field unaffected).

Test plan

  • pytest tests/unit/ passes locally, 931 passed, 7 skipped
  • ruff check src/ tests/ clean
  • mypy src/cmcp_runtime/ src/cmcp_verify/ clean
  • bandit -r src/ clean

Closes agentrust-io#425. SAGE wanted an offline check that a downstream signature came from the agent a TRACE Claim describes. Investigating turned up that the issue's own premise did not hold on current code: the Agent Manifest binding carries no agent public key anywhere, and subject_source is a static config value today, not a live authenticated credential. There is no key material anywhere in the runtime to hash yet, confirmed and refined together with the issue author in the comment thread.

Landed as a nullable, additive field instead. agent_key_thumbprint, an RFC 7638 JWK thumbprint rendered as sha256 hex, sits on AgentIdentityInfo and AgentIdentityOut and stays None today since no code path supplies agent key bytes. The real behavior change is on the verifier side: verify_trace_claim now fails closed with AGENT_KEY_THUMBPRINT_UNBOUND_SUBJECT on any claim that carries the field while subject_source is not live authenticated, so a future producer cannot launder a config supplied identity into what looks like a hardware attested key binding.

Populating the field for real needs either an agent_manifest_sdk schema change carrying the agent's public key, or a live mTLS or challenge response credential wired into the binding. Both are out of scope here and tracked in the issue thread.

Signed-off-by: Dipika Ranabhat <qubeena7@gmail.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.

Carry the agent's key thumbprint in gateway.agent_identity

1 participant