DCP-04: Comunicação entre agentes¶
Tradução informativa da especificação em inglês, atualizada em 25/10/2026. A versão normativa é a inglesa: esta tradução não tem valor normativo e, em caso de divergência, prevalece o inglês. Identificadores e blocos de código são mantidos sem tradução.
Status¶
Publicada — v2.0 (extensão; as revisões são acompanhadas conforme o retorno de quem a adota)
Resumo¶
Esta especificação define como agentes certificados pelo DCP descobrem uns aos outros, estabelecem canais de comunicação com autenticação mútua e proteção pós-quântica e trocam mensagens totalmente integradas à trilha de auditoria.
1. Introdução¶
DCP-01 a DCP-03 definem a identidade, a intenção e a auditoria de agentes individuais. O DCP-04 estende o protocolo à interação direta entre agentes, a base dos fluxos de trabalho corporativos com vários agentes.
Sem A2A, o DCP só oferece verificação passiva (o agente apresenta o bundle a um verificador). O DCP-04 permite a interação ativa: um agente da Organização A pode negociar com um agente da Organização B, ambos com autenticação mútua pós-quântica.
1.1 Princípios de design¶
- Autenticação mútua antes de qualquer troca de dados
- Segurança pós-quântica do handshake até o fim da sessão
- Cada mensagem A2A gera uma entrada de auditoria
- Nenhum intermediário central necessário (P2P)
- Compatível com as camadas de transporte existentes (WebSocket, gRPC, HTTP/2)
1.2 Modelo de ameaças¶
- Adversário quântico que coleta agora para decifrar depois (harvest-now-decrypt-later)
- Intermediário (man-in-the-middle) entre agentes
- Personificação de agentes legítimos
- Sequestro da sessão após o handshake
- Repetição de mensagens A2A entre sessões
2. Protocolo de descoberta de agentes¶
2.1 Endpoint conhecido¶
Os agentes publicam sua disponibilidade por meio de .well-known/dcp-agent-directory.json:
{
"dcp_version": "2.0",
"organization": "Acme Corp",
"agents": [
{
"agent_id": "agent:acme-purchasing-001",
"agent_name": "Acme Purchasing Agent",
"capabilities": ["negotiate", "purchase_order", "invoice"],
"bundle_endpoint": "https://acme.com/.well-known/dcp/agents/001/bundle.json",
"a2a_endpoint": "wss://acme.com/dcp/a2a",
"a2a_transports": ["websocket", "grpc"],
"security_tier_minimum": "elevated",
"supported_algorithms": {
"signing": ["ed25519", "ml-dsa-65"],
"kem": ["x25519-ml-kem-768"]
},
"status": "active",
"updated_at": "2026-02-28T00:00:00Z"
}
],
"directory_signature": {
"alg": "ed25519",
"kid": "org-signing-key-kid",
"sig_b64": "..."
}
}
2.2 Fluxo de descoberta¶
- O agente A resolve o domínio do agente B
- O agente A obtém
https://<domain>/.well-known/dcp-agent-directory.json - O agente A verifica a assinatura do diretório
- O agente A seleciona um agente pelas capacidades exigidas
- O agente A obtém o bundle assinado do agente B a partir do
bundle_endpoint - O agente A verifica localmente o bundle do agente B
2.3 Correspondência de capacidades¶
As capacidades são strings de um registro. Entre as capacidades padrão estão:
negotiate— Pode participar de fluxos de negociaçãopurchase_order— Pode emitir ou receber pedidos de comprainvoice— Pode emitir ou processar faturasdata_query— Pode responder a consultas de dadostask_delegate— Pode aceitar tarefas delegadasapproval— Pode aprovar ou rejeitar solicitaçõesnotification— Pode enviar e receber notificações
Capacidades personalizadas devem (MUST) usar notação de domínio reverso: com.acme.custom_capability.
3. Protocolo de handshake¶
3.1 Visão geral¶
O handshake A2A estabelece uma sessão com autenticação mútua e proteção pós-quântica. Ele usa o KEM híbrido (X25519 + ML-KEM-768) já definido na especificação principal v2.0.
Agent A (Initiator) Agent B (Responder)
| |
|── A2A_HELLO ─────────────────────────>|
| { signed_bundle_A, kem_pk_A, |
| nonce_A, supported_algs } |
| |
|<────────────────────── A2A_WELCOME ───|
| { signed_bundle_B, kem_pk_B, |
| nonce_B, kem_ciphertext_BA } |
| |
|── A2A_CONFIRM ───────────────────────>|
| { kem_ciphertext_AB, |
| encrypted_confirm(nonce_A+B) } |
| |
|<──────────────────── A2A_ESTABLISHED ─|
| { encrypted_ack, session_id } |
| |
|══ Encrypted A2A Messages ════════════>|
|<═════════════════════════════════════ ═|
3.2 A2A_HELLO¶
Enviada pelo iniciador para começar o handshake.
{
"type": "A2A_HELLO",
"protocol_version": "2.0",
"initiator_bundle": { "...SignedBundleV2..." },
"ephemeral_kem_public_key": {
"alg": "x25519-ml-kem-768",
"public_key_b64": "..."
},
"nonce": "<32 random bytes, hex>",
"supported_algorithms": {
"signing": ["ed25519", "ml-dsa-65"],
"kem": ["x25519-ml-kem-768"],
"cipher": ["aes-256-gcm"]
},
"requested_capabilities": ["negotiate", "purchase_order"],
"security_tier": "elevated",
"timestamp": "2026-02-28T00:00:00Z"
}
3.3 A2A_WELCOME¶
Enviada pelo respondente depois de verificar o bundle do iniciador.
{
"type": "A2A_WELCOME",
"protocol_version": "2.0",
"responder_bundle": { "...SignedBundleV2..." },
"ephemeral_kem_public_key": {
"alg": "x25519-ml-kem-768",
"public_key_b64": "..."
},
"nonce": "<32 random bytes, hex>",
"kem_ciphertext": {
"alg": "x25519-ml-kem-768",
"ciphertext_b64": "..."
},
"selected_algorithms": {
"signing": "ed25519",
"kem": "x25519-ml-kem-768",
"cipher": "aes-256-gcm"
},
"resolved_security_tier": "elevated",
"timestamp": "2026-02-28T00:00:00Z"
}
3.4 Derivação da chave¶
As duas partes derivam a chave de sessão:
shared_secret_BA = decapsulate(kem_ciphertext_BA, sk_A)
shared_secret_AB = decapsulate(kem_ciphertext_AB, sk_B)
session_key = HKDF-SHA256(
salt = nonce_A || nonce_B,
ikm = shared_secret_BA || shared_secret_AB,
info = "DCP-AI.v2.A2A.SessionKey",
len = 32
)
3.5 Vinculação da sessão¶
A sessão fica vinculada às identidades dos dois agentes:
session_id = SHA-256(
"DCP-AI.v2.A2A.Session" || 0x00 ||
agent_id_A || 0x00 ||
agent_id_B || 0x00 ||
nonce_A || nonce_B ||
session_key
)[0:32] (hex)
4. Gerenciamento de sessões¶
4.1 Estado da sessão¶
Cada sessão mantém:
session_id: identificador único da sessãosession_key: chave simétrica derivadamessage_counter_send: contador monotonicamente crescente de mensagens enviadasmessage_counter_recv: contador monotonicamente crescente de mensagens recebidascreated_at: carimbo de data/hora da criação da sessãolast_activity: carimbo de data/hora da última mensagemsecurity_tier: nível de segurança resolvido para a sessãorekeying_interval: mensagens antes da renovação da chave (padrão: 1000)
4.2 Formato das mensagens¶
{
"session_id": "<hex>",
"sequence": 42,
"type": "A2A_MESSAGE",
"encrypted_payload": "<base64>",
"iv": "<base64, 12 bytes>",
"tag": "<base64, 16 bytes>",
"sender_agent_id": "agent:acme-001",
"timestamp": "2026-02-28T00:00:00Z"
}
Cifragem: AES-256-GCM com:
- Chave:
session_key - IV: 12 bytes aleatórios por mensagem
- AAD:
session_id || sequence || sender_agent_id || timestamp
4.3 Renovação da chave¶
Quando message_counter_send atinge o rekeying_interval:
- O iniciador envia
A2A_REKEYcom uma nova chave pública KEM efêmera - O respondente responde com o texto cifrado KEM
- Uma nova chave de sessão é derivada:
- Os dois contadores voltam a 0
4.4 Encerramento da sessão¶
Qualquer uma das partes pode encerrá-la:
{
"type": "A2A_CLOSE",
"session_id": "<hex>",
"reason": "complete",
"final_sequence": 157,
"audit_summary_hash": "sha256:<hex>",
"timestamp": "2026-02-28T00:00:00Z"
}
Motivos: complete, timeout, error, revocation, policy_violation.
4.5 Retomada da sessão¶
Uma sessão estabelecida anteriormente pode ser retomada se as duas partes guardarem o estado da sessão:
{
"type": "A2A_RESUME",
"session_id": "<hex>",
"last_seen_sequence": 157,
"resume_proof": "<HMAC-SHA256(session_key, session_id || last_seen_sequence)>"
}
O respondente valida a prova e confirma com A2A_RESUMED ou rejeita com A2A_RESUME_REJECTED (o que exige um novo handshake completo).
5. Modelo de confiança¶
5.1 Confiança direta¶
Dois agentes confiam um no outro após a verificação mútua dos bundles durante o handshake. A confiança é estabelecida por sessão e, por padrão, não é transitiva.
5.2 Confiança organizacional¶
Se o agente A confia na chave de assinatura da Organização X e o diretório da Organização X lista o agente B, o agente A pode estender sua confiança ao agente B sob a autoridade da Organização X.
5.3 Confiança transitiva (opcional)¶
A confiança transitiva deve (MUST) ser habilitada explicitamente e tem profundidade limitada:
{
"trust_policy": {
"allow_transitive": true,
"max_depth": 2,
"require_tier": "elevated",
"trusted_organizations": ["org:acme", "org:globex"]
}
}
Se max_depth for 2: A confia em B, B confia em C, A pode (MAY) confiar em C. Uma profundidade 0 significa apenas confiança direta (padrão).
5.4 Revogação da confiança¶
Se o bundle de um agente for revogado durante uma sessão ativa:
- A sessão deve (MUST) ser encerrada imediatamente
- Uma entrada de auditoria
revocationdeve (MUST) ser criada - As mensagens em trânsito devem (MUST) ser descartadas
- A contraparte deve (MUST) ser notificada por
A2A_CLOSEcom o motivorevocation
6. Integração com a auditoria¶
6.1 Eventos de auditoria A2A¶
Cada interação A2A gera entradas de auditoria nas cadeias de auditoria dos dois agentes:
Eventos de handshake:
a2a_hello_sent/a2a_hello_receiveda2a_session_established
Eventos de mensagem:
a2a_message_sent/a2a_message_received
Eventos de sessão:
a2a_rekeya2a_session_closeda2a_session_resumed
6.2 Entrada de auditoria para A2A¶
{
"dcp_version": "2.0",
"event_id": "evt:<uuid>",
"event_type": "a2a_message_sent",
"agent_id": "agent:acme-001",
"session_id": "<hex>",
"counterparty_agent_id": "agent:globex-002",
"sequence": 42,
"payload_hash": "sha256:<hash of decrypted payload>",
"timestamp": "2026-02-28T00:00:00Z",
"prev_hash": "sha256:<hash of previous audit entry>",
"prev_hash_secondary": "sha3-256:<hash>"
}
6.3 Verificação entre cadeias¶
As cadeias de auditoria dos dois agentes referenciam a mesma sessão. Um auditor terceiro pode verificar a consistência:
- Obtendo as entradas de auditoria dos dois agentes para a sessão
- Verificando se os hashes das mensagens coincidem entre remetente e destinatário
- Verificando se os números de sequência são consistentes
- Verificando se os carimbos de data/hora estão dentro de uma diferença aceitável (configurável, 30 segundos por padrão)
7. Formato de transmissão¶
7.1 Requisitos de transporte¶
As mensagens A2A podem (MAY) ser transportadas sobre:
- WebSocket (recomendado para conexões bidirecionais e persistentes)
- gRPC (recomendado para ambientes corporativos de alta vazão)
- HTTP/2 Server-Sent Events (para fluxos unidirecionais)
O handshake deve (MUST) ser concluído em até 10 segundos. A entrega de mensagens deve (MUST) ter semântica de no máximo uma vez.
7.2 Codificação CBOR¶
As mensagens A2A deveriam (SHOULD) usar codificação CBOR (RFC 8949) por eficiência de transporte:
- Mensagens de handshake: JSON (para facilitar a depuração)
- Mensagens de sessão: CBOR (por desempenho)
Content-Type: application/cbor para CBOR, application/json para JSON.
8. Considerações de segurança¶
8.1 Sigilo futuro¶
As chaves KEM efêmeras oferecem sigilo futuro (forward secrecy). Comprometer as chaves de longo prazo não revela as chaves de sessões passadas.
8.2 Segurança pós-quântica¶
O KEM híbrido (X25519 + ML-KEM-768) oferece segurança contra adversários clássicos e quânticos. A chave de sessão é segura se qualquer um dos dois KEM componentes for seguro.
8.3 Negação de serviço¶
As implementações deveriam (SHOULD):
- Limitar a taxa de mensagens A2A_HELLO por origem
- Exigir um bundle válido antes das operações KEM
- Aplicar limites de conexão por agente
- Usar prova de trabalho para iniciadores anônimos (opcional)
8.4 Ordem das mensagens¶
Os números de sequência impedem a repetição e a reordenação. As implementações devem (MUST) rejeitar mensagens com:
- Números de sequência duplicados
- Números de sequência mais de 1000 à frente do último recebido (janela)
- Números de sequência abaixo do último recebido (exceto dentro da janela)
9. Conformidade¶
Uma implementação está em conformidade com o DCP-04 se:
- Implementa o protocolo de handshake definido na seção 3
- Usa KEM híbrido para o estabelecimento de chaves
- Cifra todas as mensagens de sessão com AES-256-GCM
- Gera entradas de auditoria para todos os eventos A2A
- Oferece suporte à renovação da chave de sessão
- Implementa a verificação de confiança por meio da validação de bundles
- Respeita os requisitos do nível de segurança
Referências¶
- DCP-01: Identidade e vinculação ao principal
- DCP-02: Declaração de intenção e controle por políticas
- DCP-03: Cadeia de auditoria e transparência
- FIPS 203: ML-KEM (mecanismo de encapsulamento de chaves baseado em reticulados modulares)
- RFC 5869: HKDF
- RFC 8949: CBOR
- RFC 8446: TLS 1.3 (inspiração para o design do handshake)
Esta especificação foi cocriada por uma pessoa e um agente de IA: o primeiro protocolo A2A para a cidadania digital, projetado para governar as próprias interações que possibilita.
Notas de implementação (informativas)¶
Acrescentadas em 25/10/2026. Não normativas. Estas notas não acrescentam nenhum requisito nem mudam nada do que está acima: descrevem como o código de referência em
mainse relaciona com este texto. Onde divergem, prevalece o texto normativo acima.
- O que os SDKs implementam. Em
maintodos os SDKs constroemA2A_HELLOeA2A_WELCOME; nenhum implementaA2A_CONFIRM/A2A_ESTABLISHEDnem a derivação de chave de §3.4, só o SDK de TypeScript tem o KEM híbrido X25519 + ML-KEM-768 e o SDK de Rust não tem camada de sessão (tools/interop-matrix). Nenhum SDK ou serviço declara conformidade com o DCP-04 tal como §9 a define. - O que as funções auxiliares não fazem. As funções auxiliares de TypeScript constroem mensagens, diretórios e
objetos de sessão, e cifram e decifram mensagens de sessão com uma chave fornecida por quem chama:
createSessionrecebe asession_keycomo argumento e não a deriva. Elas não executam o handshake, a troca KEM, a verificação nem a admissão do bundle da contraparte, o transporte de rede nem as entradas de auditoria de §6; tudo isso fica a cargo de quem chama. - Entradas de auditoria. Não há JSON Schema para a entrada de auditoria A2A de §6.2; sua forma (
event_id,event_type) difere deschemas/v2/audit_entry.schema.json(audit_id,outcome). As mensagens A2A de §2 a §4 também não têm schema emschemas/v2/. Para os tipos do SDK, consulte docs/API_REFERENCE.md. - Os exemplos são ilustrações com marcadores (
...,<hex>,<uuid>), não fixtures.