Streaming & Asynchronous Operations in A2A¶
The Agent2Agent (A2A) protocol is designed to handle tasks that may not complete immediately. Many AI-driven operations can be long-running, involve multiple steps, produce incremental results, or require human intervention. A2A provides robust mechanisms for managing such asynchronous interactions, ensuring that clients can receive updates effectively, whether they remain continuously connected or operate in a more disconnected fashion.
1. Streaming with Server-Sent Events (SSE)¶
For tasks that produce incremental results (like generating a long document or streaming media) or provide ongoing status updates, A2A supports real-time communication using Server-Sent Events (SSE). This is ideal when the client can maintain an active HTTP connection with the A2A Server.
Key Characteristics:
- Initiation: The client uses the
tasks/sendSubscribe
RPC method to send an initial message (e.g., a prompt or command) and simultaneously subscribe to updates for that task. - Server Capability: The A2A Server must indicate its support for streaming by setting
capabilities.streaming: true
in its Agent Card. - Server Response (Connection): If the subscription is successful, the server responds with an HTTP
200 OK
status and aContent-Type: text/event-stream
. This HTTP connection remains open for the server to push events. - Event Structure: The server sends events over this stream. Each event's
data
field contains a JSON-RPC 2.0 Response object, specifically aSendTaskStreamingResponse
. Theid
in this JSON-RPC response matches theid
from the client's originaltasks/sendSubscribe
request. - Event Types (within
SendTaskStreamingResponse.result
):TaskStatusUpdateEvent
: Communicates changes in the task's lifecycle state (e.g., fromworking
toinput-required
orcompleted
). It can also provide intermediate messages from the agent (e.g., "I'm currently analyzing the data...").TaskArtifactUpdateEvent
: Delivers new or updated Artifacts generated by the task. This is used to stream large files or data structures in chunks. TheArtifact
object itself contains fields likeindex
,append
, andlastChunk
to help the client reassemble the complete artifact.
- Stream Termination: The server signals the end of updates for a particular interaction cycle (i.e., for the current
tasks/sendSubscribe
request) by settingfinal: true
in aTaskStatusUpdateEvent
. This typically occurs when the task reaches a terminal state (completed
,failed
,canceled
) or aninput-required
state (where the server expects further input from the client). After sending afinal: true
event, the server usually closes the SSE connection for that specific request. - Resubscription: If a client's SSE connection breaks prematurely while a task is still active (and the server hasn't sent a
final: true
event for that phase), the client can attempt to reconnect to the stream using thetasks/resubscribe
RPC method. The server's behavior regarding missed events during the disconnection period (e.g., whether it backfills or only sends new updates) is implementation-dependent.
When to Use Streaming:
- Real-time progress monitoring of long-running tasks.
- Receiving large results (artifacts) incrementally, allowing processing to begin before the entire result is available.
- Interactive, conversational exchanges where immediate feedback or partial responses are beneficial.
- Applications requiring low-latency updates from the agent.
Refer to the Protocol Specification for detailed structures:
2. Push Notifications for Disconnected Scenarios¶
For very long-running tasks (e.g., lasting minutes, hours, or even days) or when clients cannot or prefer not to maintain persistent connections (like mobile clients or serverless functions), A2A supports asynchronous updates via push notifications. This mechanism allows the A2A Server to actively notify a client-provided webhook when a significant task update occurs.
Key Characteristics:
- Server Capability: The A2A Server must indicate its support for this feature by setting
capabilities.pushNotifications: true
in its Agent Card. - Configuration: The client provides a
PushNotificationConfig
to the server. This configuration can be supplied:- Within the initial
tasks/send
ortasks/sendSubscribe
request (via the optionalpushNotification
parameter inTaskSendParams
). - Separately, using the
tasks/pushNotification/set
RPC method for an existing task. ThePushNotificationConfig
includes: url
: The absolute HTTPS webhook URL where the A2A Server should send (POST) task update notifications.token
(optional): A client-generated opaque string (e.g., a secret or task-specific identifier). The server SHOULD include this token in the notification request (e.g., in a custom header likeX-A2A-Notification-Token
) for validation by the client's webhook receiver.authentication
(optional): AnAuthenticationInfo
object specifying how the A2A Server should authenticate itself to the client's webhook URL. The client (receiver of the webhook) defines these authentication requirements.
- Within the initial
- Notification Trigger: The A2A Server decides when to send a push notification. Typically, this happens when a task reaches a significant state change, such as transitioning to a terminal state (
completed
,failed
,canceled
) or aninput-required
state, particularly after its associated message and artifacts are fully generated and stable. - Notification Payload: The A2A protocol itself does not strictly define the HTTP body payload of the push notification sent by the server to the client's webhook. However, the notification SHOULD contain sufficient information for the client to identify the
taskId
and understand the general nature of the update (e.g., the newTaskState
). Servers might send a minimal payload (justtaskId
and new state) or a more comprehensive one (e.g., a summary or even the fullTask
object). - Client Action: Upon receiving a push notification (and successfully verifying its authenticity and relevance), the client typically uses the
tasks/get
RPC method with thetaskId
from the notification to retrieve the complete, updatedTask
object, including any new artifacts or detailed messages.
The Push Notification Service (Client-Side Webhook Infrastructure):
- The target
url
specified inPushNotificationConfig.url
points to a Push Notification Service. This service is a component on the client's side (or a service the client subscribes to) responsible for receiving the HTTP POST notification from the A2A Server. - Its responsibilities include:
- Authenticating the incoming notification (i.e., verifying it's from the legitimate A2A Server).
- Validating the notification's relevance (e.g., checking the
token
). - Relaying the notification or its content to the appropriate client application logic or system.
- In simple scenarios (e.g., local development), the client application itself might directly expose the webhook endpoint.
- In enterprise or production settings, this is often a robust, secure service that handles incoming webhooks, authenticates callers, and routes messages (e.g., to a message queue, an internal API, a mobile push notification gateway, or another event-driven system).
Security Considerations for Push Notifications¶
Security is paramount for push notifications due to their asynchronous and server-initiated outbound nature. Both the A2A Server (sending the notification) and the client's webhook receiver have responsibilities.
A2A Server Security (When Sending Notifications to Client Webhook)¶
-
Webhook URL Validation:
- Servers SHOULD NOT blindly trust and send POST requests to any
url
provided by a client inPushNotificationConfig
. Malicious clients could provide URLs pointing to internal services or unrelated third-party systems to cause harm (Server-Side Request Forgery - SSRF attacks) or act as Distributed Denial of Service (DDoS) amplifiers. - Mitigation Strategies:
- Allowlisting: Maintain an allowlist of trusted domains or IP ranges for webhook URLs, if feasible.
- Ownership Verification / Challenge-Response: Before sending actual notifications, the server can (and SHOULD ideally) perform a verification step. For example, it could issue an HTTP
GET
orOPTIONS
request to the proposed webhook URL with a uniquevalidationToken
(as a query parameter or header). The webhook service must respond appropriately (e.g., echo back the token or confirm readiness) to prove ownership and reachability. The A2A Python samples demonstrate a simple validation token check mechanism. - Network Controls: Use egress firewalls or network policies to restrict where the A2A Server can send outbound HTTP requests.
- Servers SHOULD NOT blindly trust and send POST requests to any
-
Authenticating to the Client's Webhook:
- The A2A Server MUST authenticate itself to the client's webhook URL according to the scheme(s) specified in
PushNotificationConfig.authentication
. - Common authentication schemes for server-to-server webhooks include:
- Bearer Tokens (OAuth 2.0): The A2A Server obtains an access token (e.g., using the OAuth 2.0 client credentials grant flow if the webhook provider supports it) for an audience/scope representing the client's webhook, and includes it in the
Authorization: Bearer <token>
header of the notification POST request. - API Keys: A pre-shared API key that the A2A Server includes in a specific HTTP header (e.g.,
X-Api-Key
). - HMAC Signatures: The A2A Server signs the request payload (or parts of the request) with a shared secret key using HMAC, and includes the signature in a header (e.g.,
X-Hub-Signature
). The webhook receiver then verifies this signature. - Mutual TLS (mTLS): If supported by the client's webhook infrastructure, the A2A Server can present a client TLS certificate.
- Bearer Tokens (OAuth 2.0): The A2A Server obtains an access token (e.g., using the OAuth 2.0 client credentials grant flow if the webhook provider supports it) for an audience/scope representing the client's webhook, and includes it in the
- The A2A Server MUST authenticate itself to the client's webhook URL according to the scheme(s) specified in
Client Webhook Receiver Security (When Receiving Notifications from A2A Server)¶
-
Authenticating the A2A Server:
- The webhook endpoint MUST rigorously verify the authenticity of incoming notification requests to ensure they originate from the legitimate A2A Server and not an imposter.
- Verify Signatures/Tokens:
- If using JWTs (e.g., as Bearer tokens), validate the JWT's signature against the A2A Server's trusted public keys (e.g., fetched from a JWKS endpoint provided by the A2A Server, if applicable). Also, validate claims like
iss
(issuer),aud
(audience - should identify your webhook),iat
(issued at), andexp
(expiration time). - If using HMAC signatures, recalculate the signature on the received payload using the shared secret and compare it to the signature in the request header.
- If using API keys, ensure the key is valid and known.
- If using JWTs (e.g., as Bearer tokens), validate the JWT's signature against the A2A Server's trusted public keys (e.g., fetched from a JWKS endpoint provided by the A2A Server, if applicable). Also, validate claims like
- Validate
PushNotificationConfig.token
: If the client provided an opaquetoken
in itsPushNotificationConfig
when setting up notifications for the task, the webhook should check that the incoming notification includes this exact token (e.g., in a custom header likeX-A2A-Notification-Token
). This helps ensure the notification is intended for this specific client context and task, adding a layer of authorization.
-
Preventing Replay Attacks:
- Timestamps: Notifications should ideally include a timestamp (e.g.,
iat
- issued at - claim in a JWT, or a custom timestamp header). The webhook should reject notifications that are too old (e.g., older than a few minutes) to prevent attackers from replaying old, captured notifications. The timestamp should be part of the signed payload (if using signatures) to ensure its integrity. - Nonces/Unique IDs: For critical notifications, consider using unique, single-use identifiers (nonces or event IDs) for each notification. The webhook should track received IDs (for a reasonable window) to prevent processing duplicate notifications. A JWT's
jti
(JWT ID) claim can serve this purpose.
- Timestamps: Notifications should ideally include a timestamp (e.g.,
-
Secure Key Management and Rotation:
- If using cryptographic keys (symmetric secrets for HMAC, or asymmetric key pairs for JWT signing/mTLS), implement secure key management practices, including regular key rotation.
- For asymmetric keys where the A2A Server signs and the client webhook verifies, protocols like JWKS (JSON Web Key Set) allow the server to publish its public keys (including new ones during rotation) at a well-known endpoint. Client webhooks can then dynamically fetch the correct public key for signature verification, facilitating smoother key rotation.
Example Asymmetric Key Flow (JWT + JWKS)¶
- Client sets
PushNotificationConfig
specifyingauthentication.schemes: ["Bearer"]
and possibly an expectedissuer
oraudience
for the JWT. - A2A Server, when sending a notification:
- Generates a JWT, signing it with its private key. The JWT includes claims like
iss
(issuer),aud
(audience - the webhook),iat
(issued at),exp
(expires),jti
(JWT ID), andtaskId
. - The JWT header (
alg
andkid
) indicates the signing algorithm and key ID. - The A2A Server makes its public keys available via a JWKS endpoint (URL for this endpoint might be known to the webhook provider or discovered).
- Generates a JWT, signing it with its private key. The JWT includes claims like
- Client Webhook, upon receiving the notification:
- Extracts the JWT from the
Authorization
header. - Inspects the
kid
in the JWT header. - Fetches the corresponding public key from the A2A Server's JWKS endpoint (caching keys is recommended).
- Verifies the JWT signature using the public key.
- Validates claims (
iss
,aud
,iat
,exp
,jti
). - Checks the
PushNotificationConfig.token
if provided.
- Extracts the JWT from the
This comprehensive, layered approach to security for push notifications ensures that messages are authentic, integral, and timely, protecting both the sending A2A Server and the receiving client webhook infrastructure.