Skip to content

docs(tdx): warn that changing app-compose breaks the sealed disk - #3745

Merged
barakeinav1 merged 6 commits into
mainfrom
barak/3742-tdx-app-compose-warning
Jul 13, 2026
Merged

docs(tdx): warn that changing app-compose breaks the sealed disk#3745
barakeinav1 merged 6 commits into
mainfrom
barak/3742-tdx-app-compose-warning

Conversation

@barakeinav1

Copy link
Copy Markdown
Contributor

Summary

Closes #3742.

Adds a warning + recovery recipe to the TDX external guide after a testnet
incident where an operator (stakin-mpc2.testnet, node 13) added a pre-launch
script via the dstack UI to inspect data, restarted, and bricked the CVM:
Failed to open encrypted data disk / No key available with this passphrase.

Why it happened: with the local-sgx key provider the LUKS disk key is
derived from MRTD + RTMR0..RTMR3. The app-compose (launcher compose,
pre-launch/init scripts, toggles) is hashed into RTMR3 as compose_hash, so
any change re-derives a different key and the existing encrypted disk can no
longer be unsealed. Clearing the script again via the UI didn't help: the UI
re-serializes app-compose.json and dropped the trailing newline inside the
embedded docker_compose_file string, which survives dstack's normalized
hashing and changes compose_hash. Recovery was to regenerate a
byte-hash-identical app-compose via deploy-launcher.sh and push it with
update-app-compose.

Changes

  • docs/running-an-mpc-node-in-tdx-external-guide.md:
    • Item 3 (Pre-launch/Init Script) now notes the scripts are measured and that a non-empty script also changes the disk-sealing key.
    • New ⚠️ callout in the web-interface section: why app-compose changes destroy keyshares, the UI re-serialization footgun, that memory/vCPU changes are equally destructive, and a step-by-step recovery (regenerate → verify sha256sumupdate-app-compose → restart; else fresh CVM + reshare). Cross-references Launcher / CVM Upgrade.

Notes

Docs-only. Opened as draft for review of the mechanism wording (esp. the
normalized-hash detail) before merge.

Changing a running node's app-compose (scripts, UI edits, or memory/vCPU)
alters the boot measurements the local-sgx key provider derives the disk
key from, making the encrypted keyshare disk unrecoverable. Document why,
call out the UI re-serialization footgun, and give the regenerate-and-
update-app-compose recovery recipe.

Refs #3742
@barakeinav1
barakeinav1 marked this pull request as ready for review July 9, 2026 09:45
Copilot AI review requested due to automatic review settings July 9, 2026 09:45
@claude

claude Bot commented Jul 9, 2026

Copy link
Copy Markdown

Pull request overview

Documentation-only change that adds a warning against modifying the app-compose of a running TDX node (which would rederive the LUKS disk key and prevent the node from starting), plus a Troubleshooting recipe to recover a bricked CVM by regenerating a byte-hash-identical app-compose. Motivated by the testnet incident on node 13 (stakin-mpc2.testnet).

Changes:

  • Expands item 3 of the web-UI deployment checklist to explain that pre-launch/init scripts are measured and change the disk-sealing key.
  • Adds a callout under the web-UI screenshots warning against app-compose changes and linking to the new troubleshooting section.
  • Adds a new Troubleshooting section Node won't start after an app-compose change with symptom, mechanism, and step-by-step recovery.

Reviewed changes

Per-file summary
File Description
docs/running-an-mpc-node-in-tdx-external-guide.md Adds warning + recovery procedure for app-compose changes that break the sealed data disk.

Findings

Blocking (must fix before merge):

  • None.

Non-blocking (nits, follow-ups, suggestions):

  • docs/running-an-mpc-node-in-tdx-external-guide.md:1908-1909 — The command block is inconsistent with the CLI conventions established a few lines above at L1855-1872. The rest of the doc uses `python $VMM_CLI_PATH --url $VMM_URL `, but the new snippet uses `vmm-cli.py --url $VMM_RPC <vm_id>`. Specifically: (a) `$VMM_RPC` is never defined anywhere in the doc — the shell variable is `$VMM_URL`; (b) `vmm-cli.py` is invoked without the `python $VMM_CLI_PATH` prefix; (c) placeholders switch from `` (hyphen) to `<vm_id>` (underscore). Suggest:
    ```bash
    python $VMM_CLI_PATH --url $VMM_URL update-app-compose .app-compose.json
    python $VMM_CLI_PATH --url $VMM_URL stop && python $VMM_CLI_PATH --url $VMM_URL start
    ```
  • docs/running-an-mpc-node-in-tdx-external-guide.md:918 — The PR description states the callout "Cross-references Launcher / CVM Upgrade", but the rendered callout only links to the troubleshooting anchor. If the intent was to also point at §Launcher / CVM Upgrade (L1657), consider adding that link explicitly, since that section describes the sanctioned upgrade flow that avoids this failure mode.
  • docs/running-an-mpc-node-in-tdx-external-guide.md:1903-1904 — "the 32 bytes after the leading `01` in a pre-incident boot log's `mr_config_id`" is dense for an operator under duress. It would help to either (a) show an example `mr_config_id` value with the `01` prefix and hash split out, or (b) point to where in the logs / which command surfaces `mr_config_id`. Consider also naming the log source (dstack CVM boot log? `journalctl` inside the guest? attestation quote?).
  • docs/running-an-mpc-node-in-tdx-external-guide.md:1900-1902 — Recovery step 1 assumes the operator still has (or can reconstruct) the original inputs to `deploy-launcher.sh` — same launcher image, same `.env`, same template revision. Worth calling out explicitly: if any of those inputs drifted (e.g. `deploy-launcher.sh` or its template changed on `main`), the regenerated `app-compose.json` won't be byte-identical either and step 2 will fail. Pinning to the git SHA that produced the original deploy is the safe recipe.
  • docs/running-an-mpc-node-in-tdx-external-guide.md:918 — Blockquote-with-emoji callouts are used elsewhere in the doc, so style is consistent; but this callout would be more discoverable if placed above the web-UI screenshots (L914-916) rather than after, since operators typically scan the screenshots and skip to the next `####` heading. Minor.

✅ Approved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the TDX external operator guide to clearly warn that modifying a CVM’s app-compose (including scripts/toggles and UI edits) changes measured boot inputs used to derive the sealed disk key under the local key provider, which can brick an existing encrypted data disk. It adds a prominent warning and a troubleshooting/recovery recipe based on a recent testnet incident.

Changes:

  • Expands the “Pre-launch / Init Script” guidance to note scripts are measured and affect the disk-sealing key (not just attestation success).
  • Adds a prominent ⚠️ callout warning operators not to change app-compose on a running node and pointing to recovery steps.
  • Adds a new troubleshooting section explaining symptoms, why it happens, and how to recover by restoring byte-identical measurements and re-applying app-compose.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


![VMM Web Page (2/2)](./attachments/VMM_web_page_deploy_2.png)

> **⚠️ Never change the app-compose of a running node** — the node will not be able to start, since the disk is encrypted with a key derived from the app-compose measurement. If this happens, see [Troubleshooting: node won't start after an app-compose change](#node-wont-start-after-an-app-compose-change) to recover.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in c8c5af6 — the callout now reads "Never change the app-compose (or the vCPU/memory) of a running node … a key derived from those measured inputs," so it no longer reads as app-compose-only.

Comment thread docs/running-an-mpc-node-in-tdx-external-guide.md
anodar
anodar previously approved these changes Jul 9, 2026
…t; fix recovery commands to guide's $VMM_CLI_PATH/$VMM_URL/<vm-id> convention
@barakeinav1
barakeinav1 added this pull request to the merge queue Jul 13, 2026
Merged via the queue into main with commit e9f3eb7 Jul 13, 2026
15 checks passed
@barakeinav1
barakeinav1 deleted the barak/3742-tdx-app-compose-warning branch July 13, 2026 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(tdx): warn that editing app-compose (scripts / UI re-serialization) breaks the sealed disk

4 participants