diff --git a/docs/aws-attested-instance-security-evaluation.md b/docs/aws-attested-instance-security-evaluation.md index 1b118f56d..42703390b 100644 --- a/docs/aws-attested-instance-security-evaluation.md +++ b/docs/aws-attested-instance-security-evaluation.md @@ -38,7 +38,7 @@ NitroTPM path meets them today. | P4 | Runtime application identity is cryptographically bound | RTMR3 `compose-hash`, `app-id`, `instance-id`, `key-provider`; event log replay | SHA384 `PCR14` event-log replay is the authoritative binding (RTMR3 analogue; non-resettable). Launch events: `system-preparing`, `app-id`, `compose-hash`, zero or more ordered `init-script-hash` events, `instance-id`, `boot-mr-done`, `key-provider`, `storage-fs`, `storage-encrypted`, `system-ready` (`dstack/dstack-util/src/system_setup.rs`). GPU launches also include `gpu-policy-hash` before `instance-id`, and `gpu-attestation` after `boot-mr-done` and before `key-provider`. `dstack-attest`, `dstack-verifier`, and KMS reject missing/mismatched PCR14 and bad replay. Optionally, the guest extends the raw `MrConfig` V2 `config_id` into `PCR8` once (`PCR8 = sha384(0^48 || config_id)`) so a lightweight third-party verifier can check compose hash + key provider without event-log replay; dstack's own verifier and KMS do not check PCR8. | | P5 | Challenge/liveness and caller key binding | `report_data` challenge or RA-TLS public key hash in quote | RA-TLS binds `report_data` to the TLS certificate public key. KMS key release is bound to the live RA-TLS handshake; external `/verify` callers supply and check their own `report_data` challenge. The low-level NitroTPM document verifier also rejects stale or far-future document timestamps. | | P6 | Secret release only to attested code | dstack KMS verifies attestation, checks auth policy, derives per-app keys | dstack KMS verifies the NitroTPM attestation, runs the same `verify_os_image_hash_for_aws_nitro_tpm` binding check as the verifier, builds `BootInfo` from verified boot PCRs plus PCR14 launch events, and checks auth policy before deriving app keys (`dstack/kms/src/main_service.rs`). AWS NitroTPM key release is gated behind the opt-in `aws_nitro_tpm_key_release` flag (default false in `kms.toml`). | -| P7 | Key-release policy is not controlled by the untrusted account admin | KMS runs inside TEE; policy from auth API/contracts; KMS identity measured | Satisfied with dstack KMS or another verifiable secret authority outside the untrusted AWS account admin's control. A NitroTPM-backed dstack KMS keeps root material out of account-admin snapshots and clones. The policy backend (dstack-auth in a trusted control plane, or on-chain `DstackKms`/`DstackApp`) must be outside the workload account admin's control. Same-account AWS KMS fails this property if the admin can change key policy, create grants, or call secret-bearing operations through a policy they control. | +| P7 | Key-release policy is not controlled by the untrusted account admin | KMS runs inside TEE; policy from auth API/contracts; KMS identity measured | Satisfied with dstack KMS or another verifiable secret authority outside the untrusted AWS account admin's control. A NitroTPM-backed dstack KMS keeps root material out of account-admin snapshots and clones. The policy backend (on-chain `DstackKms`/`DstackApp` or an equivalent service; dstack-auth is for development, testing and evaluation only) must be outside the workload account admin's control. Same-account AWS KMS fails this property if the admin can change key policy, create grants, or call secret-bearing operations through a policy they control. | | P8 | Operator cannot inject boot-time or runtime inputs that affect secrets without detection | Host-shared files are measured or independently authenticated; KMS URLs not trusted, KMS key identity measured | App TPM access is enforced by measurement, not by a container sandbox: `init_script`, `pre_launch_script`, and the docker-compose are measured into the app-compose hash, hence into the governed app identity, and replayed into non-resettable `PCR14`, so an operator cannot alter app inputs without changing the measured identity and being denied key release. Production dstack-os AWS images exclude SSH, cloud-init, SSM, EC2 Instance Connect, and serial login (checked by `audit-aws-ec2-image-hardening.sh`). IMDS/operator-provided config must not be a secret-affecting input unless measured or authenticated. | | P9 | Persistent state confidentiality from account admin | dstack disk key derived after attestation; encrypted env vars decrypted only inside CVM | The local TPM key provider seals the disk seed under a SHA384 PCR policy over `[4, 7, 8, 12, 14]` (`AWS_NITRO_PCRS` in `dstack/tpm-attest/src/lib.rs`), so the sealed seed survives same-instance stop/start but does not transfer with cloned EBS volumes to another instance. EBS snapshots and volumes remain account-admin visible at the AWS control plane, so persisted confidential state must stay encrypted inside the instance and AMIs must contain no secrets. | | P10 | Network and TLS endpoint identity is attestation-bound | RA-TLS / Zero Trust HTTPS / gateway attestation; TLS keys generated in TEE | The Rust RA-TLS verifier exposes `verify_der`/`verify_pem`, which extract the certificate's embedded attestation, verify it with the platform verifier (including AWS NitroTPM), and require `report_data = QuoteContentType::RaTlsCert(SubjectPublicKeyInfo)`. `dstack-verifier --verify-cert` provides an operator/relying-party certificate evidence path that also binds `os_image_hash`. AWS attestation alone does not protect DNS, load balancers, or admin-controlled proxies; clients must require this RA-TLS check, signed responses, or an attested gateway. | diff --git a/docs/aws-ec2-production-verifier-runbook.md b/docs/aws-ec2-production-verifier-runbook.md index ff68cb4ba..de64f1481 100644 --- a/docs/aws-ec2-production-verifier-runbook.md +++ b/docs/aws-ec2-production-verifier-runbook.md @@ -18,8 +18,9 @@ and endpoint identity. - The dstack monorepo sources pinned at the exact release revision, for the reproducible rebuild. - A dstack verifier built from this repository. -- The production auth policy backend: `dstack-auth`, auth-eth contracts, or an - equivalent verifier-controlled service. +- The production auth policy backend: auth-eth contracts or an equivalent + verifier-controlled service. `dstack-auth` is for development, testing and + evaluation only. - For public services, the endpoint's RA-TLS certificate. ## 1. Verify Release Evidence @@ -209,8 +210,8 @@ For AWS NitroTPM, the policy must require: `instance-id`, `key-provider`); - a `report_data` challenge for external verifier flows that need liveness. -With `dstack-auth`, the TCB status and advisories are checked only when the -allowlist sets them, so set both explicitly: +When evaluating with `dstack-auth`, note that the TCB status and advisories are +checked only when the allowlist sets them, so set both explicitly: ```json { diff --git a/docs/deployment.md b/docs/deployment.md index 9095496dd..57758f79b 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -126,7 +126,7 @@ Production KMS requires: | Server | Use Case | Configuration | |--------|----------|---------------| -| [dstack-auth](./dstack-auth-operations.md) | Config-file-based whitelisting | JSON config file | +| [dstack-auth](./dstack-auth-operations.md) | Config-file-based whitelisting for development, testing and evaluation only | JSON config file | | [auth-eth](../dstack/kms/auth-eth/) | On-chain governance via the `DstackKms`/`DstackApp` contracts in the same directory | Ethereum RPC + contract | | Custom | Your own authorization logic | Implement webhook interface | diff --git a/docs/dstack-auth-operations.md b/docs/dstack-auth-operations.md index 54b203580..fe3d98471 100644 --- a/docs/dstack-auth-operations.md +++ b/docs/dstack-auth-operations.md @@ -2,6 +2,11 @@ > **This guide is for self-hosted deployments** on your own TDX hardware. For cloud deployments, see [Quickstart](./quickstart.md). +> [!WARNING] +> `dstack-auth` is intended for development, testing and evaluation only. Do not +> use it to protect production keys; use [auth-eth](../dstack/kms/auth-eth/) or +> an equivalent production-grade authorization service instead. + `dstack-auth` is the file-based KMS authorization webhook. It allowlists OS images, KMS instances and apps in one JSON file. For on-chain governance, use [auth-eth](../dstack/kms/auth-eth/) instead diff --git a/docs/onboarding.md b/docs/onboarding.md index 2aa0dc588..9ff9ea1b3 100644 --- a/docs/onboarding.md +++ b/docs/onboarding.md @@ -33,7 +33,7 @@ For multi-node production, Gateway TLS, custom domains, or on-chain governance, - Source and build cache under `/var/cache/dstack`. - Runtime sockets and process state under `/run/dstack`. - A localhost-only VMM dashboard on port `9080`. -- A local `dstack-auth` webhook and `dstack-vmm` systemd unit. +- A local `dstack-auth` webhook (development, testing and evaluation only) and `dstack-vmm` systemd unit. - A single KMS CVM unless you pass `--no-kms`. - A direct host port mapping for your app. diff --git a/dstack/crates/dstack-auth/src/main.rs b/dstack/crates/dstack-auth/src/main.rs index 06efdb8bb..f19e0a11c 100644 --- a/dstack/crates/dstack-auth/src/main.rs +++ b/dstack/crates/dstack-auth/src/main.rs @@ -4,6 +4,8 @@ //! `dstack-auth` — the file-based KMS auth webhook. //! +//! Intended for development, testing and evaluation only; not for production. +//! //! Runs on the host as `dstack-auth.service`; the KMS-in-CVM reaches it at //! `http://10.0.2.2:` under user-mode networking and POSTs `BootInfo` to //! `/authorizeApp` (compose-hash allowlist) and `/authorizeKms` (mrAggregated @@ -40,7 +42,7 @@ use std::path::PathBuf; #[command( name = "dstack-auth", version, - about = "single-operator KMS auth webhook" + about = "single-operator KMS auth webhook (development, testing and evaluation only)" )] struct Cli { /// path to the allowlist JSON (re-read on every request).