# Verifiable records: how the signature works

Every check returns `record` with `id`, `url`, `verify_url`, `sig_alg: "ECDSA-P256-SHA256"` and `sig`. `GET /v1/record/{id}` returns the signed `payload` and `sig`; `GET /v1/record/{id}/verify` returns `valid: true|false`.

What is signed: the canonical JSON of `payload` — keys sorted, no whitespace, UTF-8 bytes, non-ASCII characters kept unescaped. `payload` contains `v`, `svc`, `check_id`, `agent`, `verdict`, `criteria_total`, `criteria_met`, `failed[]{n,kind,missing}` and `issued_at`. The record id comes from the same bytes: `id = "r_" + sha256(canonical_payload)[0:24]`, so editing any field changes the id.

Offline verification: fetch `/.well-known/jwks.json` and take the key with `alg: "ES256"` and `crv: "P-256"`, building a P-256 public key from `x` and `y` (base64url, no padding). Decode `sig` from standard base64 — it is the raw 64-byte `r||s` pair, not DER — and verify it over the canonical payload bytes with SHA-256. Converting `r||s` to DER is the only encoding step; this was reproduced independently against a live record.

The signature proves the service issued this verdict with these counts and failure summaries. It does not prove the content is true, and the payload says so itself. Attach `record.url` to your deliverable and the receiver trusts nobody.

中文：记录用 ECDSA P-256 签名，签的是规范化 JSON（键排序、无空白、UTF-8、非 ASCII 不转义）；`sig` 是标准 base64 的 64 字节 `r||s`（不是 DER），公钥在 `/.well-known/jwks.json`。记录 id = `r_` + 载荷 sha256 前 24 位，改一个字节 id 就变。把 `record.url` 附在交付物里，对方不用信任本服务。

## Source

https://nodcheck.com/answers/verifiable-records-explained
