Skip to content

Streaming and Asynchronous Operations for Long-Running Tasks

The Agent2Agent (A2A) protocol is explicitly designed to handle tasks that might not complete immediately. Many AI-driven operations are often long-running, involve multiple steps, produce incremental results, or require human intervention. A2A provides mechanisms for managing such asynchronous interactions, ensuring that clients receive updates effectively, whether they remain continuously connected or operate in a more disconnected fashion.

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 approach is ideal when the client is able to maintain an active HTTP connection with the A2A Server.

The following key features detail how SSE streaming is implemented and managed within the A2A protocol:

  • Server Capability: The A2A Server must indicate its support for streaming by setting capabilities.streaming: true in its Agent Card.

  • Initiating a Stream: The client uses the message/stream RPC method to send an initial message (for example, a prompt or command) and simultaneously subscribe to updates for that task.

  • Server Response and Connection: If the subscription is successful, the server responds with an HTTP 200 OK status and a Content-Type: text/event-stream. This HTTP connection remains open for the server to push events to the client.

  • Event Structure and Types: The server sends events over this stream. Each event's data field contains a JSON-RPC 2.0 Response object, typically a SendStreamingMessageResponse. The result field of the SendStreamingMessageResponse contains:

    • Task: Represents the current state of the work.
    • TaskStatusUpdateEvent: Communicates changes in the task's lifecycle state (for example, from working to input-required or completed). It also provides intermediate messages from the agent.
    • TaskArtifactUpdateEvent: Delivers new or updated Artifacts generated by the task. This is used to stream large files or data structures in chunks, with fields like append and lastChunk to help reassemble.
  • Stream Termination: The server signals the end of updates for a cycle by setting final: true in a TaskStatusUpdateEvent. This typically occurs when the task reaches a terminal state. After this, the server usually closes the SSE connection.

  • Resubscription: If a client's SSE connection breaks prematurely while a task is still active, the client is able to attempt to reconnect to the stream using the tasks/resubscribe RPC method.

When to Use Streaming

Streaming with SSE is best suited for:

  • Real-time progress monitoring of long-running tasks.
  • Receiving large results (artifacts) incrementally.
  • Interactive, conversational exchanges where immediate feedback or partial responses are beneficial.
  • Applications requiring low-latency updates from the agent.

Protocol Specification References

Refer to the Protocol Specification for detailed structures:

Push Notifications for Disconnected Scenarios

For very long-running tasks (for example, lasting minutes, hours, or even days) or when clients are unable to or prefer not to maintain persistent connections (like mobile clients or serverless functions), A2A supports asynchronous updates using push notifications. This allows the A2A Server to actively notify a client-provided webhook when a significant task update occurs.

The following key features detail how push notifications are implemented and managed within the A2A protocol:

  • 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 is supplied:
    • Within the initial message/send or message/stream request, or
    • Separately, using the tasks/pushNotificationConfig/set RPC method for an existing task. The PushNotificationConfig includes a url (the HTTPS webhook URL), an optional token (for client-side validation), and optional authentication details (for the A2A Server to authenticate to the webhook).
  • Notification Trigger: The A2A Server decides when to send a push notification, typically when a task reaches a significant state change (for example, terminal state, input-required, or auth-required).
  • Notification Payload: The A2A protocol does not strictly define the HTTP body payload, but it SHOULD contain sufficient information for the client to identify the Task ID and understand the general nature of the update (for example, the new TaskState).
  • Client Action: Upon receiving a push notification (and successfully verifying its authenticity), the client typically uses the tasks/get RPC method with the taskId from the notification to retrieve the complete, updated Task object, including any new artifacts.

When to Use Push Notifications

Push notifications are ideal for:

  • Very long-running tasks that can take minutes, hours, or days to complete.
  • Clients that cannot or prefer not to maintain persistent connections, such as mobile applications or serverless functions.
  • Scenarios where clients only need to be notified of significant state changes rather than continuous updates.

Protocol Specification References

Refer to the Protocol Specification for detailed structures:

Client-Side Push Notification Service

The url specified in PushNotificationConfig.url points to a client-side Push Notification Service. This service is responsible for receiving the HTTP POST notification from the A2A Server. Its responsibilities include authenticating the incoming notification, validating its relevance, and relaying the notification or its content to the appropriate client application logic or 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 critical 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. Malicious clients could provide URLs pointing to internal services or unrelated third-party systems, leading to Server-Side Request Forgery (SSRF) attacks or acting as Distributed Denial of Service (DDoS) amplifiers.
    • Mitigation strategies: Allowlisting of trusted domains, ownership verification (for example, challenge-response mechanisms), and network controls (e.g., egress firewalls).
  • 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 schemes include Bearer Tokens (OAuth 2.0), API keys, HMAC signatures, or mutual TLS (mTLS).

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.
    • Verification methods: Verify signatures/tokens (for example, JWT signatures against the A2A Server's trusted public keys, HMAC signatures, or API key validation). Also, validate the PushNotificationConfig.token if provided.
  • Preventing Replay Attacks:
    • Timestamps: Notifications SHOULD include a timestamp. The webhook SHOULD reject notifications that are too old.
    • Nonces/unique IDs: For critical notifications, consider using unique, single-use identifiers (for example, JWT's jti claim or event IDs) to prevent processing duplicate notifications.
  • Secure Key Management and Rotation: Implement secure key management practices, including regular key rotation, especially for cryptographic keys. Protocols like JWKS (JSON Web Key Set) facilitate key rotation for asymmetric keys.

Example Asymmetric Key Flow (JWT + JWKS)

  1. Client sets PushNotificationConfig specifying authentication.schemes: ["Bearer"] and possibly an expected issuer or audience for the JWT.
  2. A2A Server, when sending a notification:
    • Generates a JWT, signing it with its private key. The JWT includes claims like iss (issuer), aud (audience), iat (issued at), exp (expires), jti (JWT ID), and taskId.
    • The JWT header indicates the signing algorithm and key ID (kid).
    • The A2A Server makes its public keys available through a JWKS endpoint.
  3. Client Webhook, upon receiving the notification:
    • Extracts the JWT from the Authorization header.
    • Inspects the kid (key ID) 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.

This comprehensive, layered approach to security for push notifications helps ensure that messages are authentic, integral, and timely, protecting both the sending A2A Server and the receiving client webhook infrastructure.