Skip to main content
Glama

你的 AI 代理刚刚调用了一个工具。你能证明它做了什么吗?

大多数代理栈在事后记录操作,但从不验证实际发送的内容。如果请求被重放、篡改或伪造,执行端将无法知晓。

Signet 解决了这个问题:每个代理都获得一个 Ed25519 身份,每个工具调用都被签名,一个哈希链审计日志记录了发生的一切,客户端或服务器可以在信任请求之前对其进行验证。3 行代码签名。3 行代码验证。开源。

如果 Signet 对你有帮助,请给此仓库加星以帮助更多团队发现它。

从下面的 CLI 流程开始查看签名操作,然后跳转到查看它拒绝错误请求,观察服务器在未签名、被篡改、过时或目标错误的请求运行之前将其拦截。

为什么选择 Signet

Signet 为代理操作添加了一个轻量级的信任层:

  • 签名:使用代理的加密密钥对每个工具调用进行签名

  • 审计:使用仅追加的哈希链本地日志记录发生的一切

  • 验证:离线验证任何操作收据,无需网络

  • 集成:与 Claude Code、Codex CLI、MCP 客户端和服务器、Python 框架以及 Vercel AI SDK 集成

30 秒内试用

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)

如果你是新手,请从以下四条路径之一开始:

选择你的路径

  • Claude Code:最适合在编码代理中进行最快的首次运行。在 Claude Code 中运行 /plugin install signet@claude-plugins-official。5 分钟内,你将拥有已签名的工具调用和位于 ~/.signet/audit/ 的本地审计日志。

  • Codex CLI:最适合在 Codex 中签署 Bash 工具调用。将 plugins/codex/ 复制到 ~/.codex/plugins/signet 并添加一个 PostToolUse 钩子。5 分钟内,你将使用相同的审计跟踪在 Codex 中拥有已签名的 Bash 操作。

  • MCP 客户端:如果你控制 MCP 客户端或传输,这是最佳选择。使用 new SigningTransport(inner, secretKey, "my-agent") 包装你的传输。5 分钟内,你将拥有已签名的 tools/call 请求,并在 params._meta._signet 中包含收据。

  • MCP 服务器:如果你想在执行前进行验证,这是最佳选择。在你的工具处理程序中调用 verifyRequest(request, {...})。5 分钟内,你将在执行边界拥有签名者、新鲜度、目标绑定以及工具/参数检查。

查看它拒绝错误请求

运行最短的执行边界演示:

cd examples/mcp-agent
npm run execution-boundary-demo

查看 examples/mcp-agent/demo-execution-boundary.mjs 获取演示源码。

团队何时需要 Signet

  • 你需要为编码代理、MCP 工具或 CI 自动化提供审计跟踪

  • 你需要在事件发生后证明是哪个代理请求了操作

  • 你需要无需依赖托管服务即可离线验证的收据

  • 你想要已签名的工具调用证据,而无需在你的栈中添加代理或网关

Signet 是什么,不是什么

  • Signet 是代理操作的证明层:签名、审计和验证

  • Signet 旨在通过 SDK、插件和 MCP 中间件融入现有的代理栈

  • Signet 不是策略引擎、防火墙或操作拦截器

  • Signet 不是网关的替代品;它是预防和执行工具的补充

安装

# 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 (Vercel AI SDK middleware)
npm install @signet-auth/vercel-ai

快速入门

Claude Code 插件

Claude Code 中自动签署每个工具调用,无需配置:

# 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

每个工具调用都使用 Ed25519 签名,并记录到 ~/.signet/audit/ 的哈希链审计跟踪中。

其他安装方法:

# From Git
claude plugin add --from https://github.com/Prismer-AI/signet

# Via signet CLI
signet claude install

Codex 插件

Codex CLI 中自动签署每个 Bash 工具调用:

git clone https://github.com/Prismer-AI/signet.git
cp -r signet/plugins/codex ~/.codex/plugins/signet

然后将钩子添加到 ~/.codex/hooks.json

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "node \"$HOME/.codex/plugins/signet/bin/sign.cjs\"",
        "timeout": 5
      }]
    }]
  }
}

或者使用 MCP 服务器进行按需签名工具:

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

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!" },
});

每个 tools/call 请求都会将已签名的收据注入到 params._meta._signet 中。

MCP 服务器验证

如果你也控制 MCP 服务器,请在执行前验证请求:

import { verifyRequest } from "@signet-auth/mcp-server";

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const verified = verifyRequest(request, {
    trustedKeys: ["ed25519:..."],
    maxAge: 300,
  });
  if (!verified.ok) return { content: [{ type: "text", text: verified.error }], isError: true };
  console.log(`Verified: ${verified.signerName}`);
  // process tool call...
});

Vercel AI SDK 集成

import { generateText } from "ai";
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-4"),
  tools: { myTool },
  ...callbacks,
  prompt: "...",
});

// Every tool call is now signed
console.log(callbacks.receipts);

参考 MCP 服务器

此仓库还包含一个最小的 MCP 参考服务器,演示了使用 @signet-auth/mcp-server 进行服务器端验证。

cd examples/mcp-agent
npm ci
npm run verifier-server

可用工具:

  • inspect_current_request — 如果当前 MCP 工具调用包含 params._meta._signet,则验证该调用

  • verify_receipt — 根据公钥验证原始 Signet 收据

  • verify_request_payload — 离线验证合成的 MCP tools/call 有效负载

环境变量:

  • SIGNET_TRUSTED_KEYS — 以逗号分隔的 ed25519:<base64> 公钥

  • SIGNET_REQUIRE_SIGNATUREtruefalse(默认 false

  • SIGNET_MAX_AGE — 收据最大有效期(秒,默认 300

  • SIGNET_EXPECTED_TARGET — 可选的预期 receipt.action.target

独立 MCP 签名服务器

@signet-auth/mcp-tools 将 Signet 签名、验证和内容哈希作为 MCP 工具公开 — 插入任何兼容 MCP 的客户端:

npx @signet-auth/mcp-tools

可用工具:signet_generate_keypair, signet_sign, signet_verify, signet_content_hash

Python (LangChain / CrewAI / AutoGen + 6 更多)

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}")

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

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()

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)

LangGraph 集成

LangGraph 使用 LangChain 的回调系统 — 相同的处理程序可以直接工作:

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]})

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)

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}"

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

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])

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=[...],
)

注意: 工具调用参数在钩子 API 中尚不可用(issue #939)。仅签署工具名称。

低级 API

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)

双边收据(服务器共同签名)

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

工作原理

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)

仅代理端。MCP 服务器无需更改。

操作收据

每个工具调用都会产生一个已签名的收据:

{
  "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..."
}

签名涵盖整个收据主体(操作 + 签名者 + 时间戳 + 随机数),使用 RFC 8785 (JCS) 规范 JSON。修改任何字段都会使签名失效。

CLI 命令

命令

描述

signet identity generate --name <n>

生成 Ed25519 身份(默认加密)

signet identity generate --unencrypted

生成不加密的身份(用于 CI)

signet identity list

列出所有身份

signet identity export --name <n>

将公钥导出为 JSON

signet sign --key <n> --tool <t> --params <json> --target <uri>

签署操作

signet sign --hash-only

仅存储参数哈希(非原始参数)

signet sign --output <file>

将收据写入文件而不是 stdout

signet sign --no-log

跳过审计日志追加

signet verify <receipt.json> --pubkey <name>

验证收据签名

signet verify --chain

验证审计日志哈希链完整性

signet audit

列出最近的操作

signet audit --since <duration>

按时间过滤(例如 24h, 7d)

signet audit --tool <substring>

按工具名称过滤

signet audit --verify

验证所有收据签名

signet audit --export <file>

将记录导出为 JSON

signet claude install

安装 Claude Code 插件 (PostToolUse 签名钩子)

signet claude uninstall

卸载 Claude Code 插件

通过交互式提示或 SIGNET_PASSPHRASE 环境变量(用于 CI)传递密码。

文档

文档

描述

架构

系统设计、组件概述、数据流

安全

加密原语、威胁模型、密钥存储

MCP 集成指南

使用 SigningTransport 进行 MCP 设置的分步指南

CI/CD 集成

GitHub Actions 示例,CI 的密钥管理

[审计日志指南](docs

Install Server
A
security – no known vulnerabilities
A
license - permissive license
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Prismer-AI/signet'

If you have feedback or need assistance with the MCP directory API, please join our Discord server