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(signature)>"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.
Production deployments set A2A_GRANT_SIGNING_KEY only on trusted
platform components and A2A_GRANT_VERIFYING_KEY on agents that need to
verify grants. Grants are Ed25519-only.
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, write_prefixes: tuple[str, ...] = (), llm_models: tuple[str, ...] = (), llm_max_budget_usd: Optional[Annotated[float, Ge(ge=0)]] = None, llm_rpm_limit: Optional[Annotated[int, Gt(gt=0)]] = None, llm_tpm_limit: Optional[Annotated[int, Gt(gt=0)]] = None, source_grants: tuple[a2a_pack.grants.SourceGrant, ...] = (), parent_grant_id: str | None = None, delegation_depth: typing.Annotated[int, Ge(ge=0)] = 0, max_delegation_depth: typing.Annotated[int, Gt(gt=0)] = 40, 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.
GrantDelegationDenied (class)
Raised when a child grant would exceed its parent grant.
GrantInvalid (class)
Raised by :func:verify_grant when a grant is bad/expired/forged.
SourceGrant (class)
SourceGrant(*, agent: str, scope: Literal['read', 'write'] = 'read') -> NoneSource repository access carried by a workspace grant.
delegate_grant (function)
delegate_grant(parent: 'Grant', *, issuer: 'str', audience: 'str', bucket: 'str | None' = None, mode: 'WorkspaceMode' = <WorkspaceMode.READ_ONLY: 'read_only'>, allow_patterns: 'tuple[str, ...]' = ('**',), deny_patterns: 'tuple[str, ...]' = (), outputs_prefix: 'str | None' = None, write_prefixes: 'tuple[str, ...]' = (), llm_models: 'tuple[str, ...]' = (), llm_max_budget_usd: 'float | None' = None, llm_rpm_limit: 'int | None' = None, llm_tpm_limit: 'int | None' = None, source_grants: 'tuple[SourceGrant | dict[str, Any], ...]' = (), ttl_seconds: 'int' = 300) -> 'tuple[Grant, str]'Mint a child grant that is mechanically bounded by parent.
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, write_prefixes: 'tuple[str, ...]' = (), llm_models: 'tuple[str, ...]' = (), llm_max_budget_usd: 'float | None' = None, llm_rpm_limit: 'int | None' = None, llm_tpm_limit: 'int | None' = None, source_grants: 'tuple[SourceGrant | dict[str, Any], ...]' = (), parent_grant_id: 'str | None' = None, delegation_depth: 'int' = 0, max_delegation_depth: 'int' = 40, ttl_seconds: 'int' = 300) -> 'tuple[Grant, str]'Build a :class:Grant and return it together with its signed token.
sign_grant (function)
sign_grant(grant: 'Grant') -> 'str'(no docstring)
verify_grant (function)
verify_grant(token: 'str') -> '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