# TEE 机密计算证明 (/docs/zh-CN/tee-proof)

给 API Key 开启「TEE 机密计算证明」后，这把 Key 的响应会附带一份由 [VeriRelay](https://verirelay.com/zh) 签名的回执。回执写明接收请求的供应商主机（例如 `api.anthropic.com`），并带有请求体和响应体的 SHA-256 哈希。核验在 VeriRelay 上进行，你不必相信我们的一面之词：VeriRelay 的签名密钥只存在于 AMD SEV-SNP 机密虚拟机中，证明这一点的远程证明是公开的。

## 开启 [#开启]

在 [API Key](https://www.ohmygpt.com/keys) 页面新建或编辑 Key，打开「TEE 机密计算证明」。代码不用改，这把 Key 发出的每个请求都会要求证明。

## 带证明的响应 [#带证明的响应]

```http
X-VeriRelay-Request-Id: 36a420474e713c4ecbe0a6d5dfd79ed0
X-VeriRelay-Store-Id: cFMrwmc4IeTQT14_R9y6gg
X-VeriRelay-Store-Key: <secret>
```

| 响应头 | 用途 |
|---|---|
| `X-VeriRelay-Request-Id` | 取签名回执 |
| `X-VeriRelay-Store-Id`、`X-VeriRelay-Store-Key` | 取回并解密供应商收到和发出的原始请求体与响应体。Store-Key 请当作密钥保管：拿到它的人在 VeriRelay 删除存档之前都能看到这次交换的内容。 |

不带这几个响应头的响应就是未经证明。证明是尽力而为的：无法证明的请求照常应答，只是不带这几个响应头。对话接口（Chat Completions、Responses、Anthropic Messages、Gemini）的请求可以证明；embeddings、图片、音频等其他接口的响应不带回执，部分模型也不带。中途结束的流没有回执。

对任何带证明的请求，`GET /v1/generation?id=<X-Request-ID>` 也会返回同样的值，以及 VeriRelay 删除各部分的时间：

```json
"verirelay": {
  "request_id": "36a420474e713c4ecbe0a6d5dfd79ed0",
  "store_id": "cFMrwmc4IeTQT14_R9y6gg",
  "store_key": "<secret>",
  "relay": "https://relay.verirelay.com",
  "receipt_expires_at": "2026-11-11T08:45:48Z",
  "store_expires_at": "2026-11-12T07:45:48Z"
}
```

## 核验回执 [#核验回执]

在[用量](https://www.ohmygpt.com/usage)页面打开标有「可验证」的请求，点「去 VeriRelay 核验」即可。想自己拼链接，把这几个值放在 `#` 之后：

```text
https://verirelay.com/zh/verify#relay=https%3A%2F%2Frelay.verirelay.com&request_id=<X-VeriRelay-Request-Id>&store_id=<X-VeriRelay-Store-Id>&store_key=<X-VeriRelay-Store-Key>
```

浏览器不会把 `#` 之后的内容发给任何服务器，所以 Store-Key 只留在你自己的电脑上。核验页先检查签名和远程证明，再解密存档的原文，与哈希逐一比对。去掉 `store_id` 和 `store_key` 就只核验回执本身。

在代码里核验时，直接取回执，不需要 Key：

```bash
curl https://relay.verirelay.com/v1/avr/receipts/36a420474e713c4ecbe0a6d5dfd79ed0
```

```json
{
  "version": "avr/1",
  "canonicalization": "jcs-rfc8785",
  "signature_algorithm": "ed25519",
  "hash_algorithm": "sha256",
  "request_id": "36a420474e713c4ecbe0a6d5dfd79ed0",
  "timestamp": "2026-11-11T07:45:48.036395467Z",
  "method": "POST",
  "upstream_authority": "api.deepseek.com",
  "upstream_path": "/v1/chat/completions",
  "request_body_sha256": "…",
  "response_body_sha256": "…",
  "response_status": 200,
  "upstream_tls": { "sni": "api.deepseek.com", "spki_sha256": "…" },
  "service_public_key": "…",
  "key_id": "5262ba4e3931cd2a",
  "signature": { "payload_sha256": "…", "value": "…" }
}
```

`upstream_authority` 是应答的主机，`upstream_tls.spki_sha256` 是它出示的证书的指纹。`GET /v1/avr/evidence/<request_id>` 返回回执以及 SEV-SNP 远程证明，后者把签名密钥绑定到这台机密虚拟机上。格式规范见 [avr1.md](https://github.com/verirelay/protocol/blob/main/docs/avr1.md)。

## 保存证明 [#保存证明]

VeriRelay 保存签名回执 **1 小时**、原文 **24 小时**，到期即删除。想长期保留证明，请在一小时内保存 evidence 包：它自带签名和远程证明，VeriRelay 的副本删除后照样可以核验。

## 回执证明的范围 [#回执证明的范围]

回执证明的是与供应商之间的那次交换。你收到的内容与它逐字节一致，只有以下几处不同：

| 修改 | 在哪里看到 |
|---|---|
| 协议转换：用供应商不支持的协议调用模型时 | 存档的请求是供应商的协议格式 |
| 模型名：供应商收到的是它自己的模型 ID | 存档请求里的 `model` |
| 费用 | `X-Cost-Credits`，流式请求里的 `: x-cost-credits` 行 |
| Responses 的 ID：响应开启存储时 | OhMyGPT 签发的 `resp_*` ID |
| 输出上限：余额付不起你请求的上限时 | `X-Output-Tokens-Capped` 给出新的上限，与存档请求里的一致（[详见](/docs/zh-CN/costs#余额不足时)） |

存档的原文是供应商发出的原始字节，可能经过 gzip 压缩，哈希覆盖的也是压缩后的字节。与你收到的内容比对前，请先解压。
