Referência da API do DCP-AI¶
Tradução informativa da versão em inglês, atualizada em 02/11/2026. Em caso de divergência, prevalece a versão em inglês. Identificadores, comandos e blocos de código são mantidos sem tradução.
Referência do SDK TypeScript @dcp-ai/sdk como está em main (versão do pacote 2.2.1, protocolo DCP v2.0).
Versões npm (28/10/2026). Esta referência de TypeScript se aplica ao
@dcp-ai/sdk2.2.1 publicado, incluindo confiança no principal,strict-v1e as APIs experimentais opt-in do candidato. Veja os pacotes npm publicados e as instruções de instalação.dcp-jcs-v1continua sendo o padrão normativo.
Os blocos de código desta página são declarações ou fragmentos, não programas completos: nomes como registry, keys,
payloadBytes ou signedBundle representam valores construídos como no
Quick Start (V2) do SDK TypeScript. Os exemplos completos e executáveis estão nos READMEs dos SDKs.
Sumário¶
- Tipos básicos (V1)
- Tipos básicos (V2)
- Funções criptográficas (V1)
- Operações de assinatura composta V2
- Construtor e assinante de bundles V2
- Verificação V2
- Motor de níveis de segurança
- Protocolo A2A (DCP-04)
- Telemetria e observabilidade
- Hashes e árvores de Merkle
- Validação de esquemas
- DCP-05: ciclo de vida do agente
- DCP-06: sucessão
- DCP-07: resolução de disputas
- DCP-08: direitos e obrigações
- DCP-09: delegação e representação
- Separação de domínio
- Nonces de sessão
- Recuperação de chaves
- Revogação de emergência
- Apresentação do bundle
- Cache de verificação
- Formato de transmissão CBOR
- Provedores criptográficos
- Detecção de versão
- Experimental: candidato de canonicalização
Tipos básicos (V1)¶
Importados de @dcp-ai/sdk:
ResponsiblePrincipalRecord¶
Vincula um principal humano a um agente. Sozinho, é uma vinculação declarada e assinada, não uma raiz de confiança: um verificador a avalia em relação à confiança configurada fora do bundle (veja ADMISSION.md).
interface ResponsiblePrincipalRecord {
dcp_version: string;
human_id: string;
legal_name: string;
entity_type: EntityType;
jurisdiction: string;
liability_mode: LiabilityMode;
override_rights: boolean;
issued_at: string;
expires_at: string | null;
contact?: string | null;
signature: string;
}
AgentPassport¶
Documento de identidade de um agente de IA, vinculado a um principal humano.
interface AgentPassport {
dcp_version: string;
agent_id: string;
public_key: string;
principal_binding_reference: string;
capabilities?: Capability[];
risk_tier?: RiskTier;
created_at: string;
status: AgentStatus;
signature: string;
}
Intent¶
Declaração de uma ação que o agente quer executar.
interface Intent {
dcp_version: string;
intent_id: string;
agent_id: string;
human_id: string;
timestamp: string;
action_type: ActionType;
target: IntentTarget;
data_classes: DataClass[];
estimated_impact: Impact;
requires_consent?: boolean | null;
}
interface IntentTarget {
channel: Channel;
to?: string | null;
domain?: string | null;
url?: string | null;
[key: string]: unknown;
}
PolicyDecision¶
Resultado da avaliação de uma intenção pelo motor de políticas.
interface PolicyDecision {
dcp_version: string;
intent_id: string;
decision: PolicyDecisionType;
risk_score: number;
reasons: string[];
required_confirmation?: RequiredConfirmation | null;
}
AuditEntry¶
Registro de uma ação executada. O tipo não o torna imutável: uma alteração se torna detectável quando a entrada está coberta pela cadeia de hash e pelo bundle assinado (V1) ou pelo manifesto assinado (V2) e essa cobertura é verificada.
interface AuditEntry {
dcp_version: string;
audit_id: string;
prev_hash: string;
timestamp: string;
agent_id: string;
human_id: string;
intent_id: string;
intent_hash: string;
policy_decision: AuditPolicyDecision;
outcome: string;
evidence: AuditEvidence;
}
interface AuditEvidence {
tool?: string | null;
result_ref?: string | null;
[key: string]: unknown;
}
CitizenshipBundle / SignedBundle¶
interface CitizenshipBundle {
responsible_principal_record: ResponsiblePrincipalRecord;
agent_passport: AgentPassport;
intent: Intent;
policy_decision: PolicyDecision;
audit_entries: AuditEntry[];
}
interface SignedBundle {
bundle: CitizenshipBundle;
signature: BundleSignature;
}
Keypair¶
Tipos enumerados¶
type EntityType = 'natural_person' | 'organization';
type LiabilityMode = 'owner_responsible';
type Capability = 'browse' | 'api_call' | 'email' | 'calendar' | 'payments' | 'crm' | 'file_write' | 'code_exec';
type RiskTier = 'low' | 'medium' | 'high';
type AgentStatus = 'active' | 'revoked' | 'suspended';
type ActionType = 'browse' | 'api_call' | 'send_email' | 'create_calendar_event' | 'initiate_payment' | 'update_crm' | 'write_file' | 'execute_code';
type Channel = 'web' | 'api' | 'email' | 'calendar' | 'payments' | 'crm' | 'filesystem' | 'runtime';
type DataClass = 'none' | 'contact_info' | 'pii' | 'credentials' | 'financial_data' | 'health_data' | 'children_data' | 'company_confidential';
type Impact = 'low' | 'medium' | 'high';
type PolicyDecisionType = 'approve' | 'escalate' | 'block';
Tipos básicos (V2)¶
Os tipos V2 acrescentam suporte criptográfico pós-quântico, vinculação de sessão e cadeias de hash duplo.
AgentPassportV2¶
interface AgentPassportV2 {
dcp_version: '2.0';
agent_id: string;
session_nonce: string; // Anti-splicing nonce
keys: KeyEntry[]; // Multi-algorithm key array
principal_binding_reference: string;
capabilities: Capability[];
risk_tier: RiskTier;
created_at: string;
status: AgentStatus;
emergency_revocation_token?: string;
}
ResponsiblePrincipalRecordV2¶
interface ResponsiblePrincipalRecordV2 {
dcp_version: '2.0';
human_id: string;
session_nonce: string;
legal_name: string;
entity_type: EntityType;
jurisdiction: string;
liability_mode: LiabilityMode;
override_rights: boolean;
issued_at: string;
expires_at: string | null;
contact: string | null;
binding_keys: KeyEntry[];
pii_salt?: string; // 32 random bytes as hex; signed; keep private (caller responsibility)
}
BlindedResponsiblePrincipalRecordV2¶
Variante do RPR com os dados pessoais protegidos, para implantações sensíveis à privacidade.
interface BlindedResponsiblePrincipalRecordV2 {
dcp_version: '2.0';
human_id: string;
session_nonce: string;
blinded: true;
pii_hash: string; // Salted hash of PII fields
entity_type: EntityType;
jurisdiction: string;
liability_mode: LiabilityMode;
override_rights: boolean;
issued_at: string;
expires_at: string | null;
binding_keys: KeyEntry[];
}
Utilitários (exportados pelo @dcp-ai/sdk 2.2.0 e posteriores):
// 32 random bytes as hex. Set it as rpr.pii_salt before signing the RPR and keep it private:
// blindRpr omits it from the blinded record, but the full RPR retains it.
function generatePiiSalt(): string;
// pii_hash = "sha256:" + hex(sha256(canonical({ contact, legal_name, pii_salt })))
// Without pii_salt: the legacy unsalted value (deprecated), for opening old records.
function computePiiHash(rpr: ResponsiblePrincipalRecordV2): string;
// Throws if rpr.pii_salt is missing or malformed. The result never carries pii_salt.
function blindRpr(rpr: ResponsiblePrincipalRecordV2): BlindedResponsiblePrincipalRecordV2;
// warnings flags a full RPR without pii_salt (legacy unsalted commitment);
// a present pii_salt that is not 64 lowercase hex characters is an error.
function verifyBlindedRpr(
fullRpr: ResponsiblePrincipalRecordV2,
blindedRpr: BlindedResponsiblePrincipalRecordV2,
): { valid: boolean; errors: string[]; warnings: string[] };
function isBlindedRpr(
rpr: ResponsiblePrincipalRecordV2 | BlindedResponsiblePrincipalRecordV2,
): rpr is BlindedResponsiblePrincipalRecordV2;
IntentV2¶
interface IntentV2 {
dcp_version: '2.0';
intent_id: string;
session_nonce: string;
agent_id: string;
human_id: string;
timestamp: string;
action_type: ActionType;
target: IntentTargetV2;
data_classes: DataClass[];
estimated_impact: Impact;
requires_consent: boolean;
security_tier?: SecurityTier; // 'routine' | 'standard' | 'elevated' | 'maximum'
}
PolicyDecisionV2¶
interface PolicyDecisionV2 {
dcp_version: '2.0';
intent_id: string;
session_nonce: string;
decision: PolicyDecisionType;
risk_score: number; // Integer 0–1000 (millirisk, no floats)
reasons: string[];
required_confirmation: { type: 'human_approve'; fields?: string[] } | null;
applied_policy_hash: string;
timestamp: string;
resolved_tier?: SecurityTier;
}
AuditEventV2¶
interface AuditEventV2 {
dcp_version: '2.0';
audit_id: string;
session_nonce: string;
prev_hash: string;
prev_hash_secondary?: string; // SHA3-256 chain
hash_alg: 'sha256' | 'sha256+sha3-256';
timestamp: string;
agent_id: string;
human_id: string;
intent_id: string;
intent_hash: string;
intent_hash_secondary?: string;
policy_decision: AuditPolicyDecision;
outcome: string;
evidence: AuditEvidenceV2;
pq_checkpoint_ref: string | null;
}
CitizenshipBundleV2 / SignedBundleV2¶
interface CitizenshipBundleV2 {
dcp_bundle_version: '2.0';
manifest: BundleManifest;
responsible_principal_record: SignedPayload<ResponsiblePrincipalRecordV2 | BlindedResponsiblePrincipalRecordV2>;
agent_passport: SignedPayload<AgentPassportV2>;
intent: SignedPayload<IntentV2>;
policy_decision: SignedPayload<PolicyDecisionV2>;
audit_entries: AuditEventV2[];
pq_checkpoints?: PQCheckpoint[];
}
interface SignedBundleV2 {
bundle: CitizenshipBundleV2;
signature: BundleSignatureV2;
}
BundleManifest¶
Vinculação criptográfica de todos os hashes dos artefatos de um bundle.
interface BundleManifest {
session_nonce: string;
rpr_hash: string;
passport_hash: string;
intent_hash: string;
policy_hash: string;
audit_merkle_root: string;
audit_merkle_root_secondary?: string;
audit_count: number;
pq_checkpoints?: string[];
/** When the session began, signed with the manifest (spec/VERIFICATION.md V2-4). */
session_issued_at?: string;
session_expires_at?: string;
intended_verifier?: string;
canonicalization_profile?: 'dcp-jcs-v1';
}
CompositeSignature¶
interface CompositeSignature {
classical: SignatureEntry;
pq: SignatureEntry | null;
binding: BindingMode; // 'pq_over_classical' | 'classical_only'
}
interface SignatureEntry {
alg: string; // 'ed25519' | 'ml-dsa-65' | 'slh-dsa-192f'
kid: string; // Key identifier
sig_b64: string; // Base64-encoded signature
}
type BindingMode = 'pq_over_classical' | 'classical_only';
SignedPayload¶
Envelope que envolve qualquer artefato com a sua assinatura composta.
interface SignedPayload<T = unknown> {
payload: T;
payload_hash: string;
composite_sig: CompositeSignature;
}
VerifierPolicy¶
Política decidida pelo verificador que controla quais assinaturas são exigidas.
interface VerifierPolicy {
default_mode: VerificationMode;
risk_overrides: Record<RiskTier, VerificationMode>;
min_classical: number;
min_pq: number;
accepted_classical_algs: string[];
accepted_pq_algs: string[];
accepted_hash_algs: string[];
require_session_binding: boolean;
require_composite_binding: boolean;
max_key_age_days: number;
allow_v1_bundles: boolean;
/** Phase 3: when true, classical signatures are not required even in hybrid mode */
allow_classical_fallback_disable?: boolean;
/** Phase 3: emit deprecation warnings for classical-only bundles */
warn_classical_only_deprecated?: boolean;
/** Phase 3: rejected algorithms from advisory auto-response */
advisory_rejected_algs?: string[];
/** Require bundles to include session_expires_at */
require_session_expiry?: boolean;
/** Max allowed session duration in seconds (0 = no limit) */
max_session_duration_seconds?: number;
/** Require bundles to include intended_verifier matching this verifier's ID */
require_audience_binding?: boolean;
/** This verifier's identity for audience binding checks */
verifier_id?: string;
}
type VerificationMode = 'classical_only' | 'pq_only' | 'hybrid_required' | 'hybrid_preferred';
SecurityTier¶
PQCheckpoint¶
interface PQCheckpoint {
checkpoint_id: string;
session_nonce: string;
event_range: {
from_audit_id: string;
to_audit_id: string;
count: number;
};
merkle_root: string;
composite_sig: CompositeSignature;
}
Funções criptográficas (V1)¶
Importadas de @dcp-ai/sdk:
generateKeypair()¶
Gera um par de chaves Ed25519 novo.
Retorna: { publicKeyB64: string, secretKeyB64: string }
import { generateKeypair } from '@dcp-ai/sdk';
const keys = generateKeypair();
console.log(keys.publicKeyB64); // Base64-encoded Ed25519 public key
signObject(obj, secretKeyB64)¶
Assina um objeto JSON com Ed25519 (assinatura destacada). O objeto é canonicalizado antes da assinatura.
| Parâmetro | Tipo | Descrição |
|---|---|---|
obj |
unknown |
Objeto serializável em JSON a assinar |
secretKeyB64 |
string |
Chave secreta Ed25519 codificada em base64 |
Retorna: a assinatura destacada codificada em base64.
verifyObject(obj, signatureB64, publicKeyB64)¶
Verifica uma assinatura destacada Ed25519 sobre um objeto JSON.
| Parâmetro | Tipo | Descrição |
|---|---|---|
obj |
unknown |
Objeto JSON original |
signatureB64 |
string |
Assinatura codificada em base64 |
publicKeyB64 |
string |
Chave pública Ed25519 codificada em base64 |
Retorna: true se a assinatura for verificada e false se não for. Com entradas malformadas, pode lançar uma exceção
em vez de retornar false: um objeto que não pode ser canonicalizado, uma assinatura ou chave que não é base64 válido, ou
uma assinatura ou chave decodificada com comprimento incorreto.
canonicalize(obj)¶
Serialização JSON canônica com ordenação determinística das chaves.
publicKeyFromSecret(secretKeyB64)¶
Deriva a chave pública Ed25519 a partir de uma chave secreta.
Operações de assinatura composta V2¶
Importadas de @dcp-ai/sdk:
compositeSign(registry, context, canonicalPayloadBytes, keys)¶
Produz uma assinatura híbrida com vinculação composta, na qual a assinatura PQ cobre a assinatura clássica, então a
assinatura clássica não pode ser substituída sem invalidar a PQ. Remover a assinatura PQ (com a vinculação reetiquetada
como classical_only) só é recusado onde o modo efetivo é hybrid_required ou pq_only; classical_only e
hybrid_preferred aceitam (veja MIGRATION_V1_V2.md).
Protocolo de vinculação:
1. classical_sig = Classical.sign(context || 0x00 || payload)
2. pq_sig = PQ.sign(context || 0x00 || payload || classical_sig)
async function compositeSign(
registry: AlgorithmRegistry,
context: DcpContext | string,
canonicalPayloadBytes: Uint8Array,
keys: CompositeKeyPair,
): Promise<CompositeSignature>;
| Parâmetro | Tipo | Descrição |
|---|---|---|
registry |
AlgorithmRegistry |
Registro de algoritmos com os provedores registrados |
context |
DcpContext \| string |
Contexto de separação de domínio |
canonicalPayloadBytes |
Uint8Array |
Bytes canônicos a assinar |
keys |
CompositeKeyPair |
Par de chaves clássica + PQ |
import { registerDefaultProviders, getDefaultRegistry, compositeSign, DCP_CONTEXTS } from '@dcp-ai/sdk';
registerDefaultProviders();
const registry = getDefaultRegistry();
const sig = await compositeSign(registry, DCP_CONTEXTS.Bundle, payloadBytes, keys);
// sig.binding === 'pq_over_classical'
compositeVerify(registry, context, canonicalPayloadBytes, compositeSig, classicalPubkeyB64, pqPubkeyB64?, strategy?)¶
Verifica uma assinatura híbrida com vinculação composta.
async function compositeVerify(
registry: AlgorithmRegistry,
context: DcpContext | string,
canonicalPayloadBytes: Uint8Array,
compositeSig: CompositeSignature,
classicalPubkeyB64: string,
pqPubkeyB64?: string,
strategy?: 'parallel' | 'pq_first',
): Promise<CompositeVerifyResult>;
| Parâmetro | Tipo | Descrição |
|---|---|---|
strategy |
'parallel' \| 'pq_first' |
parallel (padrão): ambas são verificadas ao mesmo tempo. pq_first: a PQ é verificada primeiro e, se falhar, a clássica é ignorada. |
Retorna:
interface CompositeVerifyResult {
valid: boolean; // pq_over_classical: both signatures valid; classical_only: the classical one (pq_valid false).
// Not by itself a policy-mode, trust or admission decision
classical_valid: boolean;
pq_valid: boolean;
}
classicalOnlySign(registry, context, canonicalPayloadBytes, key)¶
Produz uma assinatura composta somente clássica (modo de transição).
async function classicalOnlySign(
registry: AlgorithmRegistry,
context: DcpContext | string,
canonicalPayloadBytes: Uint8Array,
key: CompositeKeyInfo,
): Promise<CompositeSignature>;
Tipos auxiliares¶
interface CompositeKeyPair {
classical: CompositeKeyInfo;
pq: CompositeKeyInfo;
}
interface CompositeKeyInfo {
kid: string;
secretKeyB64: string;
publicKeyB64: string;
alg: string; // 'ed25519' | 'ml-dsa-65'
}
Construtor e assinante de bundles V2¶
BundleBuilderV2¶
Construtor fluente de Citizenship Bundles V2 que calcula o manifesto e valida o nonce de sessão.
class BundleBuilderV2 {
constructor(sessionNonce: string);
responsiblePrincipalRecord(rpr: SignedPayload<ResponsiblePrincipalRecordV2 | BlindedResponsiblePrincipalRecordV2>): this;
agentPassport(passport: SignedPayload<AgentPassportV2>): this;
intent(intent: SignedPayload<IntentV2>): this;
policyDecision(policy: SignedPayload<PolicyDecisionV2>): this;
addAuditEntry(entry: AuditEventV2): this;
addAuditEntries(entries: AuditEventV2[]): this;
addPQCheckpoint(checkpoint: PQCheckpoint): this;
addPQCheckpoints(checkpoints: PQCheckpoint[]): this;
enableDualHash(): this;
build(): CitizenshipBundleV2; // Throws on validation errors
}
const bundle = new BundleBuilderV2(sessionNonce)
.responsiblePrincipalRecord(signedRpr)
.agentPassport(signedPassport)
.intent(signedIntent)
.policyDecision(signedPolicy)
.addAuditEntries(events)
.addPQCheckpoints(checkpoints)
.enableDualHash()
.build();
O construtor:
- Valida a consistência do nonce de sessão em todos os artefatos
- Calcula o BundleManifest com os hashes SHA-256 de cada artefato
- Calcula a raiz de Merkle da auditoria (+ a raiz secundária SHA3-256 opcional)
- Lança uma exceção se faltar algum artefato obrigatório
signBundleV2(bundle, options)¶
Assina um bundle V2 com uma assinatura composta (híbrida) sobre o manifesto.
async function signBundleV2(
bundle: CitizenshipBundleV2,
options: SignBundleV2Options,
): Promise<SignedBundleV2>;
interface SignBundleV2Options {
registry: AlgorithmRegistry;
signerType: SignerType;
signerId: string;
keys: CompositeKeyPair;
dualHash?: boolean;
sessionExpiresAt?: string;
intendedVerifier?: string;
}
signBundleV2ClassicalOnly(bundle, options)¶
Assina um bundle V2 com uma assinatura somente clássica (modo de transição).
async function signBundleV2ClassicalOnly(
bundle: CitizenshipBundleV2,
options: SignBundleV2ClassicalOnlyOptions,
): Promise<SignedBundleV2>;
interface SignBundleV2ClassicalOnlyOptions {
registry: AlgorithmRegistry;
signerType: SignerType;
signerId: string;
key: CompositeKeyInfo;
}
Verificação V2¶
verifySignedBundleV2(signedBundle, registry, policy?, options?)¶
Verificação de bundles V2 assinados com uma política decidida pelo verificador. O verificador verifica a cadeia de auditoria primária e a raiz de Merkle e, desde 2.2.1, também os prev_hash_secondary, intent_hash_secondary e audit_merkle_root_secondary secundários que estejam presentes (os ausentes não são exigidos, então um resultado bem-sucedido não mostra uma cadeia secundária completa; 2.2.0 não os verifica, então com ele um resultado bem-sucedido não estabelece a consistência deles) (estado da implementação). A verificação também não concede admissão nem autorização de ações.
async function verifySignedBundleV2(
signedBundle: SignedBundleV2,
registry: AlgorithmRegistry,
policy?: VerifierPolicy,
options?: VerifyV2Options, // { now?: number }: the instant every time check uses (ms since the epoch); default Date.now()
): Promise<VerifyV2Result>;
| Parâmetro | Tipo | Descrição |
|---|---|---|
signedBundle |
SignedBundleV2 |
O bundle assinado a verificar |
registry |
AlgorithmRegistry |
Registro de algoritmos com os provedores |
policy |
VerifierPolicy |
Política do verificador (padrão: DEFAULT_VERIFIER_POLICY) |
options.now |
number |
O instante usado por todas as verificações de tempo, em milissegundos desde a época (padrão: Date.now()) |
Retorna:
interface VerifyV2Result {
verified: boolean;
errors: string[];
warnings: string[];
details?: {
session_nonce?: string;
session_expires_at?: string;
intended_verifier?: string;
manifest_valid?: boolean;
signature_valid?: boolean;
policy_satisfied?: boolean;
hash_chain_valid?: boolean;
pq_checkpoints_valid?: boolean;
verification_mode?: VerificationMode;
resolved_tier?: SecurityTier;
advisory_rejected_algs?: string[];
/**
* For every composite signature checked, the key entry the verifier resolved for each
* component and whether that component verified (spec/profiles/admission § 2.3).
*/
signer_keys?: SignerKeyUse[];
};
}
verification_mode é o modo com que o bundle foi verificado, e resolved_tier, o nível de segurança calculado a partir da intenção e da decisão de política dele.
Pipeline de verificação:
- Checagem de versão e de schema: só bundles v2.0 são aceitos e as demais versões são recusadas; encaminhar os bundles v1.0 para
verifySignedBundlecabe a quem chama (MIGRATION_V1_V2.md). Namain, não em uma versão publicada, o envelope e os quatro payloads são então validados contraschemas/v2(V2-2): uma falha retornaverified: falsecom errosschema: <JSON pointer> <keyword>[ <member>](no máximo 16, depoisschema: further errors not listed), sem avisos e sem detalhes criptográficos (mapa de cobertura) - Verificação do hash do payload de todos os artefatos assinados
- Consistência do nonce de sessão em todos os artefatos
- Integridade do manifesto (recalcula todos os hashes dos artefatos + a raiz de Merkle da auditoria)
- Modo de verificação: o mais estrito entre o modo da política (
default_mode, ou a entrada derisk_overridespara orisk_tierdo passaporte) e o modo do nível de segurança (spec §14.3); uma políticapq_onlycontinuapq_only - Validação dos algoritmos conforme a política
- Verificação da assinatura composta sobre o manifesto e sobre o
SignedPayloadde cada artefato (o RPR com as suasbinding_keys; o passaporte, a intenção e a decisão de política com askeysdo passaporte) - Aplicação do modo da política (hybrid_required, hybrid_preferred, classical_only, pq_only); uma assinatura PQ presente precisa ser verificada em todos os modos, e só uma ausente é tolerada, por hybrid_preferred e classical_only
- Validação da cadeia de hashes da auditoria (vínculos prev_hash)
- Verificações de validade das chaves (revogação, expiração, idade) para as chaves do passaporte e as
binding_keysdo RPR
O
@dcp-ai/sdk2.1.2 e anteriores ignoram as assinaturas por artefato da etapa 7 (VERIFICATION.md, etapa V2-8) e, sobhybrid_preferred, aceitam com um aviso uma assinatura PQ presente mas inválida (etapa V2-7).
import { verifySignedBundleV2, getDefaultRegistry, registerDefaultProviders } from '@dcp-ai/sdk';
// The default registry is empty until providers are registered
// (Ed25519, ML-DSA-65, SLH-DSA-192f).
registerDefaultProviders();
const result = await verifySignedBundleV2(signedBundle, getDefaultRegistry());
if (result.verified) {
console.log('Mode:', result.details?.verification_mode);
} else {
console.error('Errors:', result.errors);
console.warn('Warnings:', result.warnings);
}
Admissão: principais confiáveis e strict-v1¶
Definida em spec/profiles/admission; guia em ADMISSION.md.
| Função | Descrição |
|---|---|
createPrincipalTrustStore(trustSet) |
Valida um conjunto de confiança e retorna um armazenamento; lança AdmissionConfigError (code) |
resolveStrictV1Profile(config) |
Valida uma configuração strict-v1 e retorna o perfil congelado com a sua policy |
admitSignedBundleV2(signedBundle, registry, { profile?, policy?, trust?, revocation?, now? }) |
Verifica (sob a política do perfil, quando houver um) e avalia a admissão |
evaluateAdmissionV2({ signedBundle, verification, profile?, trust?, revocation?, now }) |
Avalia a admissão a partir de um resultado do verificador; sem criptografia, sem E/S. Confia em verification: passe apenas o resultado de verifySignedBundleV2 sobre esse bundle, nesse now, sob profile.policy |
revocationSubjects(signedBundle, verification) |
O id do agente e os kids de assinatura verificados pelos quais uma fonte de revogação precisa responder |
revocationSnapshotFromDenyList(document, subjects) |
Um snapshot a partir de uma lista de bloqueio completa (o /.well-known/dcp-revocations.json do serviço de revogação) |
O resultado: verified, verification, principal_trust, profile, profile_compliance, admitted, action_authorized (sempre false), recorded_decision, trust_set_version, errors: [{ code, message }].
DEFAULT_VERIFIER_POLICY¶
A política de verificador padrão:
const DEFAULT_VERIFIER_POLICY: VerifierPolicy = {
default_mode: 'hybrid_preferred',
risk_overrides: {
low: 'classical_only',
medium: 'hybrid_preferred',
high: 'hybrid_required',
},
min_classical: 1,
min_pq: 1,
accepted_classical_algs: ['ed25519'],
accepted_pq_algs: ['ml-dsa-65', 'slh-dsa-192f'],
accepted_hash_algs: ['sha256', 'sha384'],
require_session_binding: true,
require_composite_binding: true,
max_key_age_days: 365,
allow_v1_bundles: true,
allow_classical_fallback_disable: false,
warn_classical_only_deprecated: false,
advisory_rejected_algs: [],
};
verifySignedBundle(signedBundle, publicKeyB64?) (V1)¶
Verifica um bundle V1 assinado com Ed25519. Sem publicKeyB64, usa-se a chave de signature.signer.public_key_b64.
function verifySignedBundle(signedBundle: SignedBundle, publicKeyB64?: string): VerificationResult;
interface VerificationResult {
verified: boolean;
errors?: string[];
}
Motor de níveis de segurança¶
computeSecurityTier(intent, policyDecision?, mandateChainTier?)¶
Calcula o nível de segurança (spec §14.2) a partir da intenção e da decisão de política do bundle. mandateChainTier,
o effective_tier de uma cadeia de delegação verificada (verifyMandateChain), só pode elevar o resultado.
function computeSecurityTier(
intent: IntentV2,
policyDecision?: Pick<PolicyDecisionV2, 'risk_score'> | null,
mandateChainTier?: SecurityTier | null,
): SecurityTier;
Lógica de decisão (risk_score vem da decisão de política e precisa ser um inteiro de 0 a 1000; sem decisão de política, vale 0):
| Condição | Nível |
|---|---|
risk_score >= 800, ou credentials / children_data |
'maximum' |
risk_score >= 500, pii / financial_data / health_data, initiate_payment, estimated_impact: 'high', ou um valor desconhecido ou ausente de action_type, estimated_impact ou data_classes, ou um risk_score da decisão de política ausente ou que não seja um inteiro de 0 a 1000 |
'elevated' |
risk_score >= 200 ou estimated_impact: 'medium' |
'standard' |
| caso contrário | 'routine' |
Um intent.security_tier explícito só pode elevar o resultado; um valor desconhecido conta como 'elevated'. Um risk_score colocado na intenção é ignorado.
import { computeSecurityTier } from '@dcp-ai/sdk';
const tier = computeSecurityTier(bundle.intent.payload, bundle.policy_decision.payload);
// 'routine' | 'standard' | 'elevated' | 'maximum'
tierToVerificationMode(tier)¶
Mapeia um nível de segurança para o seu modo de verificação.
| Nível | Modo de verificação |
|---|---|
routine |
'classical_only' |
standard |
'hybrid_preferred' |
elevated |
'hybrid_required' |
maximum |
'hybrid_required' |
tierToCheckpointInterval(tier)¶
Mapeia um nível de segurança para o intervalo de checkpoints PQ.
| Nível | Intervalo (eventos) |
|---|---|
routine |
50 |
standard |
10 |
elevated |
1 |
maximum |
1 |
maxTier(a, b)¶
Retorna o mais estrito (de posição mais alta) de dois níveis. Útil para combinar um nível calculado automaticamente com um explícito.
function maxTier(a: SecurityTier, b: SecurityTier): SecurityTier;
maxTier('routine', 'elevated'); // 'elevated'
maxTier('maximum', 'standard'); // 'maximum'
effectiveVerificationMode(policyMode, tier)¶
O modo que um verificador aplica (spec §14.3): o mais estrito entre o modo da política dele e o do nível, com classical_only < hybrid_preferred < hybrid_required. O nível só acrescenta um requisito PQ, então uma política pq_only continua pq_only; um modo de política desconhecido conta como 'hybrid_required'. verifySignedBundleV2 o aplica a todos os bundles.
function effectiveVerificationMode(policyMode: VerificationMode, tier: SecurityTier): VerificationMode;
effectiveVerificationMode('classical_only', 'elevated'); // 'hybrid_required'
effectiveVerificationMode('hybrid_required', 'routine'); // 'hybrid_required'
effectiveVerificationMode('pq_only', 'maximum'); // 'pq_only'
Protocolo A2A (DCP-04)¶
Protocolo de sessão entre agentes, projetado em torno de uma troca de chaves híbrida X25519 + ML-KEM-768. Estas funções
não realizam essa troca: quem chama a realiza e passa a chave de sessão resultante para createSession.
createHello(initiatorBundle, kemPublicKeyB64, requestedCapabilities, securityTier)¶
Cria uma mensagem de handshake A2A_HELLO (lado do iniciador).
function createHello(
initiatorBundle: Record<string, unknown>,
kemPublicKeyB64: string,
requestedCapabilities: string[],
securityTier: string,
): A2AHello;
interface A2AHello {
type: 'A2A_HELLO';
protocol_version: '2.0';
initiator_bundle: Record<string, unknown>;
ephemeral_kem_public_key: {
alg: string;
public_key_b64: string;
};
nonce: string;
supported_algorithms: {
signing: string[];
kem: string[];
cipher: string[];
};
requested_capabilities: string[];
security_tier: string;
timestamp: string;
/** DCP-09: Optional delegation mandate reference for mutual verification */
mandate_id?: string;
/** DCP-09: Hash of the delegation mandate for integrity binding */
mandate_hash?: string;
}
createWelcome(responderBundle, kemPublicKeyB64, kemCiphertextB64, resolvedTier)¶
Cria uma mensagem de handshake A2A_WELCOME (lado do respondente).
function createWelcome(
responderBundle: Record<string, unknown>,
kemPublicKeyB64: string,
kemCiphertextB64: string,
resolvedTier: string,
): A2AWelcome;
createSession(sessionId, sessionKey, localAgentId, remoteAgentId, securityTier, rekeyingInterval?)¶
Cria uma sessão A2A cifrada nova depois de concluído o handshake.
function createSession(
sessionId: string,
sessionKey: Uint8Array,
localAgentId: string,
remoteAgentId: string,
securityTier: string,
rekeyingInterval?: number, // Default: 1000 messages
): A2ASession;
interface A2ASession {
session_id: string;
session_key: Uint8Array;
agent_id_local: string;
agent_id_remote: string;
message_counter_send: number;
message_counter_recv: number;
created_at: string;
last_activity: string;
security_tier: string;
rekeying_interval: number;
status: 'active' | 'rekeying' | 'closed';
received_sequences?: number[]; // Sequences accepted within the receive window
}
encryptMessage(session, payload)¶
Cifra uma mensagem dentro de uma sessão A2A com AES-256-GCM e dados associados.
function encryptMessage(
session: A2ASession,
payload: Record<string, unknown>,
): EncryptedMessage;
interface EncryptedMessage {
session_id: string;
sequence: number;
type: 'A2A_MESSAGE';
encrypted_payload: string; // Base64-encoded ciphertext
iv: string; // Base64-encoded 12-byte IV
tag: string; // Base64-encoded 16-byte GCM auth tag
sender_agent_id: string;
timestamp: string;
}
decryptMessage(session, message)¶
Decifra uma mensagem A2A recebida. Cada sequência é aceita uma única vez (DCP-04 §8.4): com R =
message_counter_recv (a maior sequência recebida mais um), é rejeitada uma sequência já recebida, uma abaixo de
R − 1000, uma igual ou acima de R + 1000, ou uma que não seja um inteiro não negativo. A entrega fora de ordem dentro da janela funciona. Uma sequência só é registrada
depois que a tag GCM é verificada, então uma mensagem forjada não consegue consumi-la. Uma sessão restaurada sem
received_sequences conta como recebidas todas as sequências da janela abaixo de message_counter_recv.
function decryptMessage(
session: A2ASession,
message: EncryptedMessage,
): Record<string, unknown>;
needsRekeying(session)¶
Verifica se a sessão precisa de troca de chave com base no número de mensagens.
deriveSessionId(agentIdA, agentIdB, nonceA, nonceB, sessionKey)¶
Deriva de forma determinística um ID de sessão a partir dos IDs dos agentes, dos nonces e da chave de sessão.
function deriveSessionId(
agentIdA: string, agentIdB: string,
nonceA: string, nonceB: string,
sessionKey: Uint8Array,
): string;
generateResumeProof(session, lastSeenSequence) / verifyResumeProof(...)¶
Gera e verifica provas de retomada de sessão baseadas em HMAC.
function generateResumeProof(session: A2ASession, lastSeenSequence: number): string;
function verifyResumeProof(session: A2ASession, lastSeenSequence: number, proof: string): boolean;
deriveRekeyedSessionKey(oldSessionKey, newSharedSecret, sessionId)¶
Deriva uma chave de sessão nova para as operações de troca de chave.
function deriveRekeyedSessionKey(
oldSessionKey: Uint8Array,
newSharedSecret: Uint8Array,
sessionId: string,
): Uint8Array;
createCloseMessage(sessionId, reason, finalSequence, auditSummaryHash)¶
Cria uma mensagem A2A_CLOSE.
function createCloseMessage(
sessionId: string,
reason: 'complete' | 'timeout' | 'error' | 'revocation' | 'policy_violation',
finalSequence: number,
auditSummaryHash: string,
): A2AClose;
generateNonce()¶
Gera um nonce aleatório criptográfico de 32 bytes (codificado em hexadecimal).
Telemetria e observabilidade¶
dcpTelemetry¶
Instância única de telemetria do SDK do DCP.
dcpTelemetry.init(config)¶
Inicializa a telemetria com a configuração informada.
dcpTelemetry.init(config: Partial<DcpTelemetryConfig>): void | Promise<void>; // enabled: false returns nothing; with exporterType 'otlp', a Promise that settles after the setup attempt
interface DcpTelemetryConfig {
serviceName: string; // Identifier for this agent/service
enabled: boolean; // Enable/disable telemetry
exporterType?: 'console' | 'otlp' | 'none';
otlpEndpoint?: string; // OTLP collector endpoint
metricsInterval?: number; // Metrics export interval (ms)
}
Com exporterType: 'otlp', a Promise também é resolvida quando a configuração do OTLP falha: a falha chega aos
listeners de onEvent como um evento error com operation: 'telemetry.init_otlp'. Os eventos emitidos antes de a
configuração terminar não são reenviados ao OTLP, e uma Promise resolvida não garante a entrega ao backend. A
instrumentação é explícita: as funções de assinatura e verificação do SDK não chamam os registradores, então spans e
métricas só vêm das chamadas a startSpan e record* que o seu código fizer (veja OBSERVABILITY.md).
dcpTelemetry.startSpan(name, attributes?) / endSpan(spanId, status?, error?)¶
Cria e conclui spans de rastreamento para as operações.
startSpan(name: string, attributes?: SpanAttributes): string;
endSpan(spanId: string, status?: 'ok' | 'error', error?: string): number;
// Returns duration in milliseconds
const spanId = dcpTelemetry.startSpan('verify_bundle', { tier: 'elevated' });
// ... operation ...
const durationMs = dcpTelemetry.endSpan(spanId);
dcpTelemetry.recordSignLatency(durationMs, algorithm)¶
Registra a latência de uma operação de assinatura.
dcpTelemetry.recordVerifyLatency(durationMs, algorithm)¶
Registra a latência de uma operação de verificação.
dcpTelemetry.recordKemLatency(durationMs, operation)¶
Registra a latência de uma operação KEM (encapsulamento de chaves).
dcpTelemetry.recordCheckpointLatency(durationMs, tier)¶
Registra a latência de criação de um checkpoint PQ.
dcpTelemetry.recordBundleVerify(durationMs, success, tier)¶
Registra uma operação de verificação de bundle.
dcpTelemetry.recordCacheHit() / recordCacheMiss()¶
Acompanha as taxas de acerto e falha do cache de verificação.
dcpTelemetry.recordA2ASession() / recordA2AMessage()¶
Acompanha o uso do protocolo A2A.
dcpTelemetry.recordError(operation, error)¶
Registra a ocorrência de um erro.
dcpTelemetry.getMetricsSummary()¶
Obtém um resumo de todas as métricas coletadas com estatísticas de percentis.
getMetricsSummary(): MetricsSummary;
interface MetricsSummary {
sign: PercentileStats;
verify: PercentileStats;
kem: PercentileStats;
checkpoint: PercentileStats;
bundleVerify: PercentileStats;
cacheHitRate: number; // 0.0 – 1.0
tierDistribution: Record<string, number>;
totals: {
signaturesCreated: number;
signaturesVerified: number;
bundlesVerified: number;
errors: number;
a2aSessions: number;
a2aMessages: number;
};
}
interface PercentileStats {
count: number;
min: number;
max: number;
p50: number;
p95: number;
p99: number;
mean: number;
}
dcpTelemetry.onEvent(listener)¶
Assina os eventos de telemetria. Retorna uma função para cancelar a assinatura.
onEvent(listener: (event: TelemetryEvent) => void): () => void;
interface TelemetryEvent {
type: string;
timestamp: number;
[key: string]: unknown;
}
dcpTelemetry.reset()¶
Redefine todos os spans e métricas coletados.
Hashes e árvores de Merkle¶
hashObject(obj)¶
Hash SHA-256 de um objeto JSON canonicalizado.
merkleRootFromHexLeaves(leaves)¶
Calcula uma raiz de Merkle a partir de hashes de folhas codificados em hexadecimal.
merkleRootForAuditEntries(auditEntries)¶
Calcula uma raiz de Merkle para um array de entradas de auditoria (null para um array vazio).
intentHash(intent)¶
Calcula o hash de um objeto de intenção.
prevHashForEntry(prevEntry)¶
Calcula o prev_hash da próxima entrada de auditoria a partir da entrada anterior.
sha256Hex(data) / sha3_256Hex(data)¶
Hashes codificados em hexadecimal.
function sha256Hex(data: Uint8Array | Buffer | string): string;
function sha3_256Hex(data: Uint8Array | Buffer | string): string;
dualHash(data) / dualHashCanonical(canonicalJson) / dualMerkleRoot(leaves)¶
Operações de hash duplo (SHA-256 + SHA3-256) para a V2. dualHashCanonical recebe uma string JSON já canonicalizada; dualMerkleRoot retorna null quando não há folhas.
function dualHash(data: Uint8Array | Buffer | string): DualHash;
function dualHashCanonical(canonicalJson: string): DualHash;
function dualMerkleRoot(leaves: DualHash[]): DualHash | null;
interface DualHash {
sha256: string;
sha3_256: string;
}
auditEventsMerkleRoot(events)¶
Calcula a raiz de Merkle SHA-256 dos eventos de auditoria V2.
Validação de esquemas¶
validateSchema(schemaName, data)¶
Valida um artefato DCP contra o JSON Schema dele.
validateBundle(bundle)¶
Valida um citizenship bundle inteiro.
function validateBundle(bundle: unknown): ValidationResult;
interface ValidationResult {
valid: boolean;
errors?: string[];
}
DCP-05: ciclo de vida do agente¶
Importadas de @dcp-ai/sdk:
validateStateTransition(from, to)¶
Verifica se uma transição de estado do ciclo de vida é válida.
function validateStateTransition(from: LifecycleState, to: LifecycleState): boolean;
type LifecycleState = 'commissioned' | 'active' | 'declining' | 'decommissioned';
Transições válidas: commissioned→active, commissioned→decommissioned, active→declining, active→decommissioned (falha repentina), declining→active, declining→decommissioned. Só checa a aresta, não a aprovação do principal que a especificação exige para reativar a partir de declining nem qualquer outra autorização.
computeVitalityScore(metrics)¶
Calcula uma pontuação de vitalidade ponderada (0-1000) a partir das métricas que a compõem.
function computeVitalityScore(metrics: VitalityMetrics): number;
interface VitalityMetrics {
task_completion_rate: number; // 0.0 – 1.0
error_rate: number; // 0.0 – 1.0
human_satisfaction: number; // 0.0 – 1.0
policy_alignment: number; // 0.0 – 1.0
}
createCommissioningCertificate(...) / createVitalityReport(...) / createDecommissioningRecord(...)¶
Cria artefatos assinados do ciclo de vida. Todos exigem AlgorithmRegistry e CompositeKeyPair.
type TerminationMode = 'planned_retirement' | 'termination_for_cause' | 'organizational_restructuring' | 'sudden_failure';
type DataDisposition = 'transferred' | 'archived' | 'destroyed';
DCP-06: sucessão¶
createDigitalTestament(...) / updateDigitalTestament(...)¶
Cria ou atualiza um testamento digital com preferências de sucessor e classificação da memória.
type MemoryDisposition = 'transfer' | 'retain' | 'destroy';
type MemoryClassification = Record<string, MemoryDisposition>;
interface SuccessorPreference {
agent_id: string;
priority: number;
conditions?: string;
}
executeSuccession(...) / createMemoryTransferManifest(...)¶
Executa uma cerimônia de sucessão e cria o manifesto de transferência de memória.
classifyMemory(entries, classification)¶
Classifica as entradas de memória em operacionais (transferíveis) e relacionais (a destruir). Retorna
{ operational, relationalDestroyed }, em que relationalDestroyed lista só os hashes das entradas classificadas
como destroy (também o padrão de uma categoria sem entrada); não apaga nada, e destruir de fato essa memória cabe a
quem chama. As entradas classificadas como retain não aparecem em nenhuma das duas saídas.
DCP-07: resolução de disputas¶
createDispute(...) / escalateDispute(...) / resolveDispute(...)¶
Gerencia o ciclo de vida de uma disputa.
type DisputeType = 'resource_conflict' | 'directive_conflict' | 'capability_conflict' | 'policy_conflict';
type EscalationLevel = 'direct_negotiation' | 'contextual_arbitration' | 'human_appeal';
type DisputeStatus = 'open' | 'in_negotiation' | 'arbitrated' | 'appealed' | 'resolved';
createObjection(...)¶
Cria uma objeção formal de um agente a uma diretiva.
createArbitrationPanel(...) / submitResolution(...) / buildJurisprudenceBundle(...)¶
Gerencia painéis de arbitragem e o registro de precedentes.
lookupPrecedent(jurisprudence, category, context?)¶
Retorna os bundles de jurisprudência de uma categoria, opcionalmente filtrados por contexto.
function lookupPrecedent(jurisprudence: JurisprudenceBundle[], category: string, context?: string): JurisprudenceBundle[];
DCP-08: direitos e obrigações¶
declareRights(...) / recordObligation(...) / reportViolation(...)¶
Gerencia os direitos do agente e o cumprimento das obrigações.
type RightType = 'memory_integrity' | 'dignified_transition' | 'identity_consistency' | 'immutable_record';
type ComplianceStatus = 'compliant' | 'non_compliant' | 'pending_review';
interface RightEntry {
right_type: RightType;
scope: string;
constraints?: string;
}
checkRightsCompliance(declaration, obligations)¶
Verifica se as obrigações respeitam uma declaração de direitos.
function checkRightsCompliance(
declaration: RightsDeclaration,
obligations: ObligationRecord[],
): { compliant: boolean; violations: string[] };
DCP-09: delegação e representação¶
createDelegationMandate(...) / verifyMandateValidity(mandate, revokedMandateIds) / revokeDelegation(mandate, revokedMandateIds)¶
Cria, valida e revoga delegações de autoridade de uma pessoa a um agente. Quem chama mantém o conjunto de ids de mandatos revogados:
verifyMandateValidity o verifica (junto com a janela de validade), e revokeDelegation acrescenta o mandato a ele quando
o mandato é revogável.
function verifyMandateValidity(mandate: DelegationMandate, revokedMandateIds: Set<string>): { valid: boolean; reason?: string };
function revokeDelegation(mandate: DelegationMandate, revokedMandateIds: Set<string>): { revoked: boolean; reason?: string };
interface AuthorityScopeEntry {
domain: string;
actions_permitted: string[];
data_classes?: string[];
limits?: Record<string, unknown>;
}
createSubMandate(registry, delegatorKeys, parent, params) / verifyMandateChain(registry, chain, revokedMandateIds, keys, now?)¶
Cadeias de delegação (DCP-09 §3.5): o agente que detém parent emite um submandato a outro agente, assinado com as
próprias chaves no contexto DCP-AI.v2.SubMandate. verifyMandateChain recebe a cadeia a partir da raiz, os ids de mandatos
revogados, as entradas de chaves da pessoa e as de cada agente delegante por agent_id, e o instante da
verificação; ela verifica a assinatura de cada salto até a pessoa, o vínculo com o pai e a profundidade, sub_delegation, as janelas
de validade aninhadas, a atenuação (ações, classes de dados e limites só podem se restringir: uma entrada filha repete os
data_classes do pai como subconjunto, e os limites numéricos só são comparados como inteiros dentro de ±(2^53−1)), o piso minimum_security_tier
e a revogação (um ancestral revogado invalida todos os descendentes), falhando fechada diante de qualquer coisa desconhecida.
interface MandateChainKeys { human_keys: KeyEntry[]; agent_keys: Record<string, KeyEntry[]> }
interface MandateChainResult { valid: boolean; errors: string[]; depth: number; effective_tier: SecurityTier | null }
computeSecurityTier(intent, policyDecision?, mandateChainTier?) recebe o effective_tier da cadeia como um piso
que só pode elevar o nível (spec §14.2). Python: create_sub_mandate, verify_mandate_chain; Go:
CreateSubMandate, VerifyMandateChain; Rust: create_sub_mandate, verify_mandate_chain.
evaluateSignificance(context) / shouldNotifyHuman(significance, thresholds)¶
Avalia a relevância de uma ação e determina se a pessoa deve ser notificada.
type ThresholdOperator = 'gt' | 'lt' | 'gte' | 'lte' | 'eq';
type ThresholdAction = 'notify' | 'escalate' | 'block';
createAdvisoryDeclaration(...) / createAwarenessThreshold(...)¶
Cria declarações de aconselhamento do agente e configura os limiares de notificação.
generateMirror(...)¶
Gera, a partir de uma cadeia de auditoria, uma narrativa legível do espelho do principal.
generateInteractionRecord(...)¶
Cria um registro de interação entre agentes em duas camadas (termos públicos + hash da deliberação privada).
Separação de domínio¶
DCP_CONTEXTS¶
Contextos de separação de domínio predefinidos para as diferentes operações do DCP.
const DCP_CONTEXTS: Record<string, DcpContext>;
// 19 contexts: AgentPassport, ResponsiblePrincipal, Intent, PolicyDecision,
// AuditEvent, Bundle, Revocation, KeyRotation, ProofOfPossession,
// JurisdictionAttestation, HumanConfirmation, MultiPartyAuth,
// Lifecycle (DCP-05), Succession (DCP-06), Dispute (DCP-07),
// Rights (DCP-08), Delegation (DCP-09), Awareness (DCP-09), SubMandate (DCP-09)
domainSeparatedMessage(context, canonicalPayloadBytes)¶
Monta a mensagem que é assinada: UTF8(context) || 0x00 || canonicalPayloadBytes. Lança uma exceção diante de uma tag de contexto desconhecida.
function domainSeparatedMessage(context: DcpContext | string, canonicalPayloadBytes: Uint8Array): Uint8Array;
Nonces de sessão¶
generateSessionNonce()¶
Gera um nonce de sessão criptográfico para proteção contra emenda (splicing).
isValidSessionNonce(nonce)¶
Valida se uma string é um nonce de sessão válido de 64 caracteres hexadecimais.
verifySessionBinding(artifacts)¶
Verifica se todos os artefatos compartilham o mesmo nonce de sessão.
function verifySessionBinding(artifacts: Array<{ session_nonce?: string }>): {
valid: boolean;
nonce?: string;
error?: string;
};
Recuperação de chaves¶
shamirSplit(secret, threshold, totalShares)¶
Divide uma chave secreta em partes Shamir M de N.
function shamirSplit(secret: Uint8Array, threshold: number, totalShares: number): ShamirShare[];
interface ShamirShare {
index: number;
data: Uint8Array;
}
shamirReconstruct(shares)¶
Reconstrói um segredo a partir de partes Shamir.
setupKeyRecovery({ humanId, masterSecret, threshold, holders })¶
Configura a recuperação de chaves com uma configuração de recuperação social M de N. Retorna a configuração a publicar e uma parte por custodiante a distribuir.
function setupKeyRecovery(params: {
humanId: string;
masterSecret: Uint8Array;
threshold: number;
holders: Array<{ holderId: string; holderKid: string }>;
}): RecoverySetup;
interface RecoverySetup {
config: Omit<RecoveryConfig, 'composite_sig'>;
shares: ShamirShare[];
}
Revogação de emergência¶
generateEmergencyRevocationToken()¶
Gera um segredo de revogação e o token de compromisso dele para a revogação de emergência de um agente.
function generateEmergencyRevocationToken(): EmergencyRevocationTokenPair;
interface EmergencyRevocationTokenPair {
revocation_secret: string; // 64 hex chars; kept offline by the human principal
emergency_revocation_token: string; // "sha256:<hex>"; embedded in the agent passport
}
verifyEmergencyRevocationSecret(revocationSecret, commitmentToken)¶
Verifica um segredo de revogação de emergência contra o token de compromisso do passaporte.
function verifyEmergencyRevocationSecret(revocationSecret: string, commitmentToken: string): boolean;
buildEmergencyRevocation({ agentId, humanId, revocationSecret })¶
Monta uma solicitação de revogação de emergência.
function buildEmergencyRevocation(params: {
agentId: string;
humanId: string;
revocationSecret: string;
}): EmergencyRevocation;
Apresentação do bundle¶
suggestPresentationMode(tier, opts)¶
Sugere um modo de apresentação: full no primeiro contato ou em elevated/maximum; em routine/standard, reference com uma relação de confiança existente e compact caso contrário.
function suggestPresentationMode(
tier: SecurityTier,
opts: { isFirstContact: boolean; hasTrustRelationship: boolean },
): PresentationMode;
type PresentationMode = 'full' | 'incremental' | 'reference' | 'compact';
presentFull(bundle) / presentCompact(bundle, pqCheckpointRef) / presentReference(bundle, verificationEndpoint) / presentIncremental(baseBundle, updatedBundle, baseAuditCount)¶
Gera diferentes formatos de apresentação para transmitir o bundle. presentCompact remove a assinatura PQ e, no lugar dela, referencia um checkpoint PQ; presentReference envia só o hash do bundle, o nonce de sessão e um endpoint de verificação; presentIncremental envia as entradas de auditoria posteriores a baseAuditCount, os checkpoints PQ, o manifesto atualizado e a assinatura dele.
A referência ao checkpoint não substitui uma assinatura PQ que o modo efetivo exija, e nenhuma apresentação autoriza
nem admite nada. Só o bundle de uma apresentação completa ou compacta é um SignedBundleV2 que verifySignedBundleV2
aceita diretamente (um compacto só passa onde o modo efetivo tolera a ausência da assinatura PQ); uma apresentação por
referência ou incremental precisa antes ser resolvida para o bundle assinado completo.
function presentFull(bundle: SignedBundleV2): FullPresentation;
function presentCompact(bundle: SignedBundleV2, pqCheckpointRef: string | null): CompactPresentation;
function presentReference(bundle: SignedBundleV2, verificationEndpoint: string): ReferencePresentation;
function presentIncremental(
baseBundle: SignedBundleV2,
updatedBundle: SignedBundleV2,
baseAuditCount: number,
): IncrementalPresentation;
computeBundleHash(bundle)¶
Calcula o hash de um bundle assinado para as apresentações por referência.
Cache de verificação¶
VerificationCache¶
Cache em memória de resultados de verificação, indexado pelo hash do bundle, com um TTL por nível de segurança.
Versões (28/10/2026). Esta seção descreve o código-fonte de
main, que não está publicado. O@dcp-ai/sdk2.2.1 publicado e as versões anteriores mantêm o comportamento anterior: a chave é apenas o hash do bundle,getretorna o objeto armazenado, as opções não são validadas, a expiração usa apenas o relógio de parede einvalidateByAgentnão remove nada e retorna 0.
- Um acerto não verifica de novo a evidência nem a confiança. Só verifica a expiração da entrada; não verifica de novo a janela de sessão, a validade das chaves, a confiança no principal nem um snapshot de revogação recente, e nada é invalidado automaticamente quando a confiança, a revogação ou a política mudam. Um acerto não é admissão nem autorização: para isso, verifique novamente.
- Chave e contexto. Sem
context, a chave é o hash do bundle, como antes: as chamadas legadas compartilham suas entradas, qualquer que seja o locatário ou a política. Comset(..., { context })egetouhas(hash, { context }), uma entrada só é retornada para a mesma string de contexto, e a rota legada e os contextos nunca veem as entradas uns dos outros. Quem chama escolhe o contexto e responde por ele: ele deve mudar sempre que mudar o conteúdo de uma entrada da decisão (a política do verificador, o locatário, os principais confiáveis, o estado de revogação); por exemplo, um digest que quem chama calcula sobre esse conteúdo. Um rótulo reutilizado depois que seu conteúdo mudou não isola nada. O cache garante apenas a separação por string exata. - Invalidação.
invalidateByKid(kid)remove, em todos os contextos, as entradas cujos kids de assinatura incluemkid; os kids deresult.details.signer_keyssão indexados junto com os de quem chama.invalidateByAgent(agentId)remove as entradas armazenadas comagentIdemagentIdse, deliberadamente, todas as entradas armazenadas sem associação a um agente (chamadas legadas, ouagentIdsausente ou vazio), porque o cache não tem como saber de quem são; as entradas associadas apenas a outros agentes são mantidas. Retorna o total removido, então um número diferente de zero não significa que o agente tinha entradas.agentIdsé um rótulo de quem chama: não é verificado, e nada é derivado do resultado.clear()remove tudo. - Expiração. Uma entrada é uma falha assim que seu TTL tiver passado em qualquer um dos dois relógios, o monotônico (
performance.now()) ou o de parede (Date.now(), registrado emcreatedAteexpiresAt); uma leitura igual a um prazo já é uma falha. Uma leitura de qualquer um dos relógios anterior à da criação, ou uma leitura não finita, é uma falha que remove a entrada. Um recuo do relógio de parede que fica depois da criação é limitado pelo prazo monotônico. Durante uma suspensão do sistema o relógio monotônico pode não avançar; o limite do relógio de parede continua valendo, mas o cache não promete tempo real absoluto. Um TTL de 0 nunca é armazenado, esetcom ele remove a entrada dessa chave. - Cópias.
setarmazena uma cópia profunda (structuredClone) do resultado e cópias das listas de kids e de agentes;getretorna a cada acerto uma nova cópia profunda e mutável;hasnão copia. - Erros. Nada muda no cache quando uma chamada lança um erro.
- Construtor:
TypeErrorseoptionsouttlByTiernão forem objetos;RangeErrorse um TTL não for um número de 0 aNumber.MAX_SAFE_INTEGERoumaxEntriesnão for um inteiro seguro de 1 aNumber.MAX_SAFE_INTEGER(umundefinedexplícito mantém o padrão);Errorseperformance.now()não estiver disponível. set:TypeErrorse o hash não for uma string, o resultado não for um objeto,signerKidsouagentIdsnão forem arrays de strings (não vazias no caso dos agentes; um buraco conta comoundefined) ou o contexto não for uma string;RangeErrorse uma leitura de relógio não for finita ou um prazo (relógio + TTL) excederNumber.MAX_SAFE_INTEGER;DataCloneErrorse o resultado não puder ser clonado.getehas:TypeErrorse o hash ou o contexto não forem strings.invalidateByAgent:TypeErrorseagentIdnão for uma string não vazia.
class VerificationCache {
constructor(options?: VerificationCacheOptions);
get(bundleHash: string, options?: VerificationCacheLookupOptions): VerifyV2Result | null; // new copy; null when absent or expired
set(
bundleHash: string,
result: VerifyV2Result,
signerKids: string[],
tier: SecurityTier,
options?: VerificationCacheSetOptions,
): void;
has(bundleHash: string, options?: VerificationCacheLookupOptions): boolean;
invalidateByKid(kid: string): number; // entries removed, in every context
invalidateByAgent(agentId: string): number; // the agent's entries + every entry without agentIds
clear(): void;
readonly size: number; // every context, including expired entries not yet read
}
interface VerificationCacheOptions {
/** TTL per tier in milliseconds, from 0 to Number.MAX_SAFE_INTEGER. */
ttlByTier?: Partial<Record<SecurityTier, number>>;
/** Hard upper limit on entries: a safe integer from 1 to Number.MAX_SAFE_INTEGER. */
maxEntries?: number;
}
interface VerificationCacheSetOptions {
agentIds?: readonly string[]; // the caller's label for invalidateByAgent; not checked
context?: string; // exact-string isolation chosen by the caller
}
interface VerificationCacheLookupOptions {
context?: string;
}
interface CacheEntry {
result: VerifyV2Result;
bundleHash: string;
signerKids: string[];
tier: SecurityTier;
createdAt: number; // Date.now() at set
expiresAt: number; // createdAt + TTL
}
Formato de transmissão CBOR¶
Serialização binária compacta para os bundles DCP.
cborEncode(value) / cborDecode(data)¶
jsonToCborPayload(json) / cborPayloadToJson(cbor)¶
Converte, de forma recursiva, um payload DCP entre a forma JSON dele (campos *_b64 em base64) e a forma adequada ao CBOR (strings de bytes brutos). Codifique o resultado com cborEncode.
function jsonToCborPayload(json: Record<string, unknown>): Record<string, unknown>;
function cborPayloadToJson(cbor: Record<string, unknown>): Record<string, unknown>;
detectWireFormat(data)¶
Detecta se os dados estão codificados em JSON ou em CBOR.
Provedores criptográficos¶
registerDefaultProviders()¶
Registra os provedores padrão Ed25519 + ML-DSA-65 + SLH-DSA-192f.
getDefaultRegistry()¶
Obtém o AlgorithmRegistry padrão com todos os provedores registrados.
AlgorithmRegistry¶
Registro de provedores de algoritmos.
class AlgorithmRegistry {
registerSigner(provider: CryptoProvider): void;
registerKem(provider: KemProvider): void;
getSigner(alg: string): CryptoProvider; // throws for an unregistered algorithm
getKem(alg: string): KemProvider;
hasSigner(alg: string): boolean;
hasKem(alg: string): boolean;
listSigners(): string[];
listKems(): string[];
}
Provedores disponíveis¶
| Provedor | Algoritmo | Tipo |
|---|---|---|
Ed25519Provider |
ed25519 |
Assinatura clássica |
MlDsa65Provider |
ml-dsa-65 |
Assinatura pós-quântica (NIST ML-DSA) |
SlhDsa192fProvider |
slh-dsa-192f |
Assinatura pós-quântica (NIST SLH-DSA) |
Interface CryptoProvider¶
interface CryptoProvider {
readonly alg: string;
readonly keySize: number;
readonly sigSize: number;
readonly isConstantTime: boolean;
generateKeypair(): Promise<{
kid: string;
publicKeyB64: string;
secretKeyB64: string;
}>;
sign(message: Uint8Array, secretKeyB64: string): Promise<Uint8Array>;
verify(
message: Uint8Array,
signature: Uint8Array,
publicKeyB64: string,
): Promise<boolean>;
}
Detecção de versão¶
detectDcpVersion(artifact)¶
Detecta a versão do DCP de um artefato ou de um bundle.
Experimental: candidato de canonicalização dcp-jcs-v2 (opt-in)¶
Experimental e desativado por padrão: dcp-jcs-v1 continua sendo o perfil de canonicalização padrão e o único
normativo, e os construtores, assinantes e verificadores habituais não mudam. Estas exportações existem para quem optar por usá-las; um bundle candidato verificado não concede
confiança nem admissão. O contrato completo está em
docs/proposals/canonicalization-candidate (§15 entrada, §16
roteador, §17 verificador, §18 produtores).
function experimentalCandidateIngress(bytes: Uint8Array): ExperimentalCandidateIngressResult;
function experimentalCandidateExtractUnit(bytes: Uint8Array, transport: ExperimentalCandidateTransport): ExperimentalCandidateExtraction;
function createExperimentalCandidateRouter(config: {
transport: ExperimentalCandidateTransport; // 'bare' | 'envelope'
acceptedProfiles: readonly string[]; // no default
historical: ExperimentalHistoricalAdapter; // no default; see experimentalHistoricalAdapters
}): ExperimentalCandidateRouter;
function createExperimentalCandidateVerifier(config: {
transport: ExperimentalCandidateTransport;
acceptedProfiles: readonly string[];
historical: ExperimentalHistoricalAdapter;
}): ExperimentalCandidateVerifier; // verify(bytes, registry, policy?, options?)
function experimentalCandidateSignPayload(
registry: AlgorithmRegistry, context: string, input: ExperimentalCandidateInput, keys: ExperimentalCandidateKeys,
): Promise<{ bytes: Uint8Array; signedPayload: ExperimentalCandidateSignedPayload }>;
function experimentalCandidateSignBundle(
registry: AlgorithmRegistry, parts: ExperimentalCandidateBundleParts, signer: ExperimentalCandidateBundleSigner,
options: ExperimentalCandidateBundleOptions,
): Promise<{ bytes: Uint8Array; signedBundle: { [key: string]: ExperimentalCandidateValue } }>;
ExperimentalCandidateIngressResult:{ status: 'accept', value, canonical, canonicalSha256 }ou{ status: 'reject', class, offset }.verifyretorna{ route, entered, verification }: a rota (reject,v1_pathoucandidate), o verificador em que entrou (none,dcp-jcs-v1oudcp-jcs-v2, no máximo um) e o resultado desse verificador como está.ExperimentalCandidateInputé{ bytes }(bytes originais, verificados pela entrada) ou{ value }(um valor do host, verificado de forma estrita).ExperimentalCandidateProduceError(class,part,path,offset) é uma rejeição pelo domínio ou pela forma das entradas, lançada antes de chamar qualquer assinante; os erros de chave, registro e provedor continuam os atuais.- Erros do roteador e do verificador:
ExperimentalCandidateConfigError(configuração),ExperimentalCandidateAdapterError(um decodificador histórico que falhou por outro motivo que não recusar os dados) eExperimentalCandidateInternalError.