Guía de inicio rápido de DCP-AI¶
Traducción informativa de la versión en inglés, actualizada el 28/10/2026. Si difieren, prevalece la versión en inglés. Los identificadores, comandos y bloques de código se conservan sin traducir.
Esta guía muestra cómo producir y verificar evidencias DCP con un SDK, y qué herramientas son demos.
Elige un camino¶
- Producir y verificar evidencias con un SDK. Instala un SDK publicado. Los ejemplos de §3 TypeScript y §4 Python crean bundles firmados y los verifican; Otros SDK da la instalación y las referencias de Go, Rust y WebAssembly. La verificación comprueba la integridad y las firmas; no establece la confianza en el principal, la admisión ni la autorización (véase Admisión).
- Explorar con una demo. El playground y los proyectos iniciales de los atajos sin instalación, y el asistente de la CLI de §1 y §2, muestran los conceptos. Sus límites varían (claves o firmas PQ simuladas, claves de marcador de posición, registros sin firmar, comprobaciones solo de estructura), y lo que producen no es evidencia de verificación.
- Ejecutar un verificador sin instalar un SDK. La imagen Docker opcional del servidor de verificación de referencia, en los mismos atajos y en Ejecutar los servicios de referencia, verifica bundles; no los crea.
Las versiones actuales de los paquetes están en Versiones publicadas.
Requisitos previos¶
Según el SDK que uses:
- Node.js 18+ — para el SDK de TypeScript, la CLI, el paquete WASM y las integraciones
@dcp-ai/*; la versión actual de LangChain.js (v1) de QUICKSTART_LANGCHAIN.md necesita Node.js 22+ - Python 3.10+ — para el SDK de Python; el paquete independiente
agno-dcpde QUICKSTART_AGNO.md necesita 3.11+ - Go 1.25+ — para el SDK de Go
- Rust estable — para el crate de Rust
Solo necesitas el lenguaje con el que vayas a trabajar. Todos los SDK implementan el mismo formato de intercambio V2; los vectores compartidos y la matriz de interoperabilidad prueban la firma y la verificación entre SDK, y el README de cada SDK lista lo que le falta.
Paquetes publicados y esta guía¶
Los ejemplos TypeScript usan @dcp-ai/sdk 2.2.1 publicado, el CLI npm es @dcp-ai/cli 2.1.1 y Python es dcp-ai 2.10.1 en PyPI. Véanse npm, Python y SECURITY.md. Go y Rust se publican por separado. Para desarrollar desde el código fuente, utiliza:
git clone https://github.com/dcp-ai-protocol/dcp-ai.git
cd dcp-ai/sdks/typescript && npm install && npm run build # TypeScript SDK of main
cd ../../cli && npm install --no-save --package-lock=false --ignore-scripts --install-links ../sdks/typescript
pip install -e /path/to/dcp-ai/sdks/python # Python SDK of main
Los comandos de registro de esta guía instalan las versiones publicadas.
Atajos sin instalación¶
Estos atajos usan paquetes e imágenes publicados, no main. El playground y los proyectos iniciales son demos y no producen evidencias de verificación de un SDK (límites más abajo); la imagen Docker ejecuta el servidor de verificación de referencia, que verifica bundles pero no los crea:
- Playground interactivo: https://docs.dcp-ai.org/playground/ — genera identidades, construye bundles y verifica firmas en el navegador.
- Proyecto inicial con scaffold: ejecuta
npm create @dcp-ai/langchain my-app(o/crewai,/openai,/express) para generar un proyecto inicial. - Docker en una línea:
docker run -p 3000:3000 ghcr.io/dcp-ai-protocol/dcp-ai/verification:latestarranca el servidor de verificación de referencia sin clonar nada.
El playground es una demostración: sus firmas PQ están simuladas y su canonicalización y manejo de Merkle están simplificados, así que sus bundles no son evidencia para la verificación de los SDK. Las plantillas iniciales también tienen límites: LangChain, CrewAI y OpenAI usan claves y firmas de relleno; Express solo comprueba la estructura. Usa los ejemplos de los SDK de abajo para obtener bundles verificables.
1. Instalar la CLI¶
El asistente de la CLI es una demo para explorar: sus claves «ML-DSA-65» están simuladas (bytes aleatorios), y el RPR y el pasaporte que escribe no están firmados ni cumplen los esquemas V2. Para crear una identidad y bundles que verifiquen, salta a §3 o §4; los límites se enumeran en Creación de agentes.
La versión publicada, instalada o ejecutada directamente:
Desde una copia del repositorio (arriba), ejecuta el asistente del repositorio en el directorio de tu proyecto: node /path/to/dcp-ai/cli/bin/dcp-ai.js init.
2. Inicializar tu agente¶
Esto crea los siguientes archivos de demostración en tu proyecto:
| Archivo | Propósito |
|---|---|
.dcp/config.json |
Configuración y metadatos del agente |
.dcp/keys/ed25519_public.key, .dcp/keys/ed25519_secret.key |
Par de claves Ed25519 |
.dcp/keys/ml_dsa_65_public.key, .dcp/keys/ml_dsa_65_secret.key |
Par de claves «ML-DSA-65» simulado (bytes aleatorios), cuando se eligen claves poscuánticas |
.dcp/identity.json |
Registro con forma de RPR (sin firmar y sin cumplir el esquema) |
.dcp/passport.json |
Registro con forma de pasaporte (sin firmar y sin cumplir el esquema) |
Los archivos de claves secretas se escriben con los permisos por defecto (0644 con la umask habitual 022): ejecuta chmod 600 .dcp/keys/*_secret.key y mantenlos fuera del control de versiones añadiendo .dcp/keys/ a tu .gitignore.
3. SDK de TypeScript¶
Los ejemplos TypeScript siguientes funcionan con npm SDK 2.2.1 o con un checkout de desarrollo (véase Paquetes publicados y esta guía).
Instala una de las dos:
- el SDK de
main, compilado desde un checkout, para desarrollar el código fuente:
- o el SDK 2.2.1 publicado, que incluye estas correcciones y funciones:
Crear y firmar un bundle (V1 — Ed25519)¶
El RPR y el pasaporte se firman cada uno sobre el objeto sin su campo signature. verifySignedBundle comprueba la firma del bundle, sus hashes y la cadena; las firmas internas se comprueban aparte.
import { BundleBuilder, generateKeypair, signBundle, signObject, verifyObject, verifySignedBundle } from '@dcp-ai/sdk';
import type { AgentPassport, ResponsiblePrincipalRecord } from '@dcp-ai/sdk';
const now = new Date().toISOString();
const principalKeys = generateKeypair();
const agentKeys = generateKeypair();
// Each artifact is signed over the object without its `signature` field.
const rprBody: Omit<ResponsiblePrincipalRecord, 'signature'> = {
dcp_version: '1.0', human_id: 'human:example-001', legal_name: 'Example Principal',
entity_type: 'natural_person', jurisdiction: 'ES', liability_mode: 'owner_responsible',
override_rights: true, issued_at: now, expires_at: null, contact: null,
};
const rpr: ResponsiblePrincipalRecord = { ...rprBody, signature: signObject(rprBody, principalKeys.secretKeyB64) };
const passportBody: Omit<AgentPassport, 'signature'> = {
dcp_version: '1.0', agent_id: 'agent:example-001', public_key: agentKeys.publicKeyB64,
principal_binding_reference: rpr.human_id, capabilities: ['browse', 'api_call'],
risk_tier: 'low', created_at: now, status: 'active',
};
const passport: AgentPassport = { ...passportBody, signature: signObject(passportBody, agentKeys.secretKeyB64) };
const bundle = new BundleBuilder()
.responsiblePrincipalRecord(rpr)
.agentPassport(passport)
.intent({
dcp_version: '1.0', intent_id: 'intent:example-001', agent_id: passport.agent_id, human_id: rpr.human_id,
timestamp: now, action_type: 'api_call', target: { channel: 'api', domain: 'api.example.com' },
data_classes: ['none'], estimated_impact: 'low', requires_consent: false,
})
.policyDecision({
dcp_version: '1.0', intent_id: 'intent:example-001', decision: 'approve', risk_score: 0.05,
reasons: ['low-impact call'], required_confirmation: null,
})
.createAuditEntry({
dcp_version: '1.0', audit_id: 'audit:example-001', timestamp: now, agent_id: passport.agent_id,
human_id: rpr.human_id, intent_id: 'intent:example-001', policy_decision: 'approved',
outcome: 'call_completed', evidence: { tool: 'http', result_ref: null },
})
.build();
const signed = signBundle(bundle, { secretKeyB64: principalKeys.secretKeyB64, signerType: 'human', signerId: rpr.human_id });
console.log(verifySignedBundle(signed, principalKeys.publicKeyB64)); // { verified: true }
// The inner signatures, over the same objects without `signature`
console.log(verifyObject(rprBody, rpr.signature, principalKeys.publicKeyB64)); // true
console.log(verifyObject(passportBody, passport.signature, agentKeys.publicKeyB64)); // true
Verificar un bundle¶
import { readFileSync } from 'node:fs';
import { getDefaultRegistry, registerDefaultProviders, verifySignedBundleV2 } from '@dcp-ai/sdk';
registerDefaultProviders();
const signedBundle = JSON.parse(readFileSync('bundle.signed.json', 'utf8'));
const result = await verifySignedBundleV2(signedBundle, getDefaultRegistry());
console.log(result.verified, result.errors);
V2 — Firmas híbridas poscuánticas¶
Cada artefacto es un SignedPayload firmado en su contexto de separación de dominio con Ed25519 + ML-DSA-65; el principal firma el RPR y el manifiesto, y el agente, el pasaporte, la intención y la decisión de política.
import {
AlgorithmRegistry, BundleBuilderV2, DCP_CONTEXTS, Ed25519Provider, MlDsa65Provider, compositeSign,
generateSessionNonce, preparePayload, sha256Hex, canonicalizeV2, signBundleV2, verifySignedBundleV2,
} from '@dcp-ai/sdk';
import type {
AgentPassportV2, AuditEventV2, CompositeKeyPair, DcpContext, IntentV2, KeyEntry, PolicyDecisionV2,
ResponsiblePrincipalRecordV2, SignedPayload,
} from '@dcp-ai/sdk';
const registry = new AlgorithmRegistry();
const ed25519 = new Ed25519Provider();
const mlDsa65 = new MlDsa65Provider();
registry.registerSigner(ed25519);
registry.registerSigner(mlDsa65);
async function hybridKeys(): Promise<CompositeKeyPair> {
const c = await ed25519.generateKeypair();
const p = await mlDsa65.generateKeypair();
return {
classical: { kid: c.kid, alg: 'ed25519', secretKeyB64: c.secretKeyB64, publicKeyB64: c.publicKeyB64 },
pq: { kid: p.kid, alg: 'ml-dsa-65', secretKeyB64: p.secretKeyB64, publicKeyB64: p.publicKeyB64 },
};
}
const keyEntries = (keys: CompositeKeyPair): KeyEntry[] => [keys.classical, keys.pq].map((k) => ({
kid: k.kid, alg: k.alg, public_key_b64: k.publicKeyB64, created_at: '2026-01-01T00:00:00Z', expires_at: null, status: 'active',
}));
const sha256Of = (value: unknown) => `sha256:${sha256Hex(new TextEncoder().encode(canonicalizeV2(value)))}`;
async function signed<T>(payload: T, context: DcpContext, keys: CompositeKeyPair): Promise<SignedPayload<T>> {
const { canonicalBytes, payloadHash } = preparePayload(payload);
return { payload, payload_hash: payloadHash, composite_sig: await compositeSign(registry, context, canonicalBytes, keys) };
}
const principal = await hybridKeys();
const agent = await hybridKeys();
const nonce = generateSessionNonce();
const now = new Date().toISOString();
const rpr: ResponsiblePrincipalRecordV2 = {
dcp_version: '2.0', human_id: 'human:example-001', session_nonce: nonce, legal_name: 'Example Principal',
entity_type: 'natural_person', jurisdiction: 'ES', liability_mode: 'owner_responsible', override_rights: true,
issued_at: now, expires_at: null, contact: null, binding_keys: keyEntries(principal),
};
const passport: AgentPassportV2 = {
dcp_version: '2.0', agent_id: 'agent:example-001', session_nonce: nonce, keys: keyEntries(agent),
principal_binding_reference: rpr.human_id, capabilities: ['browse', 'api_call'], risk_tier: 'low',
created_at: now, status: 'active',
};
const intent: IntentV2 = {
dcp_version: '2.0', intent_id: 'intent:example-001', session_nonce: nonce, agent_id: passport.agent_id,
human_id: rpr.human_id, timestamp: now, action_type: 'api_call', target: { channel: 'api', domain: 'api.example.com' },
data_classes: ['none'], estimated_impact: 'low', requires_consent: false,
};
const policy: PolicyDecisionV2 = {
dcp_version: '2.0', intent_id: intent.intent_id, session_nonce: nonce, decision: 'approve', risk_score: 50,
reasons: ['low-impact call'], required_confirmation: null, applied_policy_hash: sha256Of({ policy: 'default' }), timestamp: now,
};
const audit: AuditEventV2 = {
dcp_version: '2.0', audit_id: 'audit:example-001', session_nonce: nonce, prev_hash: 'GENESIS', hash_alg: 'sha256',
timestamp: now, agent_id: passport.agent_id, human_id: rpr.human_id, intent_id: intent.intent_id,
intent_hash: sha256Of(intent), policy_decision: 'approved', outcome: 'call_completed',
evidence: { tool: 'http', result_ref: null, evidence_hash: null }, pq_checkpoint_ref: null,
};
const bundle = new BundleBuilderV2(nonce)
.responsiblePrincipalRecord(await signed(rpr, DCP_CONTEXTS.ResponsiblePrincipal, principal))
.agentPassport(await signed(passport, DCP_CONTEXTS.AgentPassport, agent))
.intent(await signed(intent, DCP_CONTEXTS.Intent, agent))
.policyDecision(await signed(policy, DCP_CONTEXTS.PolicyDecision, agent))
.addAuditEntry(audit)
.build();
const signedBundle = await signBundleV2(bundle, { registry, signerType: 'human', signerId: rpr.human_id, keys: principal });
const result = await verifySignedBundleV2(signedBundle, registry);
console.log(result.verified, result.errors); // true []
4. SDK de Python¶
Instala una de las dos:
- un checkout para desarrollar el SDK:
- o la versión publicada 2.10.1, incluidas las correcciones y API descritas aquí:
Crear y verificar un bundle¶
from datetime import datetime, timezone
from dcp_ai import (
AgentPassport,
AuditEvidence,
BundleBuilder,
Intent,
PolicyDecision,
ResponsiblePrincipalRecord,
generate_keypair,
sign_bundle,
sign_object,
verify_object,
verify_signed_bundle,
)
now = datetime.now(timezone.utc).isoformat()
principal_keys = generate_keypair()
agent_keys = generate_keypair()
# 1. The responsible principal, signed with the principal's key (the object without "signature")
rpr_body = {
"dcp_version": "1.0", "human_id": "human:example-001", "legal_name": "Example Principal",
"entity_type": "natural_person", "jurisdiction": "ES", "liability_mode": "owner_responsible",
"override_rights": True, "issued_at": now, "expires_at": None, "contact": None,
}
rpr = {**rpr_body, "signature": sign_object(rpr_body, principal_keys["secret_key_b64"])}
# 2. The agent passport, signed with the agent's key (the object without "signature")
passport_body = {
"dcp_version": "1.0", "agent_id": "agent:example-001", "public_key": agent_keys["public_key_b64"],
"principal_binding_reference": "human:example-001", "capabilities": ["browse", "api_call"],
"risk_tier": "low", "created_at": now, "status": "active",
}
passport = {**passport_body, "signature": sign_object(passport_body, agent_keys["secret_key_b64"])}
# 3. Intent, policy decision and one audit entry
intent = Intent(
intent_id="intent:example-001", agent_id="agent:example-001", human_id="human:example-001",
timestamp=now, action_type="api_call", target={"channel": "api", "domain": "api.example.com"},
data_classes=["none"], estimated_impact="low", requires_consent=False,
)
policy = PolicyDecision(
intent_id="intent:example-001", decision="approve", risk_score=0.05, reasons=["low-impact call"],
)
bundle = (
BundleBuilder()
.responsible_principal_record(ResponsiblePrincipalRecord(**rpr))
.agent_passport(AgentPassport(**passport))
.intent(intent)
.policy_decision(policy)
.create_audit_entry(
audit_id="audit:example-001", timestamp=now, agent_id="agent:example-001",
human_id="human:example-001", intent_id="intent:example-001", policy_decision="approved",
outcome="call_completed", evidence=AuditEvidence(tool="http", result_ref=None),
)
.build()
)
# 4. Sign with the principal's key and verify against the principal's public key
signed = sign_bundle(bundle, principal_keys["secret_key_b64"])
print(verify_signed_bundle(signed, principal_keys["public_key_b64"])) # {'verified': True}
# 5. The inner signatures, over the same objects without "signature"
print(verify_object(rpr_body, rpr["signature"], principal_keys["public_key_b64"])) # True
print(verify_object(passport_body, passport["signature"], agent_keys["public_key_b64"])) # True
Para bundles V2 en Python, véase V2 Bundles.
5. Niveles de seguridad¶
DCP selecciona automáticamente un nivel de seguridad criptográfica según el perfil de riesgo de la intención:
| Nivel | Nombre | Modo de verificación | Intervalo de checkpoints PQ | Desencadenante |
|---|---|---|---|---|
| 0 | Routine | Solo clásico (Ed25519) | Cada 50 eventos | Ninguno de los desencadenantes siguientes |
| 1 | Standard | Híbrido preferido | Cada 10 eventos | Puntuación de riesgo 200–499, estimated_impact: medium |
| 2 | Elevated | Híbrido obligatorio | Cada evento | Puntuación de riesgo 500–799, datos personales, financieros o de salud, pagos, estimated_impact: high, valores desconocidos |
| 3 | Maximum | Híbrido obligatorio | Cada evento | Puntuación de riesgo ≥ 800, credenciales, datos de menores |
La puntuación de riesgo es el risk_score de la decisión de política (spec §14.2).
import { computeSecurityTier, tierToVerificationMode } from '@dcp-ai/sdk';
const tier = computeSecurityTier(intent, policyDecision);
const mode = tierToVerificationMode(tier);
// tier: 'elevated', mode: 'hybrid_required'
6. Telemetría y observabilidad¶
import { dcpTelemetry } from '@dcp-ai/sdk';
dcpTelemetry.init({
serviceName: 'my-agent',
enabled: true,
exporterType: 'console', // or 'otlp'
});
// Automatic span tracking
const spanId = dcpTelemetry.startSpan('sign_bundle', { tier: 'elevated' });
// ... perform operation ...
dcpTelemetry.endSpan(spanId);
// Record metrics
dcpTelemetry.recordSignLatency(12.5, 'ed25519');
// Get summary
const summary = dcpTelemetry.getMetricsSummary();
console.log(summary.sign.p95); // p95 sign latency in ms
7. Comunicación entre agentes (A2A)¶
import { createHello, createWelcome, createSession, encryptMessage } from '@dcp-ai/sdk';
// Agent A initiates
const hello = createHello(bundleA, kemPublicKeyB64, ['api_call'], 'standard');
// Agent B responds
const welcome = createWelcome(bundleB, kemPubB, kemCiphertextB64, 'standard');
// Establish encrypted session
const session = createSession(sessionId, sessionKey, 'agent-a', 'agent-b', 'standard');
// Send encrypted messages
const encrypted = encryptMessage(session, { action: 'transfer', amount: 100 });
Otros SDK¶
Go¶
import dcp "github.com/dcp-ai-protocol/dcp-ai/sdks/go/v2/dcp"
canonical, _ := dcp.Canonicalize(map[string]string{"b": "2", "a": "1"})
// produces {"a":"1","b":"2"}
Rust¶
Los proveedores de ML-DSA-65, ML-KEM-768, SLH-DSA-192f y Ed25519 están en dcp_ai::providers::*. Consulta la documentación del crate dcp-ai en docs.rs para ver toda la superficie.
WebAssembly (navegador)¶
npm install @dcp-ai/wasm@^2.1.1 # the published version; for main, see the WASM SDK's Release status
Expone las primitivas del SDK de Rust a navegadores y a Node.js. En Node.js, initDcp() necesita el archivo .wasm como URL data:: véase Inicialización.
Ejecutar los servicios de referencia¶
Los cuatro servicios a los que hace referencia la especificación (servidor de verificación, anchor, registro de transparencia, registro de revocaciones) se distribuyen como imágenes Docker. Desde un directorio vacío:
docker run -d -p 3000:3000 ghcr.io/dcp-ai-protocol/dcp-ai/verification:latest
docker run -d -p 3001:3001 ghcr.io/dcp-ai-protocol/dcp-ai/anchor:latest
docker run -d -p 3002:3002 ghcr.io/dcp-ai-protocol/dcp-ai/transparency-log:latest
docker run -d -p 3003:3003 ghcr.io/dcp-ai-protocol/dcp-ai/revocation:latest
Para alojamiento gestionado, consulta las configuraciones de Fly.io en deploy/fly/ y la guía de despliegue para alternativas con Cloud Run, Railway o Compose.
Siguientes pasos¶
- Integración con LangChain — Añade DCP a agentes de LangChain
- Integración con CrewAI — Añade DCP a equipos de CrewAI
- Integración con OpenAI — Añade DCP a las llamadas a funciones de OpenAI
- Middleware de Express — Verifica bundles DCP en API de Express
- Referencia de la API — Documentación completa del SDK
- Especificación del protocolo — Especificación completa de DCP v2.0
- Modelo de seguridad — Modelo de amenazas y arquitectura de seguridad
- Guía del operador — Ejecutar servicios de verificación y anclaje en producción