Especificação normativa do DCP-AI v2.0¶
Tradução informativa da especificação em inglês, atualizada em 02/11/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: Final
Versão: 2.0.0
Data: 2026-02-26
Autoria: DCP-AI Protocol Governance
1. Introdução¶
O Digital Citizenship Protocol for AI (DCP-AI) v2.0 define um arcabouço resistente à computação quântica para identidade de agentes, declaração de intenções, controle por políticas e trilhas de auditoria. Ele substitui a v1.0 e introduz assinaturas híbridas com vinculação composta, separação de domínio, vinculação de sessão e aplicação de políticas em que quem manda é o verificador.
1.1 Objetivos de design¶
- Segurança pós-quântica: todos os artefatos de identidade e de auditoria são protegidos contra adversários quânticos por assinaturas compostas híbridas.
- Não repúdio: agentes e pessoas não podem negar as ações registradas em cadeias de auditoria assinadas.
- Detecção de adulterações: cadeias de hashes, raízes de Merkle e ancoragem em blockchain oferecem várias camadas de detecção de adulterações.
- Agilidade criptográfica: o registro de algoritmos e a abstração de provedores permitem migrar de algoritmo sem mudar o protocolo.
- Privacidade: o modo de RPR cego protege os dados pessoais sem perder a verificabilidade.
- Interoperabilidade: verificação entre SDKs, formato de transmissão CBOR e suporte a gRPC.
1.2 Notação¶
||denota a concatenação de bytesUTF8(s)denota a codificação UTF-8 da stringscanonical(obj)denota a canonicalização segundo o perfildcp-jcs-v1(§15), baseado na RFC 8785 JCSSHA-256(m)denota o hash SHA-256 da mensagemmhex(b)[0:n]denota os primeirosncaracteres hexadecimais da sequência de bytesb
2. Registro de algoritmos¶
2.1 Algoritmos de assinatura¶
| Identificador | Padrão | Tamanho da chave pública | Tamanho da assinatura | Nível de segurança | Status |
|---|---|---|---|---|---|
ed25519 |
RFC 8032 | 32 B | 64 B | 128 bits clássico | ACTIVE |
ml-dsa-65 |
FIPS 204 | 1952 B | 3309 B | NIST nível 3 PQ | ACTIVE (PQ principal) |
ml-dsa-87 |
FIPS 204 | 2592 B | 4627 B | NIST nível 5 PQ | ACTIVE (alta garantia) |
slh-dsa-192f |
FIPS 205 | 48 B | 35664 B | NIST nível 3 PQ | ACTIVE (PQ de reserva) |
slh-dsa-256f |
FIPS 205 | 64 B | 49856 B | NIST nível 5 PQ | RESERVED |
Nota informativa (25/10/2026), não faz parte do texto normativo: nenhum SDK do DCP-AI implementa ainda
ml-dsa-87; os SDKs assinam e verificam comed25519,ml-dsa-65eslh-dsa-192f(docs/NIST_CONFORMITY.md).
2.2 Algoritmos KEM¶
| Identificador | Padrão | Tamanho da chave pública | Tamanho do texto cifrado | Nível de segurança |
|---|---|---|---|---|
x25519 |
RFC 7748 | 32 B | 32 B | 128 bits clássico |
ml-kem-768 |
FIPS 203 | 1184 B | 1088 B | NIST nível 3 PQ |
x25519-ml-kem-768 |
Híbrido | 1216 B | 1120 B | Híbrido nível 3 |
2.3 Algoritmos de hash¶
| Identificador | Saída | Uso |
|---|---|---|
sha256 |
32 B | PADRÃO em implantações de nível 3 |
sha3-256 |
32 B | Hash secundário do modo de hash duplo |
sha384 |
48 B | RECOMENDADO em implantações de nível 5 |
2.4 Tipos numéricos¶
Todos os campos numéricos do DCP-AI v2.0 devem (MUST) ser inteiros. Valores de ponto flutuante são proibidos para eliminar a ambiguidade na canonicalização.
3. Objetos de chave¶
3.1 Entrada de chave¶
{
"kid": "<32 hex chars>",
"alg": "<algorithm identifier>",
"public_key_b64": "<base64-encoded public key>",
"created_at": "<ISO 8601>",
"expires_at": "<ISO 8601 | null>",
"status": "active | revoked | expired"
}
3.2 Derivação determinística do kid¶
Propriedades: único, determinístico e resistente a colisões (128 bits do truncamento de SHA-256).
4. Separação de domínio¶
Toda assinatura deve (MUST) incluir uma tag de separação de domínio:
4.1 Tags de contexto¶
| Tag de contexto | Uso |
|---|---|
DCP-AI.v2.AgentPassport |
Autoassinatura do passaporte do agente |
DCP-AI.v2.ResponsiblePrincipal |
Assinatura do registro de vinculação à pessoa |
DCP-AI.v2.Intent |
Assinatura da declaração de intenção |
DCP-AI.v2.PolicyDecision |
Assinatura do mecanismo de políticas |
DCP-AI.v2.AuditEvent |
Assinatura de auditoria por evento |
DCP-AI.v2.Bundle |
Assinatura do bundle |
DCP-AI.v2.Revocation |
Assinatura do registro de revogação |
DCP-AI.v2.KeyRotation |
Prova de rotação de chaves |
DCP-AI.v2.ProofOfPossession |
Desafio e resposta de prova de posse |
DCP-AI.v2.JurisdictionAttestation |
Atestação de jurisdição |
DCP-AI.v2.HumanConfirmation |
Confirmação humana |
DCP-AI.v2.AlgorithmAdvisory |
Aviso de descontinuação de algoritmo |
DCP-AI.v2.Governance |
Operações de governança |
DCP-AI.v2.MultiPartyAuth |
Autorização de uma parte em uma autorização multipartes (multi_party_authorization.schema.json) |
DCP-AI.v2.Lifecycle |
Certificado de entrada em serviço, relatório de vitalidade e registro de desativação (DCP-05) |
DCP-AI.v2.Succession |
Testamento digital, manifesto de transferência de memória e registro de sucessão (DCP-06) |
DCP-AI.v2.Dispute |
Registro de disputa, objeção, resolução de arbitragem e pacote de jurisprudência (DCP-07) |
DCP-AI.v2.Rights |
Declaração de direitos, registro de obrigação e relatório de violação de direitos (DCP-08) |
DCP-AI.v2.Delegation |
Mandato de delegação raiz (assinatura da pessoa), espelhos do principal e registros de interação (DCP-09) |
DCP-AI.v2.Awareness |
Limiares de consciência e declarações de alerta (DCP-09) |
DCP-AI.v2.SubMandate |
Submandato assinado pelo agente que delega (DCP-09 §3.5) |
Errata E1 (25/10/2026, normativa): as linhas
MultiPartyAuth,Lifecycle,Succession,Dispute,RightseAwareness, e os espelhos do principal na linhaDelegation, documentam contextos já usados pelos SDKs e portests/interop/v2/interop_vectors.json#domain_separation_all_contexts; não acrescentam nenhuma tag. Veja V2-WIRE-COMPATIBILITY.md.
5. Assinaturas compostas¶
5.1 Protocolo de vinculação¶
Step 1: classical_sig = Classical.sign(context || 0x00 || payload)
Step 2: pq_sig = PQ.sign(context || 0x00 || payload || classical_sig)
A assinatura PQ cobre a assinatura clássica. Remover qualquer um dos componentes faz os dois falharem na verificação.
5.2 Formato de transmissão¶
{
"composite_sig": {
"classical": { "alg": "ed25519", "kid": "...", "sig_b64": "..." },
"pq": { "alg": "ml-dsa-65", "kid": "...", "sig_b64": "..." },
"binding": "pq_over_classical"
}
}
5.3 Modos de vinculação¶
pq_over_classical: OBRIGATÓRIO na v2.0. A assinatura PQ cobre a assinatura clássica.classical_only: permitido durante a transição. O campo PQ énull.
6. Envelope SignedPayload¶
Os artefatos nunca contêm dados de assinatura. As assinaturas ficam em um campo irmão:
{
"payload": { /* pure artifact */ },
"payload_hash": "sha256:...",
"composite_sig": { /* ... */ }
}
Bytes assinados: context_tag || 0x00 || canonical(payload)
7. Modos de verificação¶
7.1 Modos¶
| Modo | Clássica exigida | PQ exigida | Bundles V1 |
|---|---|---|---|
classical_only |
Sim | Não | Sim |
pq_only |
Não | Sim | Não |
hybrid_required |
Sim | Sim | Configurável |
hybrid_preferred |
Sim | Não (alerta) | Configurável |
Em todos os modos, uma assinatura PQ presente (pq_over_classical) deve (MUST) ser verificada. hybrid_preferred e classical_only só toleram que ela esteja ausente.
7.2 Política definida pelo verificador¶
A política de assinaturas é definida pela configuração do verificador, NÃO pelo agente. O verificador carrega a política da sua própria configuração:
{
"verifier_policy": {
"default_mode": "hybrid_required",
"risk_overrides": { "high": "hybrid_required", "medium": "hybrid_required", "low": "hybrid_preferred" },
"min_classical": 1,
"min_pq": 1,
"accepted_classical_algs": ["ed25519"],
"accepted_pq_algs": ["ml-dsa-65", "slh-dsa-192f"],
"require_session_binding": true,
"require_composite_binding": true,
"allow_classical_fallback_disable": false,
"warn_classical_only_deprecated": false,
"advisory_rejected_algs": []
}
}
O nível de segurança (§14.3) só pode tornar mais rigoroso o modo que essa política seleciona.
7.3 Modo somente PQ (fase 3)¶
Quando default_mode é pq_only:
- As assinaturas clássicas são aceitas, mas não exigidas
min_classicalé 0 emin_pqé 1- A vinculação composta não é exigida
- Os bundles V1 são rejeitados
- Os bundles somente clássicos emitem alertas de descontinuação
8. Vinculação de sessão¶
Um session_nonce aleatório de 256 bits (64 caracteres hexadecimais) liga todos os artefatos de uma sessão:
Todo artefato V2 inclui session_nonce. O verificador deve (MUST) verificar se todos os artefatos de um bundle compartilham o mesmo nonce.
9. Manifesto do bundle¶
O manifesto do bundle vincula criptograficamente os hashes de todos os artefatos:
{
"manifest": {
"session_nonce": "...",
"rpr_hash": "sha256:...",
"passport_hash": "sha256:...",
"intent_hash": "sha256:...",
"policy_hash": "sha256:...",
"audit_merkle_root": "sha256:...",
"audit_merkle_root_secondary": "sha3-256:...",
"audit_count": 5,
"pq_checkpoints": ["ckpt-uuid-1"],
"canonicalization_profile": "dcp-jcs-v1"
}
}
canonicalization_profile é OPCIONAL (hoje só "dcp-jcs-v1" está definido; veja § 15 e CANONICALIZATION_PROFILE.md). Um verificador que encontre um bundle sem o campo deve (MUST) presumir dcp-jcs-v1. Perfis futuros tornarão o campo OBRIGATÓRIO.
A assinatura composta do bundle assina canonical(manifest).
10. Trilha de auditoria¶
10.1 Assinatura por evento¶
Cada evento de auditoria é assinado com Ed25519 (latência de microssegundos). Os eventos formam uma cadeia de hashes por meio de prev_hash.
10.2 Checkpoints PQ (modelo preguiçoso)¶
A cada N eventos (configurável, padrão 10), é produzido um checkpoint PQ: uma assinatura composta sobre a raiz de Merkle dos últimos N eventos.
10.3 Cadeias de hash duplo¶
As cadeias SHA-256 e SHA3-256 rodam em paralelo desde o lançamento da v2.0. Se uma família de hash for quebrada, a outra garante a continuidade.
10.4 Compactação da auditoria¶
Após N eventos (padrão 1000), é produzido um checkpoint de compactação. Os eventos compactados podem (MAY) ser arquivados enquanto o checkpoint permanece na cadeia ativa.
11. Gerenciamento de chaves¶
11.1 Rotação de chaves¶
- Gerar um novo par de chaves
- A nova chave assina um desafio de prova de posse (old_kid + new_kid + carimbo de data/hora) sob o contexto
DCP-AI.v2.KeyRotation - A chave antiga referenda a rotação para autorizá-la
- Janela de carência: 30 dias em que as duas chaves são aceitas
11.2 Recuperação de chaves (recuperação social M de N)¶
O segredo mestre é dividido com o compartilhamento de segredos de Shamir. As partes são cifradas com KEM híbrido para os contatos de recuperação.
Nota informativa (25/10/2026), não faz parte do texto normativo: a recuperação de chaves do SDK de TypeScript e
dcp recovery-setupproduzem as partes, mas não as cifram; cifrá-las para os contatos de recuperação fica a cargo de quem implementa.
11.3 Revogação de emergência¶
revocation_token = SHA-256(revocation_secret) registrado previamente. Revelar a pré-imagem revoga todas as chaves do agente sem assinatura criptográfica.
11.4 Suporte a HSM/TPM¶
As chaves privadas deveriam (SHOULD) ser armazenadas em módulos de segurança de hardware. A interface CryptoProvider aceita HsmCryptoProvider, que delega todas as operações ao HSM via PKCS#11.
Nota informativa (25/10/2026), não faz parte do texto normativo: o
HsmCryptoProviderdo código-fonte do SDK de TypeScript é um padrão simulado, não uma integração com HSM: não é exportado, não tem vínculo PKCS#11 e não deve ser usado para assinar ou verificar evidências reais. Este repositório não implementa nenhum backend de hardware nem declara nenhuma validação FIPS 140 (docs/NIST_CONFORMITY.md §2.2).
12. Privacidade¶
12.1 RPR cego¶
Um RPR cego (schemas/v2/blinded_rpr.schema.json) substitui os campos de dados pessoais do RPR completo (legal_name, contact) por um compromisso com sal, de modo que os bundles possam ser publicados em logs de transparência e âncoras sem os dados pessoais. Os campos que não são dados pessoais (human_id, session_nonce, entity_type, jurisdiction, liability_mode, override_rights, issued_at, expires_at, binding_keys) são copiados sem alteração e comparados com o RPR completo na divulgação.
pii_salt = hex(random(32))
pii_hash = "sha256:" || hex(SHA-256(UTF8(canonical({ contact, legal_name, pii_salt }))))
Um contact ausente entra no hash como null.
- Sal.
pii_salté um campo do RPR completo: 32 bytes de um CSPRNG em hexadecimal minúsculo, novos para cada RPR. Ele é coberto pela assinatura do RPR completo e não deve (MUST NOT) ser publicado; nunca aparece no RPR cego. Reutilizar um sal dá o mesmopii_hasha registros com os mesmos dados pessoais, o que permite ligá-los. Com 32 bytes, uma busca por adivinhação e confirmação continua custando 2^128 operações mesmo com o algoritmo de Grover. - O cegamento falha de forma fechada. As implementações devem (MUST) se recusar a cegar um RPR que não tenha um
pii_saltválido, e os verificadores devem (MUST) rejeitar um RPR completo cujopii_saltesteja presente mas não tenha 64 caracteres hexadecimais minúsculos. O sal é assinado com o RPR completo, então precisa ser definido quando o RPR é criado: um RPR que possa ser cegado depois deveria (SHOULD) ter umpii_saltdesde o início. - Divulgação. O sal só é divulgado junto com o RPR completo, por exemplo a um regulador, que recalcula
pii_hasha partir do RPR completo e compara os campos que não são dados pessoais. - Eliminação. Apagar o RPR completo, e com ele o sal, torna o compromisso publicado impossível de abrir: ninguém consegue confirmar com ele um nome e um contato adivinhados. Isso proporciona a eliminação (artigo 17 do RGPD) para registros em logs e âncoras imutáveis, que não podem ser reescritos. É preciso apagar todas as cópias do RPR completo, inclusive as divulgadas.
human_id. O RPR cego publicahuman_id, entãohuman_iddeve (MUST) ser opaco e não deve (MUST NOT) conter dados pessoais nem ser derivado deles, como um endereço de e-mail, um nome ou o hash de qualquer um deles.- Compromissos legados. Um
pii_hashcalculado a partir de um RPR completo sempii_salt(a fórmula acima sem o membropii_salt) está descontinuado. As implementações não devem (MUST NOT) cegar novos registros dessa forma. Os verificadores podem (MAY) continuar verificando um compromisso legado com um RPR completo divulgado e deveriam (SHOULD) sinalizá-lo como descontinuado: quem adivinhar os dados pessoais pode confirmá-los, e em um log imutável isso continua verdadeiro para sempre.
13. Governança¶
13.1 Conjunto de chaves de governança¶
Chaves multipartes M de N usadas para assinar avisos sobre algoritmos e decisões do protocolo. Publicadas em /.well-known/governance-keys.json.
13.2 Sistema de avisos sobre algoritmos¶
Avisos assinados com as ações warn, deprecate e revoke. A resposta automatizada do verificador remove os algoritmos afetados e acrescenta os substitutos.
13.3 Resposta automática aos avisos¶
Os verificadores, automaticamente:
- Removem das listas aceitas os algoritmos descontinuados ou revogados
- Acrescentam os algoritmos substitutos
- Passam para pq_only se todos os algoritmos clássicos forem removidos
- Mantêm uma trilha de auditoria das mudanças de política
14. Níveis de segurança adaptativos¶
O sistema de níveis de segurança adaptativos seleciona os níveis de proteção criptográfica a partir da pontuação de risco da decisão de política e das classes de dados, do tipo de ação e do impacto estimado da intenção. Os níveis determinam o modo de verificação, o intervalo dos checkpoints PQ e os modos de apresentação do bundle.
14.1 Definição dos níveis¶
| Nível | Nome | Modo de verificação | Intervalo de checkpoint PQ | Tamanho do bundle | Latência criptográfica |
|---|---|---|---|---|---|
| 0 | routine |
classical_only |
A cada 50 eventos | ~1-2 KB | ~2 ms |
| 1 | standard |
hybrid_preferred |
A cada 10 eventos | ~2-5 KB | ~2 ms + 5 ms de checkpoint |
| 2 | elevated |
hybrid_required |
A cada evento | ~10-15 KB | ~11 ms |
| 3 | maximum |
hybrid_required |
A cada evento + verificação imediata | ~15-25 KB | ~15 ms |
14.2 Algoritmo de seleção do nível¶
O nível é calculado somente a partir de campos assinados que os schemas definem: action_type, data_classes, estimated_impact e o opcional security_tier da intenção, e a risk_score (inteiro 0..1000) do PolicyDecisionV2 do bundle. O schema da intenção não tem risk_score; uma implementação não deve (MUST NOT) lê-la da intenção.
function computeSecurityTier(intent, policy_decision):
if policy_decision is absent or null:
score = 0
else if policy_decision.risk_score is an integer from 0 to 1000:
score = policy_decision.risk_score
else:
score = unknown
dc = intent.data_classes
unknown = score is unknown
OR intent.action_type ∉ ACTION_TYPES
OR intent.estimated_impact ∉ {low, medium, high}
OR dc is not an array
OR some element of dc ∉ DATA_CLASSES
if score >= 800 OR dc ∩ {credentials, children_data} ≠ ∅:
tier = "maximum"
else if score >= 500 OR dc ∩ {pii, financial_data, health_data} ≠ ∅
OR intent.action_type == "initiate_payment"
OR intent.estimated_impact == "high" OR unknown:
tier = "elevated"
else if score >= 200 OR intent.estimated_impact == "medium":
tier = "standard"
else:
tier = "routine"
explicit = intent.security_tier
if explicit is present and not null:
tier = max(tier, explicit if it is a tier name else "elevated")
if a verified mandate chain (DCP-09 §3.5) applies and has an effective tier:
tier = max(tier, that tier if it is a tier name else "elevated")
return tier
O nível efetivo de uma cadeia de delegação verificada, o maior minimum_security_tier ao longo dela, é uma entrada opcional desse cálculo que só pode elevar o resultado, nunca rebaixá-lo. Nenhum campo do bundle carrega a cadeia ainda, então o piso se aplica quando o verificador recebe uma cadeia verificada junto com o bundle; os verificadores de bundles de §18 não a leem.
ACTION_TYPES e DATA_CLASSES são os enums action_type e data_classes de schemas/v2/intent.schema.json. Um valor ausente, de tipo errado ou desconhecido falha de forma fechada para, no mínimo, elevated, de modo que um valor que o verificador não conhece nunca reduz o escrutínio que um bundle recebe, com ou sem validação de schema. Sem decisão de política, a pontuação é 0. Em uma decisão de política, uma risk_score ausente ou que não seja um inteiro de 0 a 1000 (uma string, uma fração, um número negativo, um número acima de 1000) é desconhecida da mesma forma, e as comparações de pontuação acima a tratam como 0. Um número sem parte fracionária, como 200.0, conta como esse inteiro.
A categoria security_tier de tests/interop/v2/interop_vectors.json lista o nível, o modo de verificação e o intervalo de checkpoint esperados para cada caso. Os quatro SDKs a executam.
14.3 Aplicação do nível (nunca para baixo)¶
Um verificador V2 deve (MUST) calcular o nível de cada bundle e verificar o bundle com o mais rigoroso de dois modos:
- o modo da política: o
default_modedo verificador, ou a sua entrada derisk_overridespara orisk_tierdo passaporte (§7.2); - o modo do nível (§14.1).
A ordem de rigor é classical_only < hybrid_preferred < hybrid_required. O nível só pode acrescentar um requisito PQ, então uma política pq_only continua pq_only. O agente verificado assina o passaporte e a intenção, então seu risk_tier e seu security_tier podem elevar o modo, mas não levá-lo abaixo do modo do nível. Os verificadores informam o nível resolvido junto com o resultado.
O verificador pode (MAY) elevar o nível calculado, mas não deve (MUST NOT) rebaixá-lo. O campo resolved_tier em PolicyDecisionV2 registra o nível que o mecanismo de políticas resolveu. Ele é informativo: o cálculo de §14.2 não o lê.
14.4 Campos da intenção e da decisão de política¶
IntentV2 inclui um campo opcional security_tier (calculado automaticamente ou definido de forma explícita). PolicyDecisionV2 inclui um campo opcional resolved_tier, o nível que o mecanismo de políticas resolveu, a título informativo; §14.2 não o lê.
14.5 Cache de verificação¶
Os resultados de bundles verificados podem (MAY) ser mantidos em cache com um TTL definido pelo nível resolvido:
| Nível | TTL do cache |
|---|---|
routine |
5 minutos |
standard |
2 minutos |
elevated |
30 segundos |
maximum |
10 segundos |
As entradas do cache devem (MUST) ser invalidadas quando o kid de qualquer signatário for revogado.
14.6 Modos de apresentação do bundle¶
Os níveis influenciam o modo de apresentação sugerido para otimizar a largura de banda:
- Níveis 0-1 (sessão estabelecida):
compactoureference: a assinatura PQ é omitida e a referência ao checkpoint é incluída - Níveis 2-3:
full: o bundle completo com todas as assinaturas - Primeiro contato (qualquer nível):
full
15. Canonicalização¶
O DCP-AI v2.0 usa o perfil de canonicalização dcp-jcs-v1, baseado na RFC 8785 (JCS). O perfil fixa os casos que o JCS deixa a critério da implementação (tratamento de undefined, números de ponto flutuante com valor inteiro, notação científica, preservação de null, contêineres vazios) para que os quatro SDKs produzam saída idêntica byte a byte. Ele não é um subconjunto estrito do JCS: as chaves são ordenadas por ponto de código Unicode (item 1), enquanto a RFC 8785 as ordena por unidades de código UTF-16. As duas ordens só diferem em chaves que misturam caracteres dos planos suplementares com caracteres do intervalo U+E000..U+FFFF.
Resumo:
- Chaves ordenadas lexicograficamente por ponto de código Unicode
- Forma compacta (sem espaços em branco)
- Somente números inteiros, decidido após a análise (
1.0,1e2,1.00são aceitos;0.1,NaN,Infinitysão rejeitados) nullé preservado com sua chave; os arrays preservamnullna posiçãoundefined(somente TypeScript): omitido em objetos, serializado comonullem arrays- Nenhuma exclusão de campos (envelope SignedPayload)
- Bytes assinados:
UTF8(context_tag) || 0x00 || canonical(payload)
O perfil normativo completo, com a tabela de aceitação dos casos-limite e os fixtures de teste que os quatro SDKs precisam passar, está em spec/CANONICALIZATION_PROFILE.md. Os bundles produzidos com esse perfil o declaram pelo campo opcional canonicalization_profile: "dcp-jcs-v1" do manifesto do bundle.
16. Formatos de transmissão¶
16.1 JSON (padrão)¶
Content-Type: application/json
16.2 CBOR (opcional)¶
Content-Type: application/cbor: codificação determinística da RFC 8949. De 30 a 40% menor que JSON.
17. Compatibilidade com versões anteriores¶
V1 Verifier + V1 Bundle -> PASS (unchanged)
V1 Verifier + V2 Bundle -> REJECT "unsupported dcp_version 2.0"
V2 Verifier + V1 Bundle -> PASS (when allow_v1_bundles=true)
V2 Verifier + V2 Bundle -> PASS (full V2 verification)
Os verificadores V2 devem (MUST) oferecer suporte à V1 indefinidamente. A migração é gradual.
18. Pipeline de verificação¶
- Decodificação do formato de transmissão (JSON ou CBOR)
- Validação de schema (roteamento V1/V2)
- Consistência do nonce de sessão
- Integridade do manifesto (recalcular os hashes dos artefatos) e janela de sessão a partir dos campos assinados
session_issued_atesession_expires_at - Consistência entre artefatos: status do passaporte, expiração do RPR, um único principal, agente e intenção em todos os artefatos e na trilha de auditoria (VERIFICATION.md V2-14)
- Cálculo do nível de segurança a partir da intenção e da decisão de política assinadas (§14.2)
- Rejeição de algoritmos com base nos avisos
- Verificação das assinaturas compostas (em paralelo): a assinatura do bundle com as
binding_keysdo RPR, os artefatos do agente com askeysdo passaporte, cada kid derivado da sua chave - Aplicação da política do verificador com o modo efetivo, o mais rigoroso entre o modo da política e o do nível (§14.3), à assinatura do bundle e a cada assinatura de artefato
- Validação da cadeia de hashes de auditoria
- Validação dos checkpoints PQ: exatamente os checkpoints listados, cada um sobre suas entradas de auditoria e assinado pelo agente
- Verificações de validade das chaves (expiração, revogação, derivação do kid)
- Consulta e armazenamento no cache de verificação (§14.5)
19. Modelo de ameaças¶
| Ameaça | Mitigação |
|---|---|
| Adversário quântico (algoritmo de Shor) | ML-DSA-65 na assinatura composta |
| Coletar agora e decifrar depois | Assinaturas híbridas compostas (a PQ continua válida mesmo que a clássica seja quebrada) |
| Ataque de remoção | Vinculação composta (a PQ assina sobre a assinatura clássica) |
| Repetição entre artefatos | Tags de contexto de separação de domínio |
| Emenda de sessões | session_nonce + manifesto do bundle |
| Rebaixamento da política | Política definida pelo verificador + regra de nível que nunca baixa |
| Confusão ou apropriação de chaves | kid determinístico + prova de posse |
| Quebra de algoritmo (PQ) | Agilidade criptográfica + reserva SLH-DSA-192f + sistema de avisos |
| Exploração da canonicalização | Schemas somente com inteiros, proibição de ponto flutuante |
| Roubo de chaves | HSM/TPM, certificados de curta duração, rotação de chaves com prova de posse |
| Adulteração do banco de dados | Cadeias de hashes + raízes de Merkle + ancoragem em blockchain |
| Exposição de dados pessoais | Modo de RPR cego |
| Perda de chaves | Recuperação social M de N (Shamir SSS) |
| Evasão do nível | Elevação do nível pelo verificador; o agente não pode rebaixá-lo |
| Agente que reivindica um principal (reutilizando um RPR publicado e assinado) | Assinatura do bundle somente com as binding_keys do RPR; ela se compromete com o hash do passaporte. Um RPR emitido com o human_id de outra pessoa só é barrado por um verificador que fixe ou ateste as chaves do principal |
| Artefatos inconsistentes, mas assinados validamente | Verificações de consistência entre artefatos (VERIFICATION.md V2-14) |
| Metadados não assinados que orientam uma verificação | Início da sessão assinado no manifesto; o bloco do signatário não pode contradizer a assinatura |
20. Requisitos de conformidade¶
20.1 MUST¶
- Assinaturas híbridas com vinculação composta em todos os artefatos V2
- Separação de domínio em cada assinatura
- Nonce de sessão em cada artefato de um bundle
- Campos numéricos somente inteiros
- Derivação determinística do kid
- Validação com os KATs do NIST para todos os provedores PQ
- Cálculo do nível de segurança (§14.2) e sua aplicação com a regra de nunca rebaixar (§14.3) para cada bundle V2
20.2 SHOULD¶
- HSM/TPM para o armazenamento de chaves privadas em produção
- Cadeias de hash duplo (SHA-256 + SHA3-256)
- Formato de transmissão CBOR para implantações de alta vazão
- Certificados de curta duração (TTL de 24 h) em vez de listas de revogação
- Consulta periódica de avisos (diária)
20.3 MAY¶
- CBOR + compressão gzip
- Verificação de assinaturas em paralelo
- Estratégia de verificação que falha rápido checando primeiro a PQ
- Compactação da trilha de auditoria
- Cache dos resultados de verificação com TTL por nível (§14.5)
21. Referências¶
- FIPS 203: ML-KEM (mecanismo de encapsulamento de chaves baseado em reticulados modulares)
- FIPS 204: ML-DSA (algoritmo de assinatura digital baseado em reticulados modulares)
- FIPS 205: SLH-DSA (algoritmo de assinatura digital baseado em hash sem estado)
- RFC 8032: Edwards-Curve Digital Signature Algorithm (EdDSA)
- RFC 8785: JSON Canonicalization Scheme (JCS)
- RFC 8949: Concise Binary Object Representation (CBOR)
Fim da especificação normativa do DCP-AI v2.0
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.
- §5.1 e §7.1, remoção. Nos verificadores dos SDKs, uma assinatura PQ presente que não é verificada é rejeitada em
todos os modos. Um bundle do qual a assinatura PQ foi removida e cuja vinculação foi reetiquetada como
classical_onlyé aceito quando o modo efetivo éclassical_onlyouhybrid_preferred(com um alerta emhybrid_preferred), e rejeitado comhybrid_requiredepq_only(VERIFICATION.md V2-7 a V2-9). - §7.3,
pq_only. Os verificadores dos SDKs continuam esperando a vinculaçãopq_over_classicalcom os bytes da assinatura clássica: a assinatura PQ os cobre, entãopq_onlynão permite dispensar o componente clássico. - §6, SignedPayload. O envelope envolve os quatro artefatos principais de um bundle (passaporte, RPR, intenção,
decisão de política). Os registros do DCP-05 ao DCP-09 têm suas assinaturas dentro do objeto, normalmente como
composite_sig; um mandato de delegação raiz temhuman_composite_sige um submandatodelegator_composite_sig(DCP-09 §3.5). - §9 e §15, canonicalização.
dcp-jcs-v1é o único perfil normativo e o padrão. O perfil candidato de docs/proposals/canonicalization-candidate só é acessível por APIs experimentais e opt-in, e não muda o que um verificador padrão aceita. - §10, trilha de auditoria. As entradas de auditoria não são assinadas uma a uma: são cobertas pela assinatura do
bundle por meio do manifesto. O contexto
DCP-AI.v2.AuditEventé usado nos checkpoints PQ e na compactação da auditoria, que quem chama produz com funções auxiliares do SDK; nada os assina automaticamente. Os verificadores checam os checkpoints listados e a cadeia SHA-256; desde@dcp-ai/sdk2.2.1,@dcp-ai/wasm2.1.1,dcp-ai2.10.1 (PyPI), Go v2.11.1 e Rustdcp-ai2.11.1, também checam os campos secundários SHA3-256 presentes (errata do V2-11), o que as versões anteriores não fazem. - §11.3, revogação de emergência. Os schemas do RPR não têm
revocation_token; o passaporte V2 tem umemergency_revocation_tokenopcional. - §12.1, eliminação. O texto descreve o efeito criptográfico de apagar o sal. Não é uma avaliação de conformidade com o RGPD nem com nenhuma outra lei; consulte docs/EU_AI_ACT_MAPPING.md.
- §13, avisos. O servidor de referência aplica os avisos publicados à sua política somente quando um operador chama
POST /v2/advisory/auto-apply; ele verifica acomposite_sigdo aviso apenas quanto à estrutura, e não há consulta periódica automática. - §14.1, tamanhos e latências. As colunas de tamanho do bundle e de latência são ilustrativas, não medições do
código em
main; docs/OPERATOR_GUIDE.md explica como medi-las. - §1.1 e §19, ancoragem. O serviço de ancoragem de referência mantém seus registros localmente e não envia nada para a cadeia (docker/README.md).
- §16, formatos de transmissão. CBOR é um codificador e decodificador opcional apenas do SDK de TypeScript, e o
servidor de referência só lê corpos JSON. O número de 30–40% de redução de tamanho não é respaldado por nenhuma
medição neste repositório.
api/proto/dcp.protoé uma definição: nenhum servidor ou cliente gRPC deste repositório a implementa. - §17, compatibilidade com versões anteriores. A tabela descreve resultados, não um único ponto de entrada.
verifySignedBundleV2dos SDKs só verifica bundles V2.allow_v1_bundlesé lido pelo servidor de referência e pelo perfil de admissão; overifySignedBundleraiz (lib/verify.js) envia os bundles V1 para as verificações V1 sem lê-lo. - §18, pipeline. Na
main,verifySignedBundleV2e seus equivalentes em todos os SDKs executam por conta própria a validação com JSON Schema (passo 2); as versões publicadas dos SDKs não, elib/verify.jse o servidor também a fazem antes de chamar o SDK. Ele não usa o cache de verificação que o SDK de TypeScript exporta (passo 13), e o passo 12 lê o status das chaves que está no bundle; consultar um serviço de revogação cabe à admissão (docs/ADMISSION.md). Verificar não é admitir, confiar nem autorizar.