a2a_pack.grants
Signed grant tokens for cross-agent workspace handoff.
A grant is a small, self-contained, signed claim issued by one agent that the platform (or the receiving agent) can verify without a registry round-trip.
Wire format::
"<base64url(json(payload))>.<base64url(hmac_sha256(secret, payload))>"The payload describes what the callee is allowed to do, whose workspace
they can see, and for how long. The runtime on the receiving side
materializes a :class:WorkspaceClient scoped to that grant.
Auth model is intentionally simple for v1: a shared platform secret signs every grant. Swap for asymmetric (X.509 / JWKS) when crossing trust domains.
Grant (class)
Grant(*, grant_id: str, issuer: str, audience: str, bucket: str, mode: a2a_pack.workspace.WorkspaceMode = <WorkspaceMode.READ_ONLY: 'read_only'>, allow_patterns: tuple[str, ...] = ('**',), deny_patterns: tuple[str, ...] = (), outputs_prefix: str | None = None, expires_at: typing.Annotated[int, Ge(ge=0)] = 0, issued_at: typing.Annotated[int, Ge(ge=0)] = 0, nonce: str = <factory>) -> NoneThe payload of a signed grant token.
A grant binds who (issuer) gave whom (audience) access to which workspace files (bucket + allow/deny patterns) under what mode and how long. The runtime enforces every line of this payload.
GrantInvalid (class)
Raised by :func:verify_grant when a grant is bad/expired/forged.
mint_grant (function)
mint_grant(*, issuer: 'str', audience: 'str', bucket: 'str', mode: 'WorkspaceMode' = <WorkspaceMode.READ_ONLY: 'read_only'>, allow_patterns: 'tuple[str, ...]' = ('**',), deny_patterns: 'tuple[str, ...]' = (), outputs_prefix: 'str | None' = None, ttl_seconds: 'int' = 300, secret: 'bytes | None' = None) -> 'tuple[Grant, str]'Build a :class:Grant and return it together with its signed token.
sign_grant (function)
sign_grant(grant: 'Grant', *, secret: 'bytes | None' = None) -> 'str'(no docstring)
verify_grant (function)
verify_grant(token: 'str', *, secret: 'bytes | None' = None) -> 'Grant'Parse + verify token. Raises :class:GrantInvalid on any failure.
Checks signature, expiry, and minimal structural shape. Caller-specific audience checks are layered on top by the server adapter.
Source: apps/a2a/a2a_pack/grants.py