Context
Surfaced during the PR #3704 review pass on the new Rust A2A runtime. The
SessionRecord.auth_context field (and its downstream consumers in the
trust-header path) is typed as serde_json::Value, which makes it impossible
to encode invariants at the type level — any caller can pull the
auth_context out of a SessionRecord and encode it into a trust header
without having first called validate_fingerprint.
Current code is defense-in-depth correct: in server.rs::handle_a2a_invoke,
fingerprint validation is always called before auth_context is consumed.
But nothing on the type signature of SessionRecord::auth_context enforces
this — a future refactor could drop the check and compile cleanly.
Scope
Introduce typestate wrappers so the compiler rejects trust-boundary misuse:
struct Authenticated<T>(T) — marker that a Python /authenticate
round-trip has completed.
struct FingerprintValidated<T>(T) — marker that
validate_fingerprint returned true.
SessionRecord internals shift from raw serde_json::Value for
auth_context to a newtype (AuthContext) that can only be consumed via
methods returning Authenticated<&serde_json::Value> or
FingerprintValidated<&serde_json::Value>.
trust::encode_auth_context takes Authenticated<&serde_json::Value> (or
a stricter variant) rather than a bare &serde_json::Value.
Files touched by this refactor
crates/a2a_runtime/src/session.rs — SessionRecord, SessionManager::lookup, validate_fingerprint
crates/a2a_runtime/src/trust.rs — encode_auth_context, authorize, authenticate
crates/a2a_runtime/src/server.rs — call sites in handle_a2a_invoke,
proxy_task_method, proxy_push_method, proxy_agent_card,
resolve_agent
Why deferred from PR #3704
This is a design-level refactor with a wide blast radius. Every call site
that threads auth_context through the trust layer needs updating, and the
API of SessionRecord changes visibly. Better handled as its own
coordinated change with migration notes rather than mixed into the PR that
introduced the Rust runtime.
Acceptance criteria
References
Context
Surfaced during the PR #3704 review pass on the new Rust A2A runtime. The
SessionRecord.auth_contextfield (and its downstream consumers in thetrust-header path) is typed as
serde_json::Value, which makes it impossibleto encode invariants at the type level — any caller can pull the
auth_contextout of aSessionRecordand encode it into a trust headerwithout having first called
validate_fingerprint.Current code is defense-in-depth correct: in
server.rs::handle_a2a_invoke,fingerprint validation is always called before
auth_contextis consumed.But nothing on the type signature of
SessionRecord::auth_contextenforcesthis — a future refactor could drop the check and compile cleanly.
Scope
Introduce typestate wrappers so the compiler rejects trust-boundary misuse:
struct Authenticated<T>(T)— marker that a Python/authenticateround-trip has completed.
struct FingerprintValidated<T>(T)— marker thatvalidate_fingerprintreturnedtrue.SessionRecordinternals shift from rawserde_json::Valueforauth_contextto a newtype (AuthContext) that can only be consumed viamethods returning
Authenticated<&serde_json::Value>orFingerprintValidated<&serde_json::Value>.trust::encode_auth_contexttakesAuthenticated<&serde_json::Value>(ora stricter variant) rather than a bare
&serde_json::Value.Files touched by this refactor
crates/a2a_runtime/src/session.rs—SessionRecord,SessionManager::lookup,validate_fingerprintcrates/a2a_runtime/src/trust.rs—encode_auth_context,authorize,authenticatecrates/a2a_runtime/src/server.rs— call sites inhandle_a2a_invoke,proxy_task_method,proxy_push_method,proxy_agent_card,resolve_agentWhy deferred from PR #3704
This is a design-level refactor with a wide blast radius. Every call site
that threads
auth_contextthrough the trust layer needs updating, and theAPI of
SessionRecordchanges visibly. Better handled as its owncoordinated change with migration notes rather than mixed into the PR that
introduced the Rust runtime.
Acceptance criteria
auth_contextbefore fingerprint validation.
crates/a2a_runtime/continue to pass.auth_contextwithoutvalidate_fingerprint) fails to compile(can be verified via a
compile_faildoctest).References
type-design-analyzerduring PR feat: add Rust A2A 1.0 runtime support #3704 reviewcrates/a2a_runtime/src/session.rs:29,crates/a2a_runtime/src/trust.rs:83