Vault view keys & proof-of-reserves
Sable Vault seals everything sensitive by default: declared value, yield, maturity, positions, all readable only by the issuer or the holder. That is the right default, and it is the wrong answer the moment a regulator or an auditor needs to see the book. View keys resolve that without weakening the default: privacy by default, transparency by permission. The issuer grants a specific party read access to specific fields, for a bounded time, and revokes it at will.
Granting a scoped view
POST /v1/vault/assets/{id}/view-grant (session-authed, issuer only) mints a view
key over exactly the fields you name.
curl https://api.buildsable.com/v1/vault/assets/$ASSET_ID/view-grant \
-H "Authorization: Bearer $SABLE_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"scope": ["holders", "value", "nav"],
"label": "Q3 auditor: Ernst example LLP",
"expires_in_days": 30
}'scope: the fields the grantee may read, any ofholders,value,yield,maturity,nav,documents. Nothing outside the scope is ever returned.label: a note to yourself naming who this grant is for.expires_in_days: when the view key stops working.
{
"grant_id": "vg_7c02…",
"token": "vk_…",
"url": "https://api.buildsable.com/v1/vault/view/vk_…",
"note": "The token is shown once. Share it over a secure channel; it grants read access to the scoped fields until it expires or is revoked."
}
The token is returned exactly once. The grantee needs no Sable account: they
read the granted fields at the public endpoint, and see only what the scope allows.
# The grantee, with only the token:
curl https://api.buildsable.com/v1/vault/view/$VIEW_TOKEN{
"asset": { "id": "…", "name": "Series A receivables", "type": "receivable" },
"scope": ["holders", "value", "nav"],
"holders": [{ "wallet": "0x…", "position_usd": 380000 }],
"value": { "declared_usd": 500000 },
"nav": { "nav_usd": 496200, "as_of": "2026-08-30T00:00:00Z" },
"chain_head": "a91f…",
"expires_at": "2026-09-30T00:00:00Z"
}
A field outside the granted scope is simply absent from the response. The
response also carries the asset's current chain_head, so a grantee can
cross-check what they were shown against the public
event chain and confirm the record is intact.
Managing grants
GET /v1/vault/assets/{id}/view-grants (issuer only) lists the live grants on an
asset with their scope, label, and expiry. DELETE /v1/vault/view-grants/{id}
revokes one immediately; the token stops resolving on the next request. Grants are
per-asset and independent, so a grant to one auditor never widens what another can
see.
NAV and proof-of-reserves
An auditor often needs one number proven, not the whole book: the net asset value,
and that reserves cover it. POST /v1/vault/assets/{id}/nav (issuer only) records
a NAV attestation.
curl https://api.buildsable.com/v1/vault/assets/$ASSET_ID/nav \
-H "Authorization: Bearer $SABLE_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"nav_usd": 496200,
"reserves_usd": 500000,
"as_of": "2026-08-30T00:00:00Z",
"note": "August month-end mark"
}'The gateway seals nav_usd and reserves_usd at rest, appends a hash-chained
nav_attestation event to the asset's ledger (so it
anchors to Solana with everything else), and returns a signed proof:
{
"proof": "eyJ2Ijoi…",
"signature": "0x4f8c…",
"signer": "0xA1b2…9F",
"payload": {
"asset_id": "…",
"nav_usd": 496200,
"solvent": true,
"as_of": "2026-08-30T00:00:00Z",
"chain_head": "a91f…",
"anchor": { "state": "anchored", "signature": "<base58 signature>" },
"trust_model": "attested by the Sable registry over its hash-chained ledger, publicly anchored when an anchor exists, not zero-knowledge"
},
"verify": "POST /v1/receipts/verify { receipt: proof, signature }"
}
The proof discloses the NAV and a solvent flag (true when reserves_usd >= nav_usd), without publishing the book. A counterparty verifies it through the
same public receipt verify endpoint as everything else, confirms
NAV and solvency, and learns nothing about individual positions, counterparties, or
the reserve composition unless you separately grant a view over those fields. If you
provide no reserves_usd, the proof carries the NAV without a solvency claim rather
than asserting one it can't support.
Honest scope
Everything here is registry infrastructure, not custody or audit. The figures are issuer-declared: the registry seals them, chains them so they are tamper-evident, anchors them publicly, and proves the record's integrity. It does not hold the assets, verify that the reserves exist, or appraise the NAV. A proof means Sable's signature is genuine, the ledger it signed over is intact, and its anchors are on a public chain. It does not mean Sable has independently confirmed what an issuer stated. That confirmation is what an auditor does with the view key you grant them.