diff --git a/docs.json b/docs.json index 0f0ce716..2613ba80 100644 --- a/docs.json +++ b/docs.json @@ -264,7 +264,8 @@ "pages": [ "products/verifiable-cloud/overview", "products/verifiable-cloud/lifecycle", - "products/verifiable-cloud/onboarding" + "products/verifiable-cloud/onboarding", + "products/verifiable-cloud/proofs-and-verification" ] } ] diff --git a/products/verifiable-cloud/proofs-and-verification.mdx b/products/verifiable-cloud/proofs-and-verification.mdx new file mode 100644 index 00000000..925ef5ac --- /dev/null +++ b/products/verifiable-cloud/proofs-and-verification.mdx @@ -0,0 +1,105 @@ +--- +title: "Proofs and Verification" +--- + +Turnkey Verifiable Cloud (TVC) uses two related proofs to let a verifier answer a concrete question: did this application-level result come from the expected code running in an attested enclave? + +- A **Boot Proof** is produced by the TVC platform. It answers: what enclave booted, and what code and configuration was it approved to run? +- An **App Proof** is produced by application logic. It answers: what application-level output did that enclave sign? + +The trust chain starts with AWS. The AWS Nitro Secure Module (NSM) signs an attestation document with a certificate chain rooted in the [AWS root certificate](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html); that document binds an enclave's **Ephemeral Key** to PCR measurements and Turnkey's [QOS](https://github.com/tkhq/qos) manifest digest. The QOS manifest then identifies the application binary and deployment configuration. Finally, an App Proof signature links an application-level payload back to the same Ephemeral Key. + +This page is written for TVC builders who want to design and verify their own App Proofs. It also uses Turnkey's own App Proofs as examples throughout. For the customer-facing dashboard and Embedded Wallet Kit feature built on Turnkey's proofs, see [Turnkey Verified](https://docs.turnkey.com/security/turnkey-verified). + +## Boot Proof + +A Boot Proof is a bundle of artifacts that a verifier can use to establish what code an enclave is running. It contains: + +- The **[AWS Nitro attestation document](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html#the-attestation-document)** (DER-encoded COSE Sign1), which contains PCR measurements, the AWS certificate chain, the enclave's Ephemeral public key (in the `public_key` field), and arbitrary `user_data`. +- The **QOS manifest** and **manifest envelope**, which describe the application binary and arguments, the operator quorum, the quorum public key, and other deployment configuration. The AWS attestation document's `user_data` is set by QOS to the digest of this manifest, which is what binds the two together. +- Operator **approvals** of the manifest. + +AWS PKI is the root of the cryptographic trust chain. A verifier checks that the attestation document and its certificate chain validate back to the AWS root certificate, then checks the Turnkey-specific fields and manifest binding. AWS documents the attestation document validation step in its [root of trust verification](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html) documentation. + +Boot Proofs are operating system level artifacts from enclave boot. Turnkey records the Boot Proof for every enclave that boots, both internally and for TVC, and makes the relevant proofs available through Turnkey's public API. See [Fetching proofs as a verifier](#fetching-proofs-as-a-verifier). + +## App Proof + +App Proofs are generated by enclave application logic. What makes an App Proof an App Proof is that application-level output is signed with an enclave's Ephemeral Key, so that output can be linked back to the Boot Proof Turnkey stores. + +As a TVC builder, you decide what your App Proof payload needs to prove. For example, your application might sign a model inference result, a private computation outcome, or a protocol-specific state transition. The important design requirement is that the payload commits to the facts a verifier will care about, and that the signature uses the enclave Ephemeral Key so the verifier can connect the payload to a valid Boot Proof. + +Turnkey's own products use a standardized App Proof envelope. You can use this structure as a reference design, but custom TVC applications can structure their payloads differently. + +A Turnkey App Proof contains: + +- A **proof payload** (JSON), which has a typed schema per proof type. Examples today include `APP_PROOF_TYPE_ADDRESS_DERIVATION` (a wallet address was derived from a specific path on a specific wallet) and `APP_PROOF_TYPE_POLICY_OUTCOME` (a policy decision evaluated to a specific outcome against specific organization data). +- A **signature** over the SHA-256 digest of the JSON payload bytes, produced by the enclave's Ephemeral Key (P-256). +- The **Ephemeral public key** that produced the signature. +- The **signature scheme** identifier (currently `SIGNATURE_SCHEME_EPHEMERAL_KEY_P256`). + +The Ephemeral private key never leaves the enclave by design; only the public half is exposed through the attestation document's `public_key` field and the App Proof's `publicKey` field. + +The App Proof embeds the Ephemeral public key it was signed with. The Boot Proof's attestation document also pins that same Ephemeral public key (in `public_key`). A verifier links the two by matching the App Proof's public key to a valid Boot Proof's attested key; see [Verification flow](#verification-flow) below. + +For example, Turnkey's address derivation App Proof signs a payload committing to a specific organization, wallet, derivation path, and derived address: + +```json +{ + "scheme": "SIGNATURE_SCHEME_EPHEMERAL_KEY_P256", + "publicKey": "ephemeral-public-key-from-the-enclave", + "proofPayload": "{\"type\":\"APP_PROOF_TYPE_ADDRESS_DERIVATION\",\"timestampMs\":\"1758909116\",\"addressDerivationProof\":{\"organizationId\":\"your-organization-id\",\"walletId\":\"your-wallet-id\",\"derivationPath\":\"m/44'/60'/0'/0/0\",\"address\":\"0x61f4Ec0630DD50F1393cbDB60e5ccA1ed98f5100\"}}", + "signature": "p256-sha256-signature-over-proofPayload" +} +``` + +On its own, this payload does not prove that a particular enclave signed it; but when a verifier can match `publicKey` to a valid Boot Proof, the claim is tied back to an enclave instance and the code identified by its manifest. Your own TVC App Proofs follow the same chain even if the payload schema is specific to your application. + +## Why the Ephemeral Key and not the Quorum Key + +QuorumOS enclaves already have a Quorum Key, which is the long-lived key associated with the application's identity. Why don't Turnkey App Proofs use that? + +The answer is a trust boundary distinction. + +The quorum key is designed to live across many different versions of an enclave app and can not be provably exclusive to a specific enclave instance, app binary, or configuration. The Quorum Key is provisioned via the [QuorumOS quorum provisioning protocol](https://github.com/tkhq/qos/blob/main/docs/boot_standard.md): share holders verify a node's attestation document, encrypt quorum key shares to the node's Ephemeral Key, and the node reconstructs the Quorum Key once the configured threshold is met. Because the Quorum Key can be provisioned into any enclave that satisfies the provisioning protocol, a Quorum Key signature cannot cryptographically prove the app proof payload came from the _inside_ of a _specific_ enclave. + +The Ephemeral Key can be cryptographically proven to be generated inside the enclave at boot and never exist outside of the enclave. The Nitro attestation document signs over the QOS measurement (`PCR0`/`PCR1`/`PCR2`), the AWS account/role measurement (`PCR3`), the QOS manifest digest (`user_data`), and the Ephemeral public key (`public_key`) all in a single signed document produced by the NSM. That binding is what gives the Ephemeral Key its property: it is unique to this specific enclave instance running this specific code. No quorum provisioning flow can recreate that Ephemeral private key elsewhere. + +Because that Ephemeral Key only exists inside that specific enclave running that specific code, anything signed by that Ephemeral Key must have been produced by that enclave and therefore by that exact code. An App Proof signature is, transitively, proof of what code generated the output. + +## Verification flow + +To verify a response that comes with an App Proof, a verifier needs both the App Proof and the linked Boot Proof. For Turnkey's App Proof envelope, the open-source verifiers follow this order: + +1. **Verify the App Proof signature.** Check the signature scheme, extract the P-256 signing key from the App Proof public key, hash the JSON `proofPayload` with SHA-256, and verify the ECDSA signature. +2. **Verify the Boot Proof.** Parse and verify the AWS Nitro attestation document, including the AWS Nitro certificate chain. Then hash the QOS manifest and confirm it matches the attestation document's `user_data` field. +3. **Verify that the Ephemeral public keys match.** The App Proof `publicKey`, the Boot Proof `ephemeralPublicKeyHex`, and the attestation document `public_key` must all be the same key. +4. **Interpret the verified payload.** Once the proof pair verifies, parse the typed payload and evaluate the claim it makes. For Turnkey's `addressDerivationProof`, for example, the payload commits to a specific organization, wallet, derivation path, and address. For your own TVC application, this is where your verifier applies your application-specific schema and semantics. +5. **Check code identity for full independent verification.** To independently establish the exact code that produced the result, inspect the QOS manifest and verify the application binary digest and PCR values against the known-good values you trust, such as values published in [`tkhq/core-enclaves`](https://github.com/tkhq/core-enclaves). + +If these checks pass, the App Proof's payload is tied to an AWS-attested Nitro Enclave, to the QOS manifest bound into that attestation, and to the Ephemeral Key that signed the application-level claim. + +For custom App Proofs, the Boot Proof verification and Ephemeral Key matching are the same. What changes is the application-level payload: you define the schema, what fields are signed, and what a verifier should conclude from those fields. + +## Fetching proofs as a verifier + +An App Proof usually arrives as part of an enclave response. The Boot Proof is fetched separately, keyed by the Ephemeral public key embedded in the App Proof. + +Turnkey exposes public endpoints for this: + +- [`get_boot_proof`](https://docs.turnkey.com/api-reference/queries/get-a-specific-boot-proof) — fetch the Boot Proof for a specific Ephemeral public key. This is what a verifier will use after extracting the Ephemeral key from an App Proof. +- [`get_latest_boot_proof`](https://docs.turnkey.com/api-reference/queries/get-the-latest-boot-proof-for-an-app) — fetch the most recent Boot Proof for a given enclave application name. Useful for sanity-checking what's currently deployed. +- [`list_app_proofs_for_an_activity`](https://docs.turnkey.com/api-reference/queries/list-app-proofs-for-an-activity) — fetch Turnkey App Proofs associated with an activity. + +Open-source tooling is available in: + +- [Rust](https://github.com/tkhq/rust-sdk/tree/main/proofs) +- [TypeScript](https://github.com/tkhq/sdk/tree/main/packages/crypto/src/proof.ts) +- [Go](https://github.com/tkhq/go-sdk/tree/main/pkg/proofs) + +## See also + +- [Turnkey Verified](https://docs.turnkey.com/security/turnkey-verified) — the user-facing feature built on these proofs, including supported App Proof types and example payloads. +- [Deployment Lifecycle](https://docs.turnkey.com//products/verifiable-cloud/lifecycle) — how an enclave gets from a container image to a running, attested instance. +- [AWS Nitro Enclaves: Verifying the root of trust](https://docs.aws.amazon.com/enclaves/latest/user/verify-root.html). +- [Whitepaper: Boot Proofs and App Proofs](https://whitepaper.turnkey.com/foundations#boot-proofs-and-app-proofs). diff --git a/security/turnkey-verified.mdx b/security/turnkey-verified.mdx index 57064277..bf8ab85a 100644 --- a/security/turnkey-verified.mdx +++ b/security/turnkey-verified.mdx @@ -8,6 +8,8 @@ As outlined in our [Whitepaper](https://whitepaper.turnkey.com/foundations#boot- For the first time we're exposing proofs produced by our TEEs to the outside world. Turnkey's infrastructure produces two types of proofs: **Boot Proofs** and **App Proofs**. +For a deeper architectural walkthrough — including why App Proofs are signed by the enclave's Ephemeral Key rather than the Quorum Key, and the end-to-end verification flow — see [TVC: Proofs and Verification](/products/verifiable-cloud/proofs-and-verification). + ### Boot Proofs A Boot Proof is a proof that a particular AWS Nitro Enclave has booted with a particular configuration. A Boot Proof contains: