Skip to content

guest-agent: fix v1 leftovers and pin the two untested v1 methods - #1118

Open
kvinwang wants to merge 1 commit into
nextfrom
fix/v1-audit-followups
Open

guest-agent: fix v1 leftovers and pin the two untested v1 methods#1118
kvinwang wants to merge 1 commit into
nextfrom
fix/v1-audit-followups

Conversation

@kvinwang

Copy link
Copy Markdown
Collaborator

Follow-up to #1116. A post-merge audit of the whole v1 surface — agent, proto, spec, and the four SDKs — turned up five more comments of the species that PR was already cleaning up, three documentation gaps, and two of the six v1 methods with no handler-level test. This is the agent/proto/spec half; the SDK half is a separate PR.

Comments naming things that do not exist

GetAttestationForAppKey's doc still credited "the v1 method" with sharing its report data, and the test pinning its vectors still said WorkerV1 wraps those bytes in an attestation. v1 ships neither: there is deliberately no v1 AttestAppKey, as agent_rpc_v1.proto and the spec both say at length two paragraphs earlier.

Four more places wrote WorkerV1 as a service name. The service is Worker in package dstack.guest.v1 — the proto is explicit that the names carry no version suffix, and the spec says to write "the v1 Worker". The Rust import aliases WorkerV1Client/WorkerV1Server are untouched: those disambiguate two same-named generated types in one scope, which is the reason they exist.

AttestGpu's proto comment contrasted itself against GpuInfo, a method that exists on no surface — it was removed from the unversioned surface as a never-released addition, and rpc_service_v1.rs asserts it is absent from both. The real contrast is Attest's boottime_gpu_evidence, which is the thing that returns a record written at boot.

Documentation gaps

The spec pointed at rpc_service_v1/keys.rs for the private-key vectors and for a_v0_claim_cannot_be_crafted_into_a_v1_claim. Both live in ra-tls/src/api_v1.rs; keys.rs pins only the public-key column and says so itself. A reader following either pointer to check the normative bytes landed where they are not.

The Errors table omitted the two validations AttestGpu actually performs (nonce length, and nvattest being absent from the image), while listing the other four.

Health's fail-open for an app that never opted into gating — healthy: true meaning "nobody asked me to know", not "checked and fine" — was pinned only by a test, and appeared in none of the three documents that describe the method. It is now in the proto comment, the spec, and app-health-checks.md, each saying what a non-gateway caller should read that true as.

Tests

IssueCert and AttestGpu were the two v1 methods with no handler-level coverage, so nothing would have noticed the v1 handlers ceasing to route through the shared validity check or through the attestor. Both are now asserted through the handler rather than against the helper in isolation, and the on-demand GPU format tag is pinned like its boot-time counterpart already was — a consumer selects its verifier on (vendor, format), so both tags are wire contract.

The AttestGpu test formats the error with {:#} deliberately: the handler adds a context line, and ra_rpc encodes errors as format!("{error:#}"), so asserting on the flat to_string() would test something no client ever sees.

Verification

  • cargo test -p dstack-guest-agent --all-features: 118 passed (3 new).
  • dstack-gateway: 289 passed. frozen_surface: 2 passed — the frozen descriptor digest is unmoved, as a comment-only proto edit requires.
  • cargo fmt --all --check and cargo clippy -D warnings (per CLAUDE.md) clean.

A post-merge audit of the v1 surface turned up five more comments in the
species #1116 was already cleaning up, three documentation gaps, and two of
the six v1 methods with no handler-level test.

Comments naming things that do not exist: `GetAttestationForAppKey`'s doc
still credited "the v1 method" with sharing its report data, and its vector
test still said `WorkerV1` wraps those bytes in an attestation -- v1 ships
neither. Four more spots wrote `WorkerV1` as a service name; the service is
`Worker` in package `dstack.guest.v1`, and the proto says so explicitly.
`AttestGpu`'s proto comment contrasted itself against `GpuInfo`, a method
that exists on no surface: the real contrast is `Attest`'s
`boottime_gpu_evidence`, which is the thing that returns a boot record.

Documentation gaps: the spec pointed at `rpc_service_v1/keys.rs` for the
private-key vectors and the v0-forgery regression test, both of which live
in `ra-tls/src/api_v1.rs` -- a reader checking the normative bytes landed
where they are not. The Errors table omitted the two validations `AttestGpu`
performs. And the `Health` fail-open for an app that never opted into
gating -- `healthy: true` meaning "nobody asked me to know" -- was pinned
only by a test, in none of the three documents that describe the method.

Tests: `IssueCert` and `AttestGpu` had no handler-level coverage, so nothing
would have noticed the v1 handlers ceasing to route through the shared
validity check or the attestor. Both are now asserted through the handler,
and the on-demand GPU format tag is pinned like its boot-time counterpart.
Copilot AI lite review requested due to automatic review settings August 24, 2026 16:00

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.

Comment thread dstack/guest-agent/src/rpc_service_v1.rs Dismissed
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.

3 participants