# Use AIP through A2A

AIP exposes an A2A 1.0 compatibility edge backed by the same native gateway,
policy engine, durable action store, and handlers used by native AIP and MCP.
Use this path when an external agent already speaks A2A and should participate
without becoming responsible for AIP lifecycle semantics.

## What the Profile Provides

The A2A profile projects AIP capabilities as Agent Card skills and maps A2A
tasks to native AIP actions. It supports:

- Agent Card discovery;
- message send and streaming send;
- task read, list, cancellation, and subscription;
- task push-notification configuration create, read, list, and delete;
- authenticated extended Agent Card retrieval;
- legacy v0.3 method names as inbound aliases.

Current A2A names are advertised. Legacy aliases are accepted for migration but
must not be used to infer a second task model.

## Discover the Agent Card

The preferred discovery endpoint is:

```sh
curl --fail-with-body http://127.0.0.1:18080/.well-known/agent-card.json
```

Compatibility aliases are `/.well-known/agent.json` and `/a2a/agent-card`.
The card declares the JSON-RPC interface URL, available skills, supported
content modes, security schemes, and whether push notifications are enabled.

Treat the card as discovery data, not authorization. A skill visible in a card
can still require AIP scopes, approval, idempotency, or transaction policy.

## Send a Message

The preferred JSON-RPC endpoint is `/a2a/v1`. Send `A2A-Version: 1.0` when the
client supports version headers.

```sh
curl --fail-with-body \
  -H 'Authorization: Bearer local-development-token' \
  -H 'A2A-Version: 1.0' \
  -H 'Content-Type: application/json' \
  --data @a2a-request.json \
  http://127.0.0.1:18080/a2a/v1
```

`a2a-request.json` selects one native capability explicitly:

```json
{
  "jsonrpc": "2.0",
  "id": "request-1",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "message-1",
      "contextId": "support-case-42",
      "role": "ROLE_USER",
      "parts": [
        {
          "text": "Check service health"
        }
      ]
    },
    "metadata": {
      "aip": {
        "capability_id": "cap:aipd:health",
        "input": {}
      }
    }
  }
}
```

`metadata.aip.capability_id` is required because a human-readable skill name is
not a stable routing authority. When `metadata.aip.input` is absent, the profile
derives native input from the message parts. The A2A message id becomes the
native idempotency basis.

Set `configuration.returnImmediately` to `true` to request asynchronous native
execution. The returned task id remains the stable handle for later reads and
cancellation.

## Follow and Manage Tasks

| Operation | Purpose |
|---|---|
| `SendStreamingMessage` | Start work and receive ordered task updates over SSE |
| `GetTask` | Read one task projected from the durable action record |
| `ListTasks` | List tasks visible to the authenticated principal and tenant |
| `CancelTask` | Persist cancellation intent and ask the handler to stop |
| `SubscribeToTask` | Resume task updates from retained native events |
| `CreateTaskPushNotificationConfig` | Create encrypted callback configuration for one task |
| `GetTaskPushNotificationConfig` | Read one authorized task callback configuration |
| `ListTaskPushNotificationConfigs` | List callback configurations visible to the caller |
| `DeleteTaskPushNotificationConfig` | Delete one callback configuration and stop future delivery |
| `GetExtendedAgentCard` | Retrieve the authenticated extended card |

Streaming and subscription state is derived from native action events and
chunks. A disconnected client must reconnect with the task identity and cursor
supported by its operation; it must not assume that an open socket is the
durable source of truth.

## Configure Push Notifications Safely

Push delivery is advertised only when `aipd` has both a callback signing key
and an encryption key for stored A2A credentials. Production configuration
also needs an exact callback-host allowlist:

```sh
AIPD_CALLBACK_SIGNING_SEED_HEX="$AIP_CALLBACK_SIGNING_SEED_HEX" \
AIPD_A2A_PUSH_ENCRYPTION_KEY_HEX="$AIP_A2A_PUSH_KEY_HEX" \
cargo run -p aipd -- \
  --bind 127.0.0.1:18080 \
  --service-id agent:aipd:a2a \
  --native-bearer-token-file /run/secrets/aip-native-token \
  --callback-allowed-host callbacks.example.com \
  --storage-dir /var/lib/aip
```

AIP encrypts callback credentials at rest, signs delivery payloads, persists
delivery state, and applies retry fencing. Private-network and plaintext HTTP
targets remain disabled unless the deployment explicitly weakens those
controls for an owned isolated network.

The current daemon accepts these two key values through environment variables
or inline hexadecimal CLI options; inject them from a secret manager and avoid
placing them in shell history or checked-in environment files.

## Authentication and Authority

A2A JSON-RPC operations require the native bearer identity configured by
`aipd`. The authenticated principal, not JSON-RPC metadata, determines tenant,
scope, approval authority, and action visibility. Public Agent Card discovery
does not grant task access.

At an internet boundary, terminate TLS at a trusted edge and replace static
development credentials with deployment identity policy. Do not forward a
user-supplied principal as authenticated context.

## Deployment Boundary

A2A is a compatibility profile, not a second scheduler. Native AIP owns:

- action and task durability;
- authorization and approval;
- idempotency and transaction state;
- event ordering and receipts;
- cancellation and recovery.

An A2A client therefore observes the same outcome as a native or MCP client
calling the same capability.

## Next Steps

- [Profiles, Transports, and Connectors](../concepts/profiles-and-connectors.md)
- [Transport Bindings](../reference/transport-bindings.md)
- [Identity and Trust](../concepts/identity-and-trust.md)
- [Conformance and Qualification](../reference/conformance.md)
- [AIP 1.0 Compatibility Profiles](../spec/AIP-1.0.md#21-compatibility-profiles)
