跳转到主要内容
一份合规报告只有当审计员能够信任它自你生成后未被编辑时,才对 他们有用。OrcaRouter 产生的每份报告都携带两样东西,让这一检查 无需任何账户访问即可进行:规范化证据的一个 SHA-256 内容哈希, 以及针对该哈希的一个 Ed25519 签名。本页展示如何验证一份合规 报告——获取公钥、确认哈希、检查签名——只用公共端点。 用例很具体:你交给审计员一份签名报告(或一个 共享门户链接),而他们在 依赖它之前需要证明它真实且未被篡改。他们从不触碰你的工作区、 你的密钥或控制台。

1. 随报告一同传递的东西

三个值让报告自验证。它们出现在报告制品上,以及链接的公共共享 门户元数据上。
报告规范化证据 JSON 的一个小写十六进制 SHA-256 摘要。对于 给定的报告,这些字节是确定的,所以任何持有相同证据的人都能 重新计算出相同的哈希。对证据的任何编辑都会改变这个值。
一个针对十六进制 content_hash 计算的 base64 Ed25519 签名。 它证明该哈希由 OrcaRouter 的签名密钥签署,未被伪造。
活跃公钥的一个短而稳定的标识符(例如 orca- 后跟一段 十六进制片段)。验证者用它来确认报告由当前已发布的密钥签署 ——由未知密钥 id 签署的报告会故障关闭。
签名覆盖的是内容哈希,而非直接覆盖渲染出的 PDF、CSV 或 JSON 字节。同一份证据从一个哈希渲染为全部三种格式,所以完整性保证 落在底层证据上——给定报告的每次导出都共享同一个 content_hashsignaturesig_key_id

2. 获取公钥

签名公钥发布在一个开放端点上——无需认证、无需工作区上下文。 审计员直接调用它。
curl https://api.orcarouter.ai/api/public/compliance/pubkey
{
  "success": true,
  "message": "",
  "data": {
    "algo": "ed25519",
    "key_id": "orca-1a2b3c4d5e6f",
    "public_key": "base64-encoded-ed25519-public-key"
  }
}
public_key 是 base64 编码的 32 字节 Ed25519 公钥。这里的 key_id 必须与报告上的 sig_key_id 匹配——如果不匹配,报告就是 由一个不同的(很可能已轮换或更旧的)密钥签署的,且不会针对这个 已发布的密钥验证通过。

3. 验证签名

你可以用两种方式验证签名。要么请 OrcaRouter 为你检查这个元组, 要么用已发布的公钥完全离线验证。

托管的验证端点

把报告中的三个值 POST 到开放的验证端点。它是公共的——审计员 不带任何凭据调用它。
curl -X POST https://api.orcarouter.ai/api/public/compliance/verify \
  -H "Content-Type: application/json" \
  -d '{
    "content_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
    "signature": "base64-ed25519-signature-from-the-report",
    "sig_key_id": "orca-1a2b3c4d5e6f"
  }'
{
  "success": true,
  "message": "",
  "data": {
    "valid": true,
    "key_id": "orca-1a2b3c4d5e6f"
  }
}
valid: true 意味着签名针对该密钥 id 的活跃密钥校验通过。 valid: false 意味着要么签名与哈希不匹配、哈希为空,要么 sig_key_id 与当前已发布的密钥不匹配。
验证端点会回显活跃的 key_id。把它与你提交的 sig_key_id 比较: 如果它们不同,报告就是由一个不再是活跃密钥的密钥签署的,这正是 它验证失败的原因。

用公钥离线验证

一位多疑的审计员根本不需要信任验证端点。因为算法是针对十六进制 内容哈希的标准 Ed25519,签名可以用任何加密库检查:
import base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

# public_key from GET /api/public/compliance/pubkey
pub = Ed25519PublicKey.from_public_bytes(base64.b64decode(PUBLIC_KEY_B64))

# content_hash + signature from the report
message = CONTENT_HASH.encode()            # the hex hash string, as bytes
signature = base64.b64decode(SIGNATURE_B64)

pub.verify(signature, message)             # raises if invalid; returns None if valid
被签名的消息是十六进制哈希字符串本身,编码为 ASCII 字节 ——而不是该哈希解码出的原始 32 字节。在签名验证之前原样传入 content_hash 值,否则在一份正确的报告上检查也会失败。

4. 签名覆盖什么

签名证明报告的 content_hash 由 OrcaRouter 签署,而哈希证明证据 未被编辑。有一处微妙之处:哈希是针对网关构建的证据的规范化 形式计算的——而非 JSON 或 PDF 文件的原始字节。所以你自己 重新哈希下载的制品不会重现 content_hash。请使用验证端点 (§2/§3),它会为你重新计算规范化哈希并检查 Ed25519 签名:
检查含义
signature_valid: truecontent_hash 由 OrcaRouter 的密钥签署——证据真实且未被编辑。
密钥 id 匹配报告 sig_key_id == 已发布的密钥 id → 由活跃密钥签署。
两者都通过意味着报告真实且未被篡改。签名失败意味着哈希、证据 或密钥 id 不属于 OrcaRouter 的签名密钥。

5. 验证一份共享报告

当你给审计员发送一个 共享门户链接 而不是文件时,门户元数据已经携带 content_hashsignaturesig_key_id,外加一个服务端计算的 signature_valid 标志。审计员 既可以信任该标志,可以针对公钥独立重跑上面的检查——共享 门户无需登录,验证路径完全相同。
一个共享制品只在其戳记区域仍与你工作区声明的 数据驻留区域 匹配时才提供 服务。如果区域被更改,即使签名元数据仍可验证,下载也会被扣留。 这是有意为之——参见 跨区域读取

6. 接下来去哪里

签名报告

一份签名报告如何生成、它捕获什么证据,以及如何铸造一个 审计员共享链接。

导出证据

把报告证据拉取为 PDF、CSV 或 JSON,供你审计员的工作底稿。

数据驻留

报告上的区域戳记如何治理它存储和提供服务的位置。

责任共担

OrcaRouter 在网关路径上保证什么、什么仍是你的。
签名密钥是 OrcaRouter 的;验证是任何人的。这种区分正是全部要点 所在——审计员证明一份报告真实,而无需访问产生它的那个工作区。