tresor-attest is the open-source (Apache-2.0) verifier SDK that turns the GET /attestation envelope into a hard cryptographic pin: every HTTPS request your code makes is gated on a fresh attestation check, and the call refuses to send a single byte of payload if the endpoint is not running a binary in Tresor's audited allowlist.
It is the customer-side counterpart to the Attestation trust model.
| Use case | Use tresor-attest? |
|---|---|
| Regulated workload that must prove the endpoint isn't proxied | Yes — this is the primary use case. |
| Defence against a compromised CA or TLS-terminating middlebox | Yes — pinning is rooted in the SNP report, not the WebPKI. |
| One-shot CI smoke check or audit | Use the tresor-verify CLI instead. |
| Pure browser app (no Node runtime) | Not yet — SDKs require Node ≥ 20, Python, or Go. |
If pinning fails, the call raises a typed AttestationError subclass (MeasurementNotAllowedError, IdentityTagNotAllowedError, TCBBelowFloorError, ReportDataMismatchError, SPKIMismatchError, BundleSignatureInvalid, …) before any application data crosses the wire. There is no soft-fail mode.
| Language | Package | Install |
|---|---|---|
| Python ≥ 3.10 | tresorhq-attest (import attest) | pip install tresorhq-attest |
| Node.js ≥ 20 (ESM) | @tresorhq/attest | npm install @tresorhq/attest |
| Go ≥ 1.22 | github.com/tresorhq/attest/go | go get github.com/tresorhq/attest/go/attest |
All three implement the same verifier algorithm and share the same conceptual error set; only the surface idioms differ.
tresorhq-attestDrop-in httpx transport. Works with any client that accepts a custom httpx transport — including the OpenAI Python SDK.
httpx directlyimport httpx
from attest import AttestedTransport, AttestationError
with httpx.Client(transport=AttestedTransport()) as client:
try:
resp = client.get("https://api.tresor.co/v1/models")
except AttestationError as err:
print(f"refused: {type(err).__name__}: {err}")
raise
import httpx
from openai import OpenAI
from attest import AttestedTransport
openai = OpenAI(
base_url="https://api.tresor.co/v1",
api_key="YOUR_API_KEY",
http_client=httpx.Client(transport=AttestedTransport()),
)
resp = openai.chat.completions.create(
model="global/redpill/gpt-oss-120b",
messages=[{"role": "user", "content": "Hello!"}],
)
The SDK ships with the production Tresor release-root public key bundled. To pin a private deployment or a pre-rotation key, pass the public key explicitly:
from pathlib import Path
from attest import AttestedTransport
transport = AttestedTransport(
release_root_pubkey=Path("./my-release-root.pub").read_bytes(),
)
For callers that already have the envelope and bundle in hand (e.g. cached, or fetched by another process):
import json
from attest import Envelope, verify, load_bundled_release_root
envelope = Envelope.from_dict(json.loads(http_response_body))
verified = verify(
envelope=envelope,
bundle_jws=bundle_jws_string,
release_root_pubkey=load_bundled_release_root(),
live_tls_spki=live_tls_spki_sha256_bytes,
)
print(verified.measurement.hex(), verified.workload_identity_tag.hex())
@tresorhq/attestDrop-in fetch wrapper. Requires Node.js ≥ 20, ESM-only, zero runtime dependencies.
fetch directlyimport { createAttestedFetch, AttestationError } from "@tresorhq/attest";
const attestedFetch = createAttestedFetch();
try {
const resp = await attestedFetch("https://api.tresor.co/v1/models");
console.log(await resp.text());
} catch (err) {
if (err instanceof AttestationError) {
console.error(`refused: ${err.constructor.name}: ${err.message}`);
}
throw err;
}
import OpenAI from "openai";
import { createAttestedFetch, AttestationError } from "@tresorhq/attest";
const openai = new OpenAI({
baseURL: "https://api.tresor.co/v1",
apiKey: process.env.TRESOR_API_KEY,
fetch: createAttestedFetch(),
});
try {
const resp = await openai.chat.completions.create({
model: "global/redpill/gpt-oss-120b",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(resp.choices[0]?.message?.content);
} catch (err) {
// The OpenAI SDK wraps fetch errors in APIConnectionError;
// the original AttestationError is on `err.cause`.
const cause = (err as { cause?: unknown })?.cause ?? err;
if (cause instanceof AttestationError) {
console.error(`refused: ${cause.constructor.name}: ${cause.message}`);
}
throw err;
}
import { readFileSync } from "node:fs";
import { createAttestedFetch } from "@tresorhq/attest";
const attestedFetch = createAttestedFetch({
releaseRootPubKey: readFileSync("./my-release-root.pub"),
});
import {
parseEnvelope,
verify,
loadBundledReleaseRoot,
} from "@tresorhq/attest";
const envelope = parseEnvelope(JSON.parse(httpResponseBody));
const verified = verify(
envelope,
bundleJws,
loadBundledReleaseRoot(),
liveTlsSpkiSha256,
);
github.com/tresorhq/attest/goPure verifier library for Go callers managing their own HTTP layer. The Go SDK is currently the only one that already verifies the production Azure HCL vTPM envelope (tresor.attestation/v1.az-snp-vtpm); the Python and TypeScript SDKs verify the bare-SNP envelope today and are tracking the vTPM extension.
package main
import (
"time"
"github.com/tresorhq/attest/go/attest"
)
func main() {
tuple, err := attest.Verify(attest.Inputs{
Envelope: envelope, // GET /attestation
BundleJWS: bundleJWS, // GET <trust_bundle_url>
ReleaseRootPubKey: releaseRoot, // ed25519.PublicKey
LiveTLSSPKI: liveSPKI, // SHA-256 of leaf SPKI from live TLS
Now: time.Now(),
})
if err != nil {
// Typed sentinel error: errors.Is(err, attest.ErrMeasurementNotAllowed) etc.
return
}
_ = tuple // VerifiedTuple{ Measurement, WorkloadIdentityTag, ... }
}
See attest/attest.go for the full Inputs, VerifiedTuple, and sentinel error list.
On the first request per (host, TLS cert), every SDK performs the same checks (matching the Attestation verifier algorithm step-for-step):
GET /attestation from the host.trust_bundle_url.MEASUREMENT, workload_identity_tag, and REPORTED_TCB against the bundle's allowlists/floor.REPORT_DATA[0:32] == SHA-256(tls_spki || workload_identity_tag).workload_identity_manifest_jws signature using the key named in trust_bundle.delegated_keys.workload_manifest when present, falling back to the release-root pubkey for legacy bundles, then confirm SHA-256(jws) == workload_identity_tag.The verified tuple is cached until the TLS cert rotates or the bundle expires. The cache can be inspected via attestedFetch.cache.size() (TypeScript) or the equivalent on each SDK.
Runnable end-to-end smoke tests for each language (including OpenAI-SDK integration) live under tresorhq/attest/examples/:
Run any example with ATTEST_HOST=https://api.tresor.co (the default) to verify the production fleet, or against your own private deployment.
GET /attestation — the envelope these SDKs consume