Skip to content

[FEATURE]: Typestate wrappers for A2A runtime trust-boundary types #4233

@jonpspri

Description

@jonpspri

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.rsSessionRecord, SessionManager::lookup, validate_fingerprint
  • crates/a2a_runtime/src/trust.rsencode_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

  • Compile-time rejection of code paths that consume auth_context
    before fingerprint validation.
  • All existing tests in crates/a2a_runtime/ continue to pass.
  • A new test demonstrates that a naive misuse (consuming
    auth_context without validate_fingerprint) fails to compile
    (can be verified via a compile_fail doctest).
  • No behavior change observable from the Python side.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    a2aSupport for A2A protocolenhancementNew feature or requestrustRust programmingsecurityImproves securitytriageIssues / Features awaiting triage

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions