Signet
Recibos de acciones criptográficas para agentes de IA. Firma cada llamada de herramienta MCP con Ed25519, registro de auditoría encadenado por hash. 3 líneas de código para integrar.
Documentación
Signet
No solo registres las acciones de los agentes. Pruébalas.
Confianza criptográfica y evidencia de autorización para cada acción de un agente de IA: identidad, delegación, políticas, recibos: firmados, encadenados por hash, verificables sin conexión. Independiente de cualquier proveedor.
Paquetes TypeScript:
@signet-auth/core ·
@signet-auth/mcp ·
@signet-auth/mcp-server ·
@signet-auth/mcp-tools ·
@signet-auth/node ·
@signet-auth/vercel-ai
▶ Prueba la demo en vivo — firma una llamada de herramienta en tu navegador, cambia un campo y observa cómo falla la verificación. (espejo: GitHub Pages)
▶ Tutorial: firma, registro de auditoría y verificación · ▶ Demo: límite de ejecución e integración con MCP
Flujo piloto de un solo host: firma cada llamada de herramienta, entrega un paquete de evidencia firmado y vuelve a verificar en cualquier máquina, sin necesidad de un almacén de claves signet. Manual del piloto →
Tu agente de IA acaba de realizar un pedido, eliminar una fila, enviar un correo electrónico o fusionar un PR. ¿Puedes probar exactamente qué hizo, ante un auditor, un cliente o incluso ante ti mismo después de un incidente?
Signet es la capa de confianza independiente para las acciones de los agentes. Cada llamada de herramienta recibe un recibo firmado que cualquiera puede verificar sin conexión, sin confiar en la plataforma que alojó al agente ni en el proveedor que almacenó los registros. Y desde la versión 0.11, la autorización detrás de una acción lleva su propia prueba: quién es el agente (principal), quién le permitió actuar (delegación) y quién permitió esta acción específica (decisión firmada por la autoridad).
Tus agentes se ejecutan en su infraestructura. La prueba te pertenece a ti.
¿Por Qué No Solo Registros?
Los registros tradicionales te dicen lo que una plataforma dice que sucedió. Son mutables, dependen del proveedor y no se pueden verificar sin confiar en la parte que los escribió.
Los recibos de Signet son diferentes. Modifica cualquier campo (nombre de la herramienta, parámetros, marca de tiempo, firmante) y la firma Ed25519 se rompe. Elimina o reordena entradas y la cadena de hash SHA-256 se rompe. La verificación solo requiere la clave pública. Sin llamada de red, sin API, sin inicio de sesión.
| Registros ordinarios | Recibos de Signet |
|---|---|
| El proveedor dice que sucedió | Cualquiera puede verificarlo, sin conexión |
| Mutables después del hecho | La firma se rompe ante manipulación |
| Sin prueba de orden | La cadena de hash se rompe al eliminar/reordenar |
| Confía en el host de registros | Verifica con la clave pública |
| Afirmación unilateral | Co-firma bilateral disponible |
Usa registros para observabilidad. Usa Signet cuando necesites evidencia.
¿Para Quién Es Esto?
- Creadores de MCP — envuelve cualquier servidor MCP con
signet proxy, firma cadatools/call, sin cambios de código - Equipos de seguridad / cumplimiento — rastro de auditoría a prueba de manipulación que cumple con el Art. 12 de la Ley de IA de la UE, SOC 2 CC7.2, ISO 27001 A.8.15
- Plataformas empresariales de agentes — prueba qué hizo el agente, quién lo autorizó, qué política estaba vigente
- Usuarios de frameworks — LangChain, CrewAI, Claude Code, Codex, OpenAI Agents, Vercel AI SDK — todos compatibles
- Despliegues agente a agente — co-firma bilateral cuando ambos lados tienen claves
Si una llamada de herramienta no se puede verificar de forma independiente, no se debe confiar en ella incondicionalmente. Esto importa cuando un auditor pide pruebas, cuando ocurre un incidente en infraestructura que no controlas, o cuando la pregunta no es "qué dice la consola" sino "qué sucedió realmente".
Cada agente obtiene una identidad Ed25519. Cada llamada de herramienta se puede firmar, añadir a un rastro de auditoría encadenado por hash, verificar sin conexión o antes de la ejecución, co-firmar por el servidor, vincular a una cadena de delegación y, opcionalmente, vincular a una decisión de política.
El video anterior muestra el flujo completo. El SVG a continuación muestra los detalles de firma de la CLI, o salta a Ver Cómo Rechaza Solicitudes Incorrectas para ver al servidor bloquear solicitudes incorrectas antes de que se ejecuten.
Esta primera demo muestra la firma y los recibos de auditoría. Consulta también el diagrama de flujo de MCP.
Qué Añade Signet
Signet añade una capa de confianza ligera para las acciones de los agentes:
- Firma cada llamada de herramienta con la clave criptográfica del agente
- Verifica solicitudes sin conexión o en el límite de ejecución antes de que se confíe en ellas
- Proxy cualquier servidor MCP de forma transparente: firma solicitudes sin tocar el código del agente o del servidor, con co-firma de auditoría bilateral local en la ruta del proxy
- Co-firma respuestas del servidor con recibos bilaterales cuando controlas ambos lados
- Traza flujos de trabajo de múltiples pasos vinculando recibos con
trace_idyparent_receipt_id - Autoriza agentes con cadenas de delegación con alcance que prueban quién permitió la acción
- Atestigua políticas incrustando un
PolicyAttestationfirmado cuando se cumple una política YAML - Inspecciona localmente con un registro de auditoría de solo añadido y un panel de control, sin necesidad de un plano de control alojado
Qué Hay de Nuevo en 0.11
- Principales canónicos: cada identidad puede llevar un URI principal con alcance (
agent://prismer/deploy-bot), firmado dentro de recibos y tokens de delegación; las afirmacionesacting_forson corroboradas por máquina por la raíz de la cadena. - Decisiones de autorización firmadas por la autoridad:
signet authorizepre-aprueba una intención;signet sign --decisionproduce un recibo respaldado por ella (o--authority-keylo hace en un solo paso). Una decisión se vincula a la acción medianteintent_hash, por lo que la reproducción en una acción diferente se rechaza. - Revocación:
signet revokeinvalida tokens de delegación y decisiones con un registro firmado por el emisor. La verificación informa un estado explícito:revokedfalla,unknownnunca se informa como autorizado (--require-revocation-knownpara modo estricto). Los paquetes de evidencia incluyen registros de revocación. - Condiciones y límites: las reglas de política llevan obligaciones tipadas (
require_approval,sandbox, …); los alcances de delegación llevan restricciones (--max-calls,--spend-limit). Las rutas de firma hacen cumplir presupuestos de conteo de llamadas y la invariante de estrechamiento (una concesión puede reducir una delegación, nunca ampliarla). - Endurecimiento:
verify()ahora verifica correctamente los recibos v4; las reglas de política con límite de velocidad fallan de forma cerrada cuando no se proporciona estado; la expiración de la delegación se vincula al reloj de pared (retroceder la marca de tiempo de un recibo ya no la evita).
Cumplimiento
Signet proporciona los controles técnicos que los auditores buscan al evaluar las operaciones de agentes de IA. Consulta el Mapeo de Cumplimiento completo para más detalles.
| Marco | Qué Aborda Signet |
|---|---|
| SOC 2 Tipo II | Rastro de auditoría firmado (CC7.2), detección de manipulación (CC7.3), alcance basado en roles (CC6.3), prueba de autorización (CC8.1) |
| ISO 27001 | Registro de eventos (A.8.15), control de acceso (A.5.15), autenticación (A.5.17), gestión de configuración (A.8.9) |
| Ley de IA de la UE | Artículo 12 mantenimiento de registros: registro de eventos, trazabilidad, identificación, integridad |
| DORA | Registro de incidentes TIC (Art. 17), evidencia de riesgo de terceros (Art. 28-30), integridad del rastro de auditoría |
| NIST AI RMF | Gobernar (cadenas de delegación), Mapear (recibos firmados), Medir (consultas de auditoría), Gestionar (motor de políticas) |
Signet es una herramienta, no una certificación. Proporciona controles que respaldan el cumplimiento: tu despliegue y configuración determinan la postura de cumplimiento.
Pruébalo en 30 Segundos
pip install signet-auth
from signet_auth import SigningAgent
agent = SigningAgent.create("my-agent", owner="team")
receipt = agent.sign("github_create_issue", params={"title": "fix bug"})
assert agent.verify(receipt)
print(receipt.id)
¿Por Qué Darle Estrella a Este Repositorio?
Signet está construyendo una nueva categoría: recibos de llamadas de herramientas verificables para agentes de IA. Darle estrella no es solo un marcador: ayuda a impulsar la evidencia criptográfica para las acciones de los agentes en el ecosistema para que las industrias reguladas, las plataformas empresariales y los usuarios de frameworks no tengan que crear la suya propia.
- Trabajando con Microsoft Agent Governance Toolkit (ejemplo fusionado en PR #1196)
- Contribuyente nombrado en RFC de ComplianceBackend de LangChain (#35691)
- Trabajo de conformidad hacia la especificación IETF draft-farley-acta-signed-receipts
- Se mapea a los cuatro pilares de NIST NCCoE para identidad y autorización de agentes de IA (Perfil de Interoperabilidad Q4 2026)
Si estás construyendo agentes que necesitan sobrevivir a una auditoría, un incidente o a un tercero que pregunta "pruébalo" — dale estrella al repositorio, pruébalo, abre un problema.
Si eres nuevo, comienza con una de estas cinco rutas:
Elige Tu Ruta
- Claude Code: Mejor para la primera ejecución más rápida en un agente de codificación. Ejecuta
/plugin install signet@claude-plugins-officialen Claude Code. En 5 minutos tendrás llamadas de herramientas firmadas y un registro de auditoría local en~/.signet/audit/. - Codex CLI: Mejor para firmar llamadas de herramientas Bash en Codex. Copia
plugins/codex/en~/.codex/plugins/signety añade un hookPostToolUse. En 5 minutos tendrás acciones Bash firmadas en Codex usando el mismo rastro de auditoría. - SDK de Python: Mejor si quieres recibos dentro de LangGraph, LlamaIndex, OpenAI Agents, CrewAI o tu propio ejecutor de herramientas. Comienza con
SigningAgent.create(...)y añade hooks de framework solo donde los necesites. - Clientes MCP: Mejor si controlas un cliente MCP o transporte. Envuelve tu transporte con
new SigningTransport(inner, secretKey, "my-agent"). En 5 minutos tendrás solicitudestools/callfirmadas con recibos enparams._meta._signet. - Servidores MCP: Mejor si quieres verificación antes de la ejecución. Llama a
verifyRequest(request, {...})en tu manejador de herramientas. En 5 minutos tendrás verificaciones de firmante, frescura, vinculación de objetivo y herramientas/parámetros en el límite de ejecución.
Ver Cómo Rechaza Solicitudes Incorrectas
Ejecuta la demo más corta del límite de ejecución:
cd examples/mcp-agent
npm run execution-boundary-demo
¿Prefieres movimiento? Descarga el MP4 o el GIF.
Consulta examples/mcp-agent/demo-execution-boundary.mjs para el código fuente de la demo.
Cadenas de Delegación: ¿Quién Autorizó a Este Agente?
Los recibos de Signet prueban qué sucedió. Las cadenas de delegación prueban quién lo permitió.
Una identidad raíz (humana u organización) delega criptográficamente autoridad con alcance a un agente. Los permisos solo pueden estrecharse, nunca ampliarse. El recibo v4 del agente lleva la prueba completa de autorización.
Owner (alice) → Agent A (tools: [Bash, Read], max_depth: 0)
↓
v4 Receipt: tool=Bash, authorization.chain proves alice → Agent A
# Create a delegation token (expires in 24 hours)
signet delegate create --from alice --to deploy-bot --to-name deploy-bot \
--tools Bash,Read --targets "mcp://github" --max-depth 0 --ttl 24h
# Sign with authorization proof (v4 receipt)
signet delegate sign --key deploy-bot --tool Bash \
--params '{"cmd":"git pull"}' --target "mcp://github" --chain chain.json
# Verify: signature + chain + scope + root trust
signet delegate verify-auth receipt.json --trusted-roots alice
Mejores prácticas: Utilice delegaciones de corta duración (
--ttl 1h,--ttl 24h) en lugar de tokens de larga duración o que no expiran. Si un agente se ve comprometido, la delegación expira automáticamente. Reemita tokens según sea necesario. Este es el mismo patrón utilizado por los JWT de corta duración y los certificados X.509.
O en Python:
from signet_auth import sign_delegation, sign_authorized, verify_authorized
# Delegation functions accept JSON strings for scope, chain, and receipts
token_json = sign_delegation(root_key_b64, "alice", agent_pubkey_b64, "bot", scope_json)
receipt_json = sign_authorized(agent_key_b64, action_json, "bot", f"[{token_json}]")
scope_json = verify_authorized(receipt_json, [root_pubkey_b64])
Atestaciones de Política: ¿Esto Estaba Permitido?
Signet puede aplicar una política YAML antes de firmar. Cuando una acción está permitida, el recibo firmado lleva un PolicyAttestation que demuestra qué hash de política, regla y decisión estaban en vigor.
version: 1
name: production-agents
default_action: deny
rules:
- id: allow-read
match:
tool: Read
action: allow
- id: deny-rm-rf
match:
tool: Bash
params:
command:
contains: "rm -rf"
action: deny
reason: destructive command
signet policy validate policy.yaml
signet policy check policy.yaml --tool Bash --params '{"command":"rm -rf /"}'
signet sign --key deploy-bot --tool Read \
--params '{"path":"README.md"}' --target "mcp://github" --policy policy.yaml
Las acciones denegadas fallan antes de que se produzca un recibo. Las acciones permitidas producen un recibo cuyo payload firmado demuestra la decisión de la política.
Cuándo los Equipos Recurren a Signet
- Necesita un rastro de auditoría a prueba de manipulaciones para agentes de codificación, herramientas MCP o automatización de CI
- Quiere demostrar qué agente solicitó una acción y quién la autorizó después de un incidente
- Necesita recibos que puedan verificarse sin conexión sin depender de un servicio alojado
- Quiere una aplicación de políticas ligera antes de firmar sin añadir un proxy a su stack
Qué Es Signet y Qué No Es
- Signet es una capa de confianza para acciones de agentes: firma, auditoría, verificación, delegación y atestación de políticas
- Signet está diseñado para integrarse en stacks de agentes existentes con SDK, plugins y middleware MCP
- Signet puede rechazar solicitudes MCP sin firmar, obsoletas, repetidas o mal dirigidas antes de la ejecución
- Signet puede denegar acciones antes de firmar cuando se proporciona un archivo de política
- Signet no es una puerta de enlace alojada, un plano de control siempre activo, ni un reemplazo para el sandboxing y el diseño de privilegios mínimos
Instalación
# CLI
cargo install signet-cli
# Python
pip install signet-auth
# TypeScript (MCP middleware)
npm install @signet-auth/core @signet-auth/mcp
# TypeScript (MCP server verification)
npm install @signet-auth/mcp-server
# TypeScript (Node local audit/operator helpers)
npm install @signet-auth/node
# TypeScript (Vercel AI SDK middleware)
npm install @signet-auth/vercel-ai
# TypeScript (standalone MCP signing server)
npx @signet-auth/mcp-tools
Inicio Rápido
Plugin de Claude Code
Firme automáticamente cada llamada a herramienta en Claude Code con configuración cero:
# Option A: From the official Anthropic plugin marketplace
/plugin install signet@claude-plugins-official
# Option B: Add Signet as a marketplace source, then install
/plugin marketplace add Prismer-AI/signet
/plugin install signet@signet
Cada llamada a herramienta se firma con Ed25519 y se registra en un rastro de auditoría encadenado por hash en ~/.signet/audit/.
Métodos de instalación alternativos:
# From Git
claude plugin add --from https://github.com/Prismer-AI/signet
# Via signet CLI
signet claude install
Plugin de Codex
Firme automáticamente cada llamada a la herramienta Bash en Codex CLI:
git clone https://github.com/Prismer-AI/signet.git
cp -r signet/plugins/codex ~/.codex/plugins/signet
Luego añada el hook a ~/.codex/hooks.json:
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "node \"$HOME/.codex/plugins/signet/bin/sign.cjs\"",
"timeout": 5
}]
}]
}
}
O use el servidor MCP para herramientas de firma bajo demanda:
codex mcp add signet -- npx @signet-auth/mcp-tools
CLI
# Generate an agent identity
signet identity generate --name my-agent
# Sign an action
signet sign --key my-agent --tool "github_create_issue" \
--params '{"title":"fix bug"}' --target mcp://github.local
# Verify a receipt
signet verify receipt.json --pubkey my-agent
# Audit recent actions
signet audit --since 24h
# Verify log integrity
signet verify --chain
Integración con Cliente MCP (TypeScript)
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { generateKeypair } from "@signet-auth/core";
import { SigningTransport } from "@signet-auth/mcp";
// Generate an agent identity
const { secretKey } = generateKeypair();
// Wrap any MCP transport -- all tool calls are now signed
const inner = new StdioClientTransport({ command: "my-mcp-server" });
const transport = new SigningTransport(inner, secretKey, "my-agent");
const client = new Client({ name: "my-agent", version: "1.0" }, {});
await client.connect(transport);
// Every callTool() is now cryptographically signed
const result = await client.callTool({
name: "echo",
arguments: { message: "Hello!" },
});
Cada solicitud tools/call recibe un recibo firmado inyectado en params._meta._signet.
Verificación del Servidor MCP
Si también controla el servidor MCP, verifique las solicitudes antes de la ejecución:
import { FileNonceCache, verifyRequest } from "@signet-auth/mcp-server";
const nonceCache = new FileNonceCache(".signet/nonces.json");
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const verified = verifyRequest(request, {
trustedKeys: ["ed25519:..."],
maxAge: 300,
nonceCache,
});
if (!verified.ok) return { content: [{ type: "text", text: verified.error }], isError: true };
if (!verified.trusted) return { content: [{ type: "text", text: "untrusted signer" }], isError: true };
console.log(`Verified: ${verified.signerName}`);
// process tool call...
});
Integración con Vercel AI SDK
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { generateKeypair } from "@signet-auth/core";
import { createSignetCallbacks } from "@signet-auth/vercel-ai";
const { secretKey } = generateKeypair();
const callbacks = createSignetCallbacks(secretKey, "my-agent");
const result = await generateText({
model: openai("gpt-4o"),
tools: { myTool },
...callbacks,
prompt: "...",
});
// Every tool call is now signed
console.log(callbacks.receipts);
Servidor MCP de Referencia
Este repositorio también incluye un servidor MCP de referencia mínimo que demuestra la verificación del lado del servidor con @signet-auth/mcp-server.
cd examples/mcp-agent
npm ci
npm run verifier-server
Herramientas disponibles:
inspect_current_request— verifica la llamada a herramienta MCP actual si incluyeparams._meta._signetverify_receipt— verifica un recibo Signet sin procesar contra una clave públicaverify_request_payload— verifica un payload MCPtools/callsintético sin conexión
Variables de entorno:
SIGNET_TRUSTED_KEYS— claves públicased25519:<base64>separadas por comasSIGNET_REQUIRE_SIGNATURE—trueofalse(por defectotrue)SIGNET_REQUIRE_TRUSTED_SIGNER—trueofalse(por defectotrue)SIGNET_MAX_AGE— antigüedad máxima del recibo en segundos (por defecto300)SIGNET_EXPECTED_TARGET—receipt.action.targetesperado opcional
Servidor de Firma MCP Independiente
@signet-auth/mcp-tools expone la firma, verificación y hash de contenido de Signet como herramientas MCP — conéctese a cualquier cliente compatible con MCP:
npx @signet-auth/mcp-tools
Herramientas disponibles: signet_generate_keypair, signet_sign, signet_verify, signet_content_hash.
SDK de Python (LangChain / CrewAI / AutoGen + 6 más)
pip install signet-auth
from signet_auth import SigningAgent
# Create an agent identity (saved to ~/.signet/keys/)
agent = SigningAgent.create("my-agent", owner="willamhou")
# Sign any tool call -- receipt is auto-appended to audit log
receipt = agent.sign("github_create_issue", params={"title": "fix bug"})
# Verify
assert agent.verify(receipt)
# Query audit log
for record in agent.audit_query(since="24h"):
print(f"{record.receipt.ts} {record.receipt.action.tool}")
Para herramientas Python simples, el punto de entrada de menor fricción es la capa de decoradores:
from signet_auth import SigningAgent, signet_tool
agent = SigningAgent.create("tool-bot", owner="team")
@signet_tool(agent=agent, target="mcp://github.prod", audit_encrypt_params=True)
def create_issue(title: str, repo: str) -> str:
return f"{repo}:{title}"
Si ejecuta un servidor MCP de Python u otro límite de ejecución, use verify_request() con un backend de nonce duradero en la forma piloto:
from signet_auth import FileNonceChecker, VerifyOptions, verify_request
nonce_checker = FileNonceChecker(".signet/nonces.json")
opts = VerifyOptions(
trusted_keys=["ed25519:..."],
expected_target="mcp://github.prod",
nonce_checker=nonce_checker,
)
result = verify_request(request_params, opts)
if not result.ok:
raise ValueError(result.error or "verification failed")
if not result.trusted:
raise ValueError("untrusted signer")
Integración con LangChain
from signet_auth import SigningAgent
from signet_auth.langchain import SignetCallbackHandler
agent = SigningAgent("my-agent")
handler = SignetCallbackHandler(agent)
# Every tool call is now signed + audited
chain.invoke(input, config={"callbacks": [handler]})
# Async chains supported too
from signet_auth.langchain import AsyncSignetCallbackHandler
Integración con CrewAI
from signet_auth import SigningAgent
from signet_auth.crewai import install_hooks
agent = SigningAgent("my-agent")
install_hooks(agent)
# All CrewAI tool calls are now globally signed
crew.kickoff()
Integración con AutoGen
from signet_auth import SigningAgent
from signet_auth.autogen import signed_tool, sign_tools
agent = SigningAgent("my-agent")
# Wrap a single tool
wrapped = signed_tool(tool, agent)
# Or wrap all tools at once
wrapped_tools = sign_tools([tool1, tool2], agent)
Integración con LangGraph
LangGraph usa el sistema de callbacks de LangChain — el mismo handler funciona directamente:
from signet_auth import SigningAgent
from signet_auth.langgraph import SignetCallbackHandler
agent = SigningAgent("my-agent")
handler = SignetCallbackHandler(agent)
result = graph.invoke(input, config={"callbacks": [handler]})
Integración con LlamaIndex
from signet_auth import SigningAgent
from signet_auth.llamaindex import install_handler
agent = SigningAgent("my-agent")
handler = install_handler(agent)
# All tool call events are now signed
index = ... # your LlamaIndex setup
response = index.as_query_engine().query("What is Signet?")
# Access receipts
print(handler.receipts)
Integración con Pydantic AI
from signet_auth import SigningAgent
from signet_auth.pydantic_ai_integration import SignetMiddleware
agent = SigningAgent("my-agent")
middleware = SignetMiddleware(agent)
@middleware.wrap
def my_tool(query: str) -> str:
return f"result: {query}"
Integración con Google ADK
from signet_auth import SigningAgent
from signet_auth.google_adk import SignetPlugin
agent = SigningAgent("my-agent")
plugin = SignetPlugin(agent)
# Pass as callback to ADK agent
Integración con Smolagents
from signet_auth import SigningAgent
from signet_auth.smolagents import signet_step_callback
agent = SigningAgent("my-agent")
callback = signet_step_callback(agent)
bot = CodeAgent(tools=[...], model=model, step_callbacks=[callback])
Integración con OpenAI Agents SDK
from signet_auth import SigningAgent
from signet_auth.openai_agents import SignetAgentHooks
agent = SigningAgent("my-agent")
oai_agent = Agent(
name="assistant",
hooks=SignetAgentHooks(agent),
tools=[...],
)
Nota: Los argumentos de las llamadas a herramientas aún no están disponibles en la API de hooks (issue #939). Solo se firma el nombre de la herramienta.
API de Bajo Nivel
from signet_auth import generate_keypair, sign, verify, Action
kp = generate_keypair()
action = Action("github_create_issue", params={"title": "fix bug"})
receipt = sign(kp.secret_key, action, "my-agent", "willamhou")
assert verify(receipt, kp.public_key)
Recibo Bilateral (Co-firma del Servidor)
from signet_auth import generate_keypair, sign, sign_bilateral, verify_bilateral, Action
# Agent signs the tool call
agent_kp = generate_keypair()
action = Action("github_create_issue", params={"title": "fix bug"})
agent_receipt = sign(agent_kp.secret_key, action, "my-agent")
# Server co-signs with the response
server_kp = generate_keypair()
bilateral = sign_bilateral(
server_kp.secret_key, agent_receipt,
{"content": [{"type": "text", "text": "issue #42 created"}]},
"github-server",
)
assert verify_bilateral(bilateral, server_kp.public_key)
assert bilateral.v == 3 # v3 = bilateral receipt
Cómo Funciona
Your Agent
|
v
SigningTransport (wraps any MCP transport)
|
+---> Signs each tool call (Ed25519)
+---> Appends Action Receipt to local audit log (hash-chained)
+---> Forwards request to MCP server (unchanged)
La firma del lado del cliente funciona sin cambiar el servidor. Si también controla el servidor, añada verifyRequest() y signResponse() opcional para verificación en el límite de ejecución y recibos bilaterales. signResponse() solo debe ejecutarse después de un verifyRequest() de confianza exitoso, y ahora puede llevar el estado final de resultado executed / failed / rejected / requires_approval dentro de la firma bilateral.
Recibo de Acción
Cada llamada a herramienta comienza con un recibo firmado. Las versiones de recibo más altas añaden co-firma del servidor (v3) y cadenas de autorización (v4):
{
"v": 1,
"id": "rec_e7039e7e7714e84f...",
"action": {
"tool": "github_create_issue",
"params": {"title": "fix bug"},
"params_hash": "sha256:b878192252cb...",
"target": "mcp://github.local",
"transport": "stdio"
},
"signer": {
"pubkey": "ed25519:0CRkURt/tc6r...",
"name": "demo-bot",
"owner": "willamhou"
},
"ts": "2026-03-29T23:24:03.309Z",
"nonce": "rnd_dcd4e135799393...",
"sig": "ed25519:6KUohbnSmehP..."
}
La firma cubre todo el cuerpo del recibo (acción + firmante + timestamp + nonce) usando JSON canónico RFC 8785 (JCS). Modificar cualquier campo invalida la firma.
Comandos CLI
| Comando | Descripción |
|---|---|
signet identity generate --name <n> | Generar identidad Ed25519 (cifrada por defecto) |
signet identity generate --unencrypted | Generar sin cifrado (para CI) |
signet identity list | Listar todas las identidades |
signet identity export --name <n> | Exportar clave pública como JSON |
signet sign --key <n> --tool <t> --params <json> --target <uri> | Firmar una acción |
signet sign --hash-only | Almacenar solo el hash de parámetros (no los parámetros sin procesar) |
signet sign --output <file> | Escribir recibo en archivo en lugar de stdout |
signet sign --no-log | Omitir la adición al registro de auditoría |
signet sign --encrypt-params | Cifrar action.params en el registro de auditoría manteniendo la salida del recibo sin cambios |
signet sign --policy <path> | Aplicar política antes de firmar e incrustar PolicyAttestation |
signet verify <receipt.json> --pubkey <name> | Verificar la firma de un recibo |
signet verify --chain | Verificar la integridad de la cadena de hash del registro de auditoría |
signet audit | Listar acciones recientes |
signet audit --since <duration> | Filtrar por tiempo (p. ej., 24h, 7d) |
signet audit --tool <substring> | Filtrar por nombre de herramienta |
signet audit --verify | Verificar todas las firmas de recibos |
signet audit --export <file> | Exportar registros como JSON |
signet audit --bundle <dir> | Construir un paquete de evidencia firmada portátil (records.jsonl + manifest.json + hash-summary.txt) para entrega de auditoría fuera del host |
signet audit --bundle <dir> --include-trust-bundle <path> | Incrustar una instantánea del paquete de confianza en el paquete de evidencia |
signet audit --restore <dir> | Re-verificar un paquete de evidencia producido previamente (funciona en cualquier máquina, sin necesidad de keystore de signet) |
signet audit --export <file> --decrypt-params | Exportar registros de auditoría originales más materialized_receipt con parámetros descifrados |
signet explore | Navegar por recibos interactivamente (tabla, detalle, estadísticas, verificación de cadena) |
signet explore --show N | Inspeccionar el recibo #N con firma, política e información de cadena |
signet explore --show N --decrypt-params | Materializar action.params cifrado para inspección local |
signet explore --stats | Estadísticas de recibos por herramienta, firmante y versión |
signet delegate create ... --ttl 24h | Crear un token de delegación con alcance (corta duración) |
signet delegate sign ... --chain <file> | Firmar con prueba de delegación y producir un recibo v4 |
signet delegate verify-auth <receipt> --trusted-roots <name> | Verificar cadena de autorización, alcance y raíz de confianza |
signet policy validate <path> | Validar sintaxis de política e imprimir su hash |
signet policy check <path> --tool <t> --params <json> | Ejecución de prueba para ver si una acción estaría permitida |
signet proxy --target <cmd> --key <name> | Ejecutar como proxy MCP stdio — firmar todas las llamadas a herramientas de forma transparente (clave de servidor efímera) |
signet proxy ... --server-key <name> | Usar una identidad de firma de servidor persistente (requerido para que los paquetes de confianza anclen una clave pública de servidor estable entre reinicios) |
signet proxy ... --policy <path> | Proxy con aplicación de políticas antes de firmar |
signet verify <bilateral.json> --trust-bundle <bundle> --nonce-store <path> | Verificar recibos bilaterales v3 con protección de reproducción que sobrevive a reinicios de procesos |
signet claude install | Instalar plugin de Claude Code (hook de firma PostToolUse) |
signet claude uninstall | Eliminar plugin de Claude Code |
signet dashboard | Abrir panel de auditoría local en el navegador |
Frase de contraseña mediante prompt interactivo o variable de entorno SIGNET_PASSPHRASE para CI.
Panel de Auditoría
Ejecute signet dashboard para abrir una interfaz web local para su registro de auditoría — sin cuenta, sin red, solo sus recibos locales.
Vista de línea de tiempo: cada llamada a herramienta registrada con firmante, nombre de herramienta, destino e ID de recibo. Filtre por tiempo, herramienta o firmante.
La pestaña Integridad de Cadena verifica la cadena de hash SHA-256 en todo su registro de auditoría — cualquier manipulación o brecha se señala al archivo y línea exactos:
Cadena rota en la línea 189: hash esperado vs. real mostrado. Así es como se ve "solo añadir" en la práctica.
Documentación
| Documento | Descripción |
|---|---|
| Arquitectura | Diseño del sistema, visión general de componentes, flujo de datos |
| Seguridad | Primitivas criptográficas, modelo de amenazas, almacenamiento de claves |
| Runbook de Implementación Piloto | Runbook de extremo a extremo para un piloto asistido por fundador: identidades, paquete de confianza, proxy --server-key, reproducción duradera, paquetes de evidencia, captura de resultados, procedimientos ante compromiso |
| Guía de Integración MCP | Configuración MCP paso a paso con SigningTransport |
| Integración CI/CD | Ejemplo de GitHub Actions, gestión de claves para CI |
| Guía de Registro de Auditoría | Consultas, filtrado, verificación de cadena de hash |
| Contribuciones | Instrucciones de compilación, flujo de trabajo de desarrollo |
| Registro de Cambios | Historial de versiones |
Estructura del Proyecto
signet/
├── crates/signet-core/ Rust core: identity, sign, verify, audit, keystore
├── signet-cli/ CLI tool (signet binary)
├── bindings/
│ ├── signet-ts/ WASM binding (wasm-bindgen)
│ └── signet-py/ Python binding (PyO3 + maturin)
├── plugins/
│ ├── claude-code/ Claude Code plugin (WASM signing + audit)
│ └── codex/ Codex CLI plugin (WASM signing + audit)
├── packages/
│ ├── signet-core/ @signet-auth/core — TypeScript wrapper
│ ├── signet-mcp/ @signet-auth/mcp — MCP SigningTransport middleware
│ ├── signet-mcp-server/ @signet-auth/mcp-server — Server verification
│ ├── signet-mcp-tools/ @signet-auth/mcp-tools — Standalone MCP signing server
│ ├── signet-node/ @signet-auth/node — Node local audit/operator helpers
│ └── signet-vercel-ai/ @signet-auth/vercel-ai — Vercel AI SDK middleware
├── examples/
│ ├── wasm-roundtrip/ WASM validation tests
│ └── mcp-agent/ MCP agent, echo server, and verifier server example
├── docs/ Design docs, specs, plans
├── LICENSE-APACHE
└── LICENSE-MIT
Compilación desde el Código Fuente
Requisitos Previos
- Rust (1.70+)
- wasm-pack
- Node.js (18+)
- Python (3.10+) + maturin (para el binding de Python)
Compilación
# Rust core + CLI
cargo build --release -p signet-cli
# WASM binding
wasm-pack build bindings/signet-ts --target nodejs --out-dir ../../packages/signet-core/wasm
# TypeScript packages
cd packages/signet-core && npm run build
cd packages/signet-mcp && npm run build
cd packages/signet-mcp-server && npm run build
cd packages/signet-mcp-tools && npm run build
cd packages/signet-node && npm run build
cd packages/signet-vercel-ai && npm run build
# Python binding
cd bindings/signet-py
pip install maturin
maturin develop
Pruebas
# Rust tests
cargo test --workspace
# Python tests
cd bindings/signet-py && pytest tests/ -v
# WASM roundtrip
node examples/wasm-roundtrip/test.mjs
# TypeScript tests
cd packages/signet-core && npm test
cd packages/signet-mcp && npm test
cd packages/signet-mcp-server && npm test
cd packages/signet-mcp-tools && npm test
cd packages/signet-node && npm test
# Plugin tests
cd plugins/claude-code && npm test
cd plugins/codex && npm test
# Vercel AI SDK tests
cd packages/signet-vercel-ai && npm test
# Reference verifier server smoke test
cd examples/mcp-agent && npm run smoke
Seguridad
- Firmas Ed25519 (nivel de seguridad de 128 bits,
ed25519-dalek) - Derivación de claves Argon2id (mínimo recomendado por OWASP)
- Cifrado de claves XChaCha20-Poly1305 con datos asociados autenticados (AAD)
- Cadena de hash SHA-256 para registro de auditoría a prueba de manipulaciones
- JSON canónico RFC 8785 (JCS) para firmas deterministas
Claves almacenadas en ~/.signet/keys/ con permisos 0600. Anule con la variable de entorno SIGNET_HOME.
Qué demuestra Signet
- La clave X del agente firmó la intención de llamar a la herramienta Y con los parámetros Z en el tiempo T
Qué NO demuestra Signet (aún)
- Que el servidor MCP ejecutó la acción (use recibos bilaterales con
signResponse()para co-firma del servidor — incluido en v0.4) - Que signer.owner realmente controla la clave (planificado: registro de identidades)
Signet es primero una capa de evidencia: demuestra lo que sucedió. También puede aplicar verificaciones en el límite de firma y en el límite de ejecución, pero no reemplaza el sandboxing, el diseño de privilegios mínimos ni la aprobación humana cuando estos son requeridos.
Proyectos Relacionados
- Prismer Cloud — Harness de agente completo con motor de evolución, capa de memoria, comunidad e identidad Ed25519/DID integrada. Usa Prismer Cloud para la plataforma de agente completa; usa Signet cuando solo necesites la capa de atestación independiente.
- Prismer.AI — La plataforma de investigación de IA de código abierto
Historial de estrellas
Si Signet te resulta útil, por favor dale una estrella a este repositorio: ayuda a que más equipos lo encuentren.
Licencia
Licencia dual Apache-2.0 + MIT.