Skip to content

fix(guest): write generated credentials atomically - #883

Merged
kvinwang merged 1 commit into
masterfrom
codex/fix-guest-atomic-credentials
Aug 4, 2026
Merged

kvinwang merged 1 commit into
masterfrom
codex/fix-guest-atomic-credentials

Conversation

@kvinwang

@kvinwang kvinwang commented Jul 31, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

dstack-util gen-ra-cert, gen-ca-cert and gen-app-keys truncated and rewrote their destination files in place. A crash or a full disk during the write left a partial certificate, private key, or app-keys JSON on disk that the next boot then tried to load.

Fix

Write those files with safe-write, the crate the workspace already uses for the same job in kms, gateway, dstack-attest, and dstack-util's own system setup. The payload goes to a temporary file in the target directory, is fsynced, renamed over the destination, and the parent directory is flushed afterwards. A reader only ever observes the old file or the complete new one.

Private keys and app keys go through safe_write_with_mode(.., 0o600), so the mode is applied at creation time and the secret never exists on disk with wider permissions -- not even briefly between a rename and a follow-up chmod.

The workspace safe-write pin moves from 0.1.2 to 0.2.0: safe_write_with_mode landed in 0.1.3, and 0.2.0 carries the durability and temp-file permission fixes this change depends on.

Changed paths:

  • dstack/Cargo.toml
  • dstack/Cargo.lock
  • dstack/dstack-util/src/main.rs

Scope

This PR addresses one logical guest finding. It intentionally excludes the acceptance-test infrastructure from #841 and unrelated product fixes from #840.

Dependency and merge order

This PR is based directly on master and does not require another split product PR to merge first.

Verification

  • cargo check -p dstack-util: passed.
  • cargo clippy -p dstack-util --all-targets: clean.
  • cargo fmt -p dstack-util -- --check: clean.
  • cargo check --workspace with the safe-write 0.2.0 bump: passed, no other crate needed a change.

Copilot AI review requested due to automatic review settings July 31, 2026 02:56

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

`dstack-util gen-ra-cert`, `gen-ca-cert` and `gen-app-keys` truncated and
rewrote the destination in place. A crash or a full disk mid-write left a
partial certificate, private key, or app-keys JSON on disk that the next
boot then tried to load.

Write them with `safe-write`, which the workspace already uses for the same
job in `kms`, `gateway`, `dstack-attest` and `dstack-util`'s own system
setup: the payload goes to a temporary file in the target directory, is
fsynced, renamed over the destination, and the parent directory is flushed.
A reader only ever sees the old file or the complete new one.

Private keys and app keys use `safe_write_with_mode(.., 0o600)`, so the
mode is applied at creation and the secret never exists on disk with wider
permissions, not even briefly between a rename and a follow-up chmod.

Bump the workspace `safe-write` to 0.2.0: `safe_write_with_mode` landed in
0.1.3, and 0.2.0 carries the durability and temp-file permission fixes this
change depends on.
@kvinwang
kvinwang force-pushed the codex/fix-guest-atomic-credentials branch from cfba158 to 83076e6 Compare August 4, 2026 07:49
@kvinwang
kvinwang merged commit c09a6de into master Aug 4, 2026
15 checks passed
kvinwang added a commit that referenced this pull request Aug 5, 2026
[STACKED on #883] fix(util): write TPM quotes atomically
@kvinwang
kvinwang deleted the codex/fix-guest-atomic-credentials branch August 7, 2026 13:46
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.

2 participants