Verification is what turns “the database claims to be in a TEE” into a cryptographic fact. Skipping it gives you transport security without any guarantee that the program on the other end is the program you expect — defeating the point of running TeeSQL.Documentation Index
Fetch the complete documentation index at: https://docs.teesql.com/llms.txt
Use this file to discover all available pages before exploring further.
Why verify
The server’s RA-TLS certificate is self-signed and carries a TDX quote in a custom extension. A client that trusts the chain like a normal TLS endpoint trusts no one in particular — it just sees a cert that doesn’t chain to a public CA. Verification means extracting the quote, checking it against Intel’s signing chain, and confirming the measurements match what you expect. Only then is the connection meaningfully attested. Two failure modes that verification catches and standard TLS does not:- The CVM image was rotated to one you have not approved (caught by
allowedMrTdpinning) - The CVM is running with TDX debug attributes set, which means the host can inspect its memory (caught by the debug-mode check)
Prerequisites
- A TeeSQL cluster host and an Intel Trust Authority API key (or use a client library with local DCAP)
- One of the RA-TLS client libraries:
prisma-ra-tls,psycopg-ra-tls,sqlx-ra-tls, or the verifier-only packagera-tls-verifyfor Python - The expected MRTD value(s) for your cluster’s CVM image
Methods
There are three places verification can happen, all using the same primitives.Method 1 — verify atomically during connect (recommended)
The RA-TLS client libraries fold extraction and verification into the connection path. This is the default and the recommended pattern: every new connection re-checks the quote (with caching), and a verification failure surfaces as a connection error before any SQL runs.Method 2 — verify standalone with SDK primitives
For pre-flight checks, monitoring, or any path that wants to verify without opening a database connection, the same libraries expose the underlying primitives directly.extract_tdx_quote and TypeScript extractTdxQuote are the same primitive: they walk the X.509 extensions looking for OID 1.3.6.1.4.1.62397.1.8 (the current SCALE-encoded attestation), with a fallback to OID 1.3.6.1.4.1.62397.1.1 (legacy raw quote), and return the raw quote bytes (or null for a non-RA-TLS cert).
Method 3 — manual inspection via /attestation
The sidecar exposes a JSON attestation report at GET /attestation on port 8080. Useful for dashboards, ad-hoc operator checks, or any monitoring tool that just wants the report without verifying the quote itself.
tcb_info (MRTD plus RTMR0–3), postgres_state (current WAL LSN, pg_controldata hash, server version), app_id, compose_hash, and a unix timestamp. To turn this into a trust decision, feed the quote field into a verifier:
/attestation endpoint binds REPORTDATA = SHA-256(wal_lsn || controldata_hash || timestamp), so the quote also commits to the database’s live state at the moment the report was produced — useful when you want to cryptographically pin “what was Postgres doing when you said this.”
Verify-before-connect pattern
For most applications, Method 1 is what you want — the connection path verifies on every handshake, with a 1-hour cache, so there’s no separate “verify” step to forget. Use the explicit verify-before-connect form only when you need to abort early in a code path before any database work is set up:What to do when verification fails
The client libraries treat any verification failure as a hard refusal: no bytes are forwarded to the underlying Postgres driver, the connection error surfaces upward, and the transient verification cache is not populated. The same set of failure modes appears across all three libraries:| Failure | What it means | Action |
|---|---|---|
| Quote extension missing | Server is not a TeeSQL RA-TLS endpoint, or you hit the simulator without allowSimulator | Confirm host and port; for dev set allowSimulator: true |
| Intel Trust Authority returned non-2xx | API key invalid, network filtering, or transient ITA outage | Check INTEL_TRUST_AUTHORITY_API_KEY, retry, or switch to local DCAP |
tdx_is_debuggable: true | The CVM was launched with TDX debug attributes — no confidentiality | Operator must redeploy without debug; never set allowDebugMode: true in production |
| TCB status not acceptable | Platform firmware/microcode is out of date | Escalate to the cluster operator; do not bypass |
MRTD not in allowedMrTd | The CVM image is not the one you approved | Verify the operator’s release notes; if intentional, update your allowlist |
Where to get expected measurements
- MRTD is published by the cluster operator when they cut a CVM image. Pin it via
allowedMrTd(TS) /allowed_mr_td(Python) /allowed_mrtds(Rust). - RTMR0–3 are returned in every attestation result for inspection but are not pinned by default. Pin them in custom verifier code if you want to lock to a specific kernel + boot configuration.
compose_hashis exposed via/attestationand pins the application layer.