tresor-attest SDK

Drop-in fetch / httpx / Go wrappers that verify the Tresor API endpoint is the genuine binary inside an AMD SEV-SNP Confidential VM before any request data leaves your process.

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.

When to use it

Use caseUse tresor-attest?
Regulated workload that must prove the endpoint isn't proxiedYes — this is the primary use case.
Defence against a compromised CA or TLS-terminating middleboxYes — pinning is rooted in the SNP report, not the WebPKI.
One-shot CI smoke check or auditUse 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.

Packages

LanguagePackageInstall
Python ≥ 3.10tresorhq-attest (import attest)pip install tresorhq-attest
Node.js ≥ 20 (ESM)@tresorhq/attestnpm install @tresorhq/attest
Go ≥ 1.22github.com/tresorhq/attest/gogo 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.

Python — tresorhq-attest

Drop-in httpx transport. Works with any client that accepts a custom httpx transport — including the OpenAI Python SDK.

With httpx directly

import 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

With the OpenAI SDK

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!"}],
)

Pinning a custom release root

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(),
)

Lower-level API

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())

Node.js / TypeScript — @tresorhq/attest

Drop-in fetch wrapper. Requires Node.js ≥ 20, ESM-only, zero runtime dependencies.

With fetch directly

import { 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;
}

With the OpenAI SDK

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;
}

Pinning a custom release root

import { readFileSync } from "node:fs";
import { createAttestedFetch } from "@tresorhq/attest";

const attestedFetch = createAttestedFetch({
  releaseRootPubKey: readFileSync("./my-release-root.pub"),
});

Lower-level API

import {
  parseEnvelope,
  verify,
  loadBundledReleaseRoot,
} from "@tresorhq/attest";

const envelope = parseEnvelope(JSON.parse(httpResponseBody));
const verified = verify(
  envelope,
  bundleJws,
  loadBundledReleaseRoot(),
  liveTlsSpkiSha256,
);

Go — github.com/tresorhq/attest/go

Pure 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.

What is verified

On the first request per (host, TLS cert), every SDK performs the same checks (matching the Attestation verifier algorithm step-for-step):

  1. Fetch GET /attestation from the host.
  2. Fetch the JWS at the envelope's trust_bundle_url.
  3. Verify the bundle JWS signature against the pinned release-root public key (bundled with each SDK release; overridable per-instance).
  4. Verify the VCEK certificate chain up to the AMD root CA carried in the bundle.
  5. Verify the SNP report's ECDSA-P384 signature against the VCEK leaf.
  6. Check MEASUREMENT, workload_identity_tag, and REPORTED_TCB against the bundle's allowlists/floor.
  7. Check REPORT_DATA[0:32] == SHA-256(tls_spki || workload_identity_tag).
  8. Check the live TLS SubjectPublicKeyInfo SHA-256 matches the envelope.
  9. Verify the 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.

Examples repository

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.

See also