You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The industrial-embodied-ai example (agentrust-io/examples#16, refined in #18
and #27) documents this under "Evidence boundaries": the Agent Manifest declares
a signed agent identity and the approved prompt, policy and tool hashes, but the
current preview does not bind that identity to the runtime session. The README
states it plainly: the current preview does not cryptographically bind that
manifest identity to the runtime session.
This is the identity member of the same binding family as #301 (independent
controller evidence) and #126 (tool transcript). #301 binds what the controller
did. #126 binds what tools were called. This issue binds who acted.
The gap
The committed Trust Record makes it concrete:
trace.subject is spiffe://cmcp.gateway/session/<uuid>, described in
trace-claim.schema.json as "SPIFFE URI identifying the gateway session".
The Agent Manifest agent_id is spiffe://factory.example/agent/material-movement/dev, signed together with
the prompt, policy and tool hashes.
Nothing links the two. cMCP loads the policy bundle and catalog by hash, so an
offline check can confirm the loaded hashes match the manifest's bound hashes.
But cMCP never ingests the manifest, never checks that the identity acting in the
session is the manifest's agent_id, and the Trust Record carries no agent
identity at all, only the session. Verification therefore proves that some
session ran an approved policy and catalog. It does not prove that the agent the
operator reviewed is the agent that acted.
Why this matters for embodied agents
Embodied agents restart, get redeployed, and get replaced. Identity persistence,
proof that the agent that acted is exactly the one that was reviewed, down to its
prompt, policy and tools, is the property that survives those restarts. Without
the binding, an operator can run a different agent (a different system prompt, a
different planner, a different identity) under the same approved policy and
catalog, and the evidence chain will not register the substitution. Permission
and policy hashes are pinned; the actor is not. For a system that moves
machinery, who actually drove this session is not a detail.
Both identities are already SPIFFE URIs, so the binding has a natural spine, and
cMCP already issues SVIDs conditioned on TEE attestation (#96).
Proposed direction
Option A, bind at the gateway. At session create, cMCP ingests the signed
Agent Manifest, verifies the issuer signature against a configured trust
anchor, checks that the session's authenticated subject (the agent SVID from [tee] SPIFFE/SPIRE integration — SVID issuance conditioned on TEE attestation #96) matches manifest.agent_id, and checks that the loaded policy bundle and
catalog hashes equal the manifest's bound hashes. The Trust Record then carries
the manifest_id and the bound agent_id alongside the session subject, and
the verifier asserts the binding. Strongest option, and it reuses the SPIFFE
path already in place.
Option B, bind at verification only. Keep manifest ingestion out of the
gateway and have the verifier cross-check the offline manifest against the
Trust Record: session subject consistent with manifest.agent_id, hashes in
agreement. Lighter, but it only detects a mismatch after the fact and cannot
refuse a mismatched run at the boundary.
Option C, status quo, documented as permanent. Rejected: identity persistence
is a core property of the trust model, and leaving it undefined invites readers
to treat a signed manifest as proof of who acted, which it is not today.
Recommendation: Option A as the binding spine, with the Option B verifier check
kept as defense in depth so offline evidence is self-checking.
Scope for a first iteration
Manifest ingestion at session create, with issuer signature verification
against a configured trust anchor.
Subject-to-agent_id binding check (SVID equals manifest.agent_id), plus
policy bundle and catalog hash agreement with the manifest, default deny on
mismatch.
Carry manifest_id and the bound agent_id into the Trust Record, and have
cmcp-verify assert the binding.
Conformance tests: a matching manifest binds and verifies; a mismatched
agent_id, a tampered manifest signature, and a policy or catalog hash drift
each fail closed.
Update LIMITATIONS.md and the session and trace-claim spec to state exactly
what the binding does and does not prove.
Update the industrial-embodied-ai example to show the bound case. This needs
the committed signed evidence regenerated from a live run, the same capture
step flagged in examples#27.
Coordinate the canonical manifest shape and signed_fields with the
agent-manifest SDK (agentrust-io/agent-manifest).
Non-goals
This binds identity, not behavior. It does not establish that the reviewed
agent behaved well, only that the reviewed agent is the one that acted.
It does not, by itself, prove logical-agent continuity across restarts or
replacements. Binding a session to its reviewed manifest is the prerequisite;
reputation and continuity across sessions are separate work.
Context
The industrial-embodied-ai example (agentrust-io/examples#16, refined in #18
and #27) documents this under "Evidence boundaries": the Agent Manifest declares
a signed agent identity and the approved prompt, policy and tool hashes, but the
current preview does not bind that identity to the runtime session. The README
states it plainly: the current preview does not cryptographically bind that
manifest identity to the runtime session.
This is the identity member of the same binding family as #301 (independent
controller evidence) and #126 (tool transcript). #301 binds what the controller
did. #126 binds what tools were called. This issue binds who acted.
The gap
The committed Trust Record makes it concrete:
trace.subjectisspiffe://cmcp.gateway/session/<uuid>, described intrace-claim.schema.json as "SPIFFE URI identifying the gateway session".
agent_idisspiffe://factory.example/agent/material-movement/dev, signed together withthe prompt, policy and tool hashes.
Nothing links the two. cMCP loads the policy bundle and catalog by hash, so an
offline check can confirm the loaded hashes match the manifest's bound hashes.
But cMCP never ingests the manifest, never checks that the identity acting in the
session is the manifest's
agent_id, and the Trust Record carries no agentidentity at all, only the session. Verification therefore proves that some
session ran an approved policy and catalog. It does not prove that the agent the
operator reviewed is the agent that acted.
Why this matters for embodied agents
Embodied agents restart, get redeployed, and get replaced. Identity persistence,
proof that the agent that acted is exactly the one that was reviewed, down to its
prompt, policy and tools, is the property that survives those restarts. Without
the binding, an operator can run a different agent (a different system prompt, a
different planner, a different identity) under the same approved policy and
catalog, and the evidence chain will not register the substitution. Permission
and policy hashes are pinned; the actor is not. For a system that moves
machinery, who actually drove this session is not a detail.
Both identities are already SPIFFE URIs, so the binding has a natural spine, and
cMCP already issues SVIDs conditioned on TEE attestation (#96).
Proposed direction
Agent Manifest, verifies the issuer signature against a configured trust
anchor, checks that the session's authenticated subject (the agent SVID from
[tee] SPIFFE/SPIRE integration — SVID issuance conditioned on TEE attestation #96) matches
manifest.agent_id, and checks that the loaded policy bundle andcatalog hashes equal the manifest's bound hashes. The Trust Record then carries
the
manifest_idand the boundagent_idalongside the session subject, andthe verifier asserts the binding. Strongest option, and it reuses the SPIFFE
path already in place.
gateway and have the verifier cross-check the offline manifest against the
Trust Record: session subject consistent with
manifest.agent_id, hashes inagreement. Lighter, but it only detects a mismatch after the fact and cannot
refuse a mismatched run at the boundary.
is a core property of the trust model, and leaving it undefined invites readers
to treat a signed manifest as proof of who acted, which it is not today.
Recommendation: Option A as the binding spine, with the Option B verifier check
kept as defense in depth so offline evidence is self-checking.
Scope for a first iteration
against a configured trust anchor.
manifest.agent_id), pluspolicy bundle and catalog hash agreement with the manifest, default deny on
mismatch.
manifest_idand the boundagent_idinto the Trust Record, and havecmcp-verify assert the binding.
agent_id, a tampered manifest signature, and a policy or catalog hash drift
each fail closed.
what the binding does and does not prove.
the committed signed evidence regenerated from a live run, the same capture
step flagged in examples#27.
agent-manifest SDK (agentrust-io/agent-manifest).
Non-goals
agent behaved well, only that the reviewed agent is the one that acted.
replacements. Binding a session to its reviewed manifest is the prerequisite;
reputation and continuity across sessions are separate work.
transcript). The three bind different facts: who acted, what tools ran, and
what the controller did.
I am happy to own this end to end (spec text, gateway change, conformance tests,
and the example update), in a personal capacity.