Skip to content

Commit 213a577

Browse files
committed
test(test-utils): address review on the regenerated fixtures
- strip the NUL that terminates the PEM chains in the node's collateral, so the fixture stays valid PEM for consumers stricter than dcap-qvl, and regenerate the borsh arg fixture - stop asserting the borsh fixture's final byte in .editorconfig: it is whatever the encoded collateral ends with - give the secret key file a trailing newline, and confirm in the runbook that its account exists on no public network - warn loudly when a pre-launch script is baked in, and document in the deploy guide and default.env that such a CVM cannot pass attestation - state the DCAP verdict of the localnet verify_quote call without depending on today's date, in both runbooks and the sandbox module doc - make the regeneration reminder unconditional (the committed key is normally present but stale), document the borsh/report-value refresh step, and drop the vestigial --run-ignored - assert the compiled-in pre-launch policy through validate_app_compose_config, not only through the helper, and rename the new tests to the should_ form
1 parent f711dcf commit 213a577

14 files changed

Lines changed: 95 additions & 36 deletions

File tree

.editorconfig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ insert_final_newline = false
2929
# localnet verify_quote call; the text rules do not apply.
3030
[crates/tee-verifier/tests/fixtures/*.borsh]
3131
end_of_line = unset
32-
insert_final_newline = false
32+
# `unset`, not `false`: the last byte is whatever the encoded collateral ends
33+
# with, so asserting either way breaks on the next fixture regeneration.
34+
insert_final_newline = unset
3335
trim_trailing_whitespace = false
3436
charset = unset

crates/attestation/src/attestation.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ mod tests {
628628
}
629629

630630
#[test]
631-
fn scripts_absent_with__rejects_pre_launch_script_when_disallowed() {
631+
fn scripts_absent_with__should_reject_pre_launch_script_when_disallowed() {
632632
// Asserts the production policy, which test builds relax for the fixture.
633633

634634
// Given
@@ -644,7 +644,25 @@ mod tests {
644644
}
645645

646646
#[test]
647-
fn scripts_absent_with__accepts_pre_launch_script_when_allowed() {
647+
fn validate_app_compose_config__should_follow_the_compiled_in_pre_launch_policy() {
648+
// Covers the wired-in policy at the call site, which the tests below reach
649+
// only through the helper.
650+
651+
// Given
652+
let app_compose = AppCompose {
653+
pre_launch_script: Some("echo collecting fixtures".to_string()),
654+
..valid_app_compose()
655+
};
656+
657+
// When
658+
let result = DstackAttestation::validate_app_compose_config(&app_compose);
659+
660+
// Then
661+
assert_eq!(result, cfg!(feature = "allow-pre-launch-script"));
662+
}
663+
664+
#[test]
665+
fn scripts_absent_with__should_accept_pre_launch_script_when_allowed() {
648666
// Given
649667
let app_compose = AppCompose {
650668
pre_launch_script: Some("echo collecting fixtures".to_string()),
@@ -658,7 +676,7 @@ mod tests {
658676
}
659677

660678
#[test]
661-
fn scripts_absent_with__rejects_other_scripts_even_when_pre_launch_is_allowed() {
679+
fn scripts_absent_with__should_reject_other_scripts_when_pre_launch_is_allowed() {
662680
// The relaxation must stay scoped to `pre_launch_script`.
663681

664682
// Given

crates/contract/tests/sandbox/tee_verifier.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,10 @@ async fn submit_participant_info__should_run_dcap_within_verifier_gas_budget() {
361361
let result = submit_dstack(&submitter, &contract).await;
362362

363363
// Then: the real DCAP run succeeds within the production gas budget and its
364-
// Verified verdict reaches the callback. The submission then fails at the
365-
// post-DCAP report_data binding, because the submitter does not hold the
366-
// fixture account key (see #3787); that terminal error is asserted to pin
367-
// that the verdict was Verified, not Rejected.
364+
// Verified verdict reaches the callback. This test deliberately submits from
365+
// a plain dev account rather than the fixture node, so it then fails at the
366+
// post-DCAP report_data binding; asserting that terminal error pins that the
367+
// verdict was Verified, not Rejected.
368368
let outcomes = result.outcomes();
369369
let verify_quote_outcome = outcomes
370370
.iter()
-1 Bytes
Binary file not shown.

crates/test-utils/assets/README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ All files will be written into the specified output directory.
5757
exported during collection, which is what the `PRELAUNCH_SCRIPT` in
5858
[the rust-launcher README](../../../localnet/tee/scripts/rust-launcher/README.md#exporting-the-nodes-signer-key)
5959
is for. The fixture node is a throwaway localnet node, which is the only reason its
60-
secret key may live in the repo.
60+
secret key may live in the repo: its account (`frodo.test.near`) exists on no
61+
public network, and the quote and collateral that bind the key are public anyway.
62+
Re-check that before committing a regenerated key.
6163

6264
Because of that export hook, the fixture's app-compose carries a
6365
`pre_launch_script`, which production verification rejects as arbitrary root code.
@@ -87,6 +89,19 @@ All files will be written into the specified output directory.
8789
> will be managed entirely through on-chain voting (`vote_add_os_measurement`), and these
8890
> files will no longer need to be kept in sync with the deployed OS image.
8991
92+
8. Regenerate the verifier's borsh argument fixture and refresh the report values
93+
the verifier test hardcodes (`mr_config_id`, `rt_mr3`, `report_data` change with
94+
every new node):
95+
96+
```shell
97+
UPDATE_FIXTURES=1 cargo test -p tee-verifier --test verify_quote verify_quote_args_fixture
98+
cargo test -p tee-verifier --test verify_quote
99+
```
100+
101+
The second run fails on `verify_quote__should_return_verified_td10_report_for_valid_fixture`
102+
and prints the values actually produced; copy them into
103+
`crates/tee-verifier/tests/verify_quote.rs`.
104+
90105
## Tests that depend on these assets
91106

92107
After updating assets, these tests should pass:
@@ -104,5 +119,5 @@ also depend on these assets (including `near_account_secret_key` for the tests t
104119
sign as the fixture account):
105120

106121
```shell
107-
cargo nextest run --cargo-profile=test-release -p mpc-contract tee_verifier --run-ignored all
122+
cargo nextest run --cargo-profile=test-release -p mpc-contract tee_verifier
108123
```

crates/test-utils/assets/collateral.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88
"qe_identity_issuer_chain": "-----BEGIN CERTIFICATE-----\nMIICjTCCAjKgAwIBAgIUfjiC1ftVKUpASY5FhAPpFJG99FUwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTI1MDUwNjA5MjUwMFoXDTMyMDUwNjA5MjUwMFowbDEeMBwG\nA1UEAwwVSW50ZWwgU0dYIFRDQiBTaWduaW5nMRowGAYDVQQKDBFJbnRlbCBDb3Jw\nb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQswCQYD\nVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABENFG8xzydWRfK92bmGv\nP+mAh91PEyV7Jh6FGJd5ndE9aBH7R3E4A7ubrlh/zN3C4xvpoouGlirMba+W2lju\nypajgbUwgbIwHwYDVR0jBBgwFoAUImUM1lqdNInzg7SVUr9QGzknBqwwUgYDVR0f\nBEswSTBHoEWgQ4ZBaHR0cHM6Ly9jZXJ0aWZpY2F0ZXMudHJ1c3RlZHNlcnZpY2Vz\nLmludGVsLmNvbS9JbnRlbFNHWFJvb3RDQS5kZXIwHQYDVR0OBBYEFH44gtX7VSlK\nQEmORYQD6RSRvfRVMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMAoGCCqG\nSM49BAMCA0kAMEYCIQDdmmRuAo3qCO8TC1IoJMITAoOEw4dlgEBHzSz1TuMSTAIh\nAKVTqOkt59+co0O3m3hC+v5Fb00FjYWcgeu3EijOULo5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n",
99
"qe_identity": "{\"id\":\"TD_QE\",\"version\":2,\"issueDate\":\"2026-08-07T00:34:59Z\",\"nextUpdate\":\"2026-09-06T00:34:59Z\",\"tcbEvaluationDataNumber\":19,\"miscselect\":\"00000000\",\"miscselectMask\":\"FFFFFFFF\",\"attributes\":\"11000000000000000000000000000000\",\"attributesMask\":\"FBFFFFFFFFFFFFFF0000000000000000\",\"mrsigner\":\"DC9E2A7C6F948F17474E34A7FC43ED030F7C1563F1BABDDF6340C82E0E54A8C5\",\"isvprodid\":2,\"tcbLevels\":[{\"tcb\":{\"isvsvn\":4},\"tcbDate\":\"2025-05-14T00:00:00Z\",\"tcbStatus\":\"UpToDate\"}]}",
1010
"qe_identity_signature": "3924f3d4773c519a708264a7678da83b3a62445162aba96e26e182d653416de2572eadb8602b5c3da484c1807fa502f94a19d2fea61f6b5c3b97c017f5443935",
11-
"pck_certificate_chain": "-----BEGIN CERTIFICATE-----\nMIIE8TCCBJagAwIBAgIUf2SbywkMVTJKU57/JwBp8EdhP04wCgYIKoZIzj0EAwIw\ncDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBQbGF0Zm9ybSBDQTEaMBgGA1UECgwR\nSW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI\nDAJDQTELMAkGA1UEBhMCVVMwHhcNMjUxMTA2MDczNzM0WhcNMzIxMTA2MDczNzM0\nWjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK\nDBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV\nBAgMAkNBMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGpv\n0YuYrqAuSKBzKlub6mL+rvfD5AjYO3QNgfWztg4em1EGBVkGlWvduB0XQSE/sxGD\nmSvKo9t3CrOPC4SU6X6jggMMMIIDCDAfBgNVHSMEGDAWgBSVb13NvRvh6UBJydT0\nM84BVwveVDBrBgNVHR8EZDBiMGCgXqBchlpodHRwczovL2FwaS50cnVzdGVkc2Vy\ndmljZXMuaW50ZWwuY29tL3NneC9jZXJ0aWZpY2F0aW9uL3Y0L3Bja2NybD9jYT1w\nbGF0Zm9ybSZlbmNvZGluZz1kZXIwHQYDVR0OBBYEFG3n6S+KxN6t+HI8Gp96PkuZ\niWsZMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIICOQYJKoZIhvhNAQ0B\nBIICKjCCAiYwHgYKKoZIhvhNAQ0BAQQQ0gjfsQAjRq4btO8qPAVSkjCCAWMGCiqG\nSIb4TQENAQIwggFTMBAGCyqGSIb4TQENAQIBAgEEMBAGCyqGSIb4TQENAQICAgEE\nMBAGCyqGSIb4TQENAQIDAgECMBAGCyqGSIb4TQENAQIEAgECMBAGCyqGSIb4TQEN\nAQIFAgEEMBAGCyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEAMBAGCyqG\nSIb4TQENAQIIAgEFMBAGCyqGSIb4TQENAQIJAgEAMBAGCyqGSIb4TQENAQIKAgEA\nMBAGCyqGSIb4TQENAQILAgEAMBAGCyqGSIb4TQENAQIMAgEAMBAGCyqGSIb4TQEN\nAQINAgEAMBAGCyqGSIb4TQENAQIOAgEAMBAGCyqGSIb4TQENAQIPAgEAMBAGCyqG\nSIb4TQENAQIQAgEAMBAGCyqGSIb4TQENAQIRAgELMB8GCyqGSIb4TQENAQISBBAE\nBAICBAEABQAAAAAAAAAAMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQE\nBrDAbwAAADAPBgoqhkiG+E0BDQEFCgEBMB4GCiqGSIb4TQENAQYEEDa9htA8AJ/Z\n2FmaL5Jq/KEwRAYKKoZIhvhNAQ0BBzA2MBAGCyqGSIb4TQENAQcBAQH/MBAGCyqG\nSIb4TQENAQcCAQH/MBAGCyqGSIb4TQENAQcDAQH/MAoGCCqGSM49BAMCA0kAMEYC\nIQCFG1YAb3eXFte853ClVBnhlCfDyc572ZXEqax4UccSawIhAOn0VNKTZmAxUF4n\nwRkSFh4qFJ3aUlzFoPQT3xIf7kFD\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICljCCAj2gAwIBAgIVAJVvXc29G+HpQEnJ1PQzzgFXC95UMAoGCCqGSM49BAMC\nMGgxGjAYBgNVBAMMEUludGVsIFNHWCBSb290IENBMRowGAYDVQQKDBFJbnRlbCBD\nb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQsw\nCQYDVQQGEwJVUzAeFw0xODA1MjExMDUwMTBaFw0zMzA1MjExMDUwMTBaMHAxIjAg\nBgNVBAMMGUludGVsIFNHWCBQQ0sgUGxhdGZvcm0gQ0ExGjAYBgNVBAoMEUludGVs\nIENvcnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0Ex\nCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENSB/7t21lXSO\n2Cuzpxw74eJB72EyDGgW5rXCtx2tVTLq6hKk6z+UiRZCnqR7psOvgqFeSxlmTlJl\neTmi2WYz3qOBuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBS\nBgNVHR8ESzBJMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2Vy\ndmljZXMuaW50ZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUlW9d\nzb0b4elAScnU9DPOAVcL3lQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYB\nAf8CAQAwCgYIKoZIzj0EAwIDRwAwRAIgXsVki0w+i6VYGW3UF/22uaXe0YJDj1Ue\nnA+TjD1ai5cCICYb1SAmD5xkfTVpvo4UoyiSYxrDWLmUR4CI9NKyfPN+\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n\u0000"
11+
"pck_certificate_chain": "-----BEGIN CERTIFICATE-----\nMIIE8TCCBJagAwIBAgIUf2SbywkMVTJKU57/JwBp8EdhP04wCgYIKoZIzj0EAwIw\ncDEiMCAGA1UEAwwZSW50ZWwgU0dYIFBDSyBQbGF0Zm9ybSBDQTEaMBgGA1UECgwR\nSW50ZWwgQ29ycG9yYXRpb24xFDASBgNVBAcMC1NhbnRhIENsYXJhMQswCQYDVQQI\nDAJDQTELMAkGA1UEBhMCVVMwHhcNMjUxMTA2MDczNzM0WhcNMzIxMTA2MDczNzM0\nWjBwMSIwIAYDVQQDDBlJbnRlbCBTR1ggUENLIENlcnRpZmljYXRlMRowGAYDVQQK\nDBFJbnRlbCBDb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNV\nBAgMAkNBMQswCQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGpv\n0YuYrqAuSKBzKlub6mL+rvfD5AjYO3QNgfWztg4em1EGBVkGlWvduB0XQSE/sxGD\nmSvKo9t3CrOPC4SU6X6jggMMMIIDCDAfBgNVHSMEGDAWgBSVb13NvRvh6UBJydT0\nM84BVwveVDBrBgNVHR8EZDBiMGCgXqBchlpodHRwczovL2FwaS50cnVzdGVkc2Vy\ndmljZXMuaW50ZWwuY29tL3NneC9jZXJ0aWZpY2F0aW9uL3Y0L3Bja2NybD9jYT1w\nbGF0Zm9ybSZlbmNvZGluZz1kZXIwHQYDVR0OBBYEFG3n6S+KxN6t+HI8Gp96PkuZ\niWsZMA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMIICOQYJKoZIhvhNAQ0B\nBIICKjCCAiYwHgYKKoZIhvhNAQ0BAQQQ0gjfsQAjRq4btO8qPAVSkjCCAWMGCiqG\nSIb4TQENAQIwggFTMBAGCyqGSIb4TQENAQIBAgEEMBAGCyqGSIb4TQENAQICAgEE\nMBAGCyqGSIb4TQENAQIDAgECMBAGCyqGSIb4TQENAQIEAgECMBAGCyqGSIb4TQEN\nAQIFAgEEMBAGCyqGSIb4TQENAQIGAgEBMBAGCyqGSIb4TQENAQIHAgEAMBAGCyqG\nSIb4TQENAQIIAgEFMBAGCyqGSIb4TQENAQIJAgEAMBAGCyqGSIb4TQENAQIKAgEA\nMBAGCyqGSIb4TQENAQILAgEAMBAGCyqGSIb4TQENAQIMAgEAMBAGCyqGSIb4TQEN\nAQINAgEAMBAGCyqGSIb4TQENAQIOAgEAMBAGCyqGSIb4TQENAQIPAgEAMBAGCyqG\nSIb4TQENAQIQAgEAMBAGCyqGSIb4TQENAQIRAgELMB8GCyqGSIb4TQENAQISBBAE\nBAICBAEABQAAAAAAAAAAMBAGCiqGSIb4TQENAQMEAgAAMBQGCiqGSIb4TQENAQQE\nBrDAbwAAADAPBgoqhkiG+E0BDQEFCgEBMB4GCiqGSIb4TQENAQYEEDa9htA8AJ/Z\n2FmaL5Jq/KEwRAYKKoZIhvhNAQ0BBzA2MBAGCyqGSIb4TQENAQcBAQH/MBAGCyqG\nSIb4TQENAQcCAQH/MBAGCyqGSIb4TQENAQcDAQH/MAoGCCqGSM49BAMCA0kAMEYC\nIQCFG1YAb3eXFte853ClVBnhlCfDyc572ZXEqax4UccSawIhAOn0VNKTZmAxUF4n\nwRkSFh4qFJ3aUlzFoPQT3xIf7kFD\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICljCCAj2gAwIBAgIVAJVvXc29G+HpQEnJ1PQzzgFXC95UMAoGCCqGSM49BAMC\nMGgxGjAYBgNVBAMMEUludGVsIFNHWCBSb290IENBMRowGAYDVQQKDBFJbnRlbCBD\nb3Jwb3JhdGlvbjEUMBIGA1UEBwwLU2FudGEgQ2xhcmExCzAJBgNVBAgMAkNBMQsw\nCQYDVQQGEwJVUzAeFw0xODA1MjExMDUwMTBaFw0zMzA1MjExMDUwMTBaMHAxIjAg\nBgNVBAMMGUludGVsIFNHWCBQQ0sgUGxhdGZvcm0gQ0ExGjAYBgNVBAoMEUludGVs\nIENvcnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0Ex\nCzAJBgNVBAYTAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENSB/7t21lXSO\n2Cuzpxw74eJB72EyDGgW5rXCtx2tVTLq6hKk6z+UiRZCnqR7psOvgqFeSxlmTlJl\neTmi2WYz3qOBuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBS\nBgNVHR8ESzBJMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2Vy\ndmljZXMuaW50ZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUlW9d\nzb0b4elAScnU9DPOAVcL3lQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYB\nAf8CAQAwCgYIKoZIzj0EAwIDRwAwRAIgXsVki0w+i6VYGW3UF/22uaXe0YJDj1Ue\nnA+TjD1ai5cCICYb1SAmD5xkfTVpvo4UoyiSYxrDWLmUR4CI9NKyfPN+\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIICjzCCAjSgAwIBAgIUImUM1lqdNInzg7SVUr9QGzknBqwwCgYIKoZIzj0EAwIw\naDEaMBgGA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENv\ncnBvcmF0aW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJ\nBgNVBAYTAlVTMB4XDTE4MDUyMTEwNDUxMFoXDTQ5MTIzMTIzNTk1OVowaDEaMBgG\nA1UEAwwRSW50ZWwgU0dYIFJvb3QgQ0ExGjAYBgNVBAoMEUludGVsIENvcnBvcmF0\naW9uMRQwEgYDVQQHDAtTYW50YSBDbGFyYTELMAkGA1UECAwCQ0ExCzAJBgNVBAYT\nAlVTMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEC6nEwMDIYZOj/iPWsCzaEKi7\n1OiOSLRFhWGjbnBVJfVnkY4u3IjkDYYL0MxO4mqsyYjlBalTVYxFP2sJBK5zlKOB\nuzCBuDAfBgNVHSMEGDAWgBQiZQzWWp00ifODtJVSv1AbOScGrDBSBgNVHR8ESzBJ\nMEegRaBDhkFodHRwczovL2NlcnRpZmljYXRlcy50cnVzdGVkc2VydmljZXMuaW50\nZWwuY29tL0ludGVsU0dYUm9vdENBLmRlcjAdBgNVHQ4EFgQUImUM1lqdNInzg7SV\nUr9QGzknBqwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwCgYI\nKoZIzj0EAwIDSQAwRgIhAOW/5QkR+S9CiSDcNoowLuPRLsWGf/Yi7GSX94BgwTwg\nAiEA4J0lrHoMs+Xo5o/sX6O9QWxHRAvZUGOdRQ7cvqRXaqI=\n-----END CERTIFICATE-----\n"
1212
}

crates/test-utils/assets/create-assets.sh

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,23 @@ printf '%s' "$(jq -r --indent 4 '.tee_participant_info.Dstack.tcb_info.app_compo
4040
# arrays, while the fixture parser (`attestation::collateral::collateral_from_json`)
4141
# reads them as hex strings, so hex-encode those four fields here. Fields that
4242
# are already hex pass through unchanged.
43+
# The PEM chain arrives NUL-terminated from the quote's C string; strip it so the
44+
# fixture stays valid PEM for consumers stricter than dcap-qvl.
4345
jq -r 'def tohex:
4446
if type == "array" then
4547
reduce .[] as $b (""; . + ("0123456789abcdef" | .[(($b / 16) | floor):(($b / 16) | floor) + 1])
4648
+ ("0123456789abcdef" | .[($b % 16):($b % 16) + 1]))
4749
else . end;
50+
def strip_nul: if type == "string" then until(endswith("\u0000") | not; rtrimstr("\u0000")) else . end;
4851
.tee_participant_info.Dstack.collateral
4952
| .root_ca_crl |= tohex
5053
| .pck_crl |= tohex
5154
| .tcb_info_signature |= tohex
52-
| .qe_identity_signature |= tohex' "$INPUT_FILE" > "$OUTPUT_DIR/collateral.json"
55+
| .qe_identity_signature |= tohex
56+
| .pck_crl_issuer_chain |= strip_nul
57+
| .tcb_info_issuer_chain |= strip_nul
58+
| .qe_identity_issuer_chain |= strip_nul
59+
| .pck_certificate_chain |= strip_nul' "$INPUT_FILE" > "$OUTPUT_DIR/collateral.json"
5360

5461
# Extract quote
5562
jq -c '.tee_participant_info.Dstack.quote' "$INPUT_FILE" > "$OUTPUT_DIR/quote.json"
@@ -68,12 +75,12 @@ echo "Extraction complete. Files written to '$OUTPUT_DIR':"
6875
ls -la "$OUTPUT_DIR"
6976

7077
# The secret counterpart of near_account_public_key.pub is not part of
71-
# public_data: it must be exported from the node (secrets.json in the node
72-
# home dir) by whoever regenerates the assets. Without it, the sandbox tests
73-
# that sign as the fixture account cannot run (issue #3787).
74-
if [ ! -f "$OUTPUT_DIR/near_account_secret_key" ]; then
75-
echo ""
76-
echo "WARNING: '$OUTPUT_DIR/near_account_secret_key' is missing."
77-
echo "Copy the node's NEAR signer secret key (ed25519:<base58>, one line) there,"
78-
echo "or the fixture keypair will drift apart. See README.md."
79-
fi
78+
# public_data: it must be exported from the node (secrets.json in the node home
79+
# dir) by whoever regenerates the assets. It is committed, so it is normally
80+
# present but stale — hence an unconditional reminder rather than an
81+
# existence check. A mismatched pair fails the sandbox tests that sign as the
82+
# fixture account.
83+
echo ""
84+
echo "REMINDER: replace '$OUTPUT_DIR/near_account_secret_key' with the secret key of"
85+
echo "the node you just extracted from (ed25519:<base58>, one line). It must pair with"
86+
echo "the freshly written near_account_public_key.pub. See README.md."
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ed25519:rS6SmFPPaViyKph7Uapy4Gb8ZfBHwmRMCEUfgmpAYyi8hdgkeKpVMPJDwaQjp6GrkdCgViKRy7hrjUmJwarZcLR
1+
ed25519:rS6SmFPPaViyKph7Uapy4Gb8ZfBHwmRMCEUfgmpAYyi8hdgkeKpVMPJDwaQjp6GrkdCgViKRy7hrjUmJwarZcLR

deployment/cvm-deployment/default.env

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,11 @@ OS_IMAGE=dstack-dev-0.5.8
6969
# Path of the user_config file
7070
USER_CONFIG_FILE_PATH=user-config.toml
7171

72+
# Leave unset. A pre-launch script runs as root inside the CVM, and attestation
73+
# verification rejects any app-compose carrying one, so the CVM cannot join the
74+
# network. Only fixture collection sets this; see
75+
# localnet/tee/scripts/rust-launcher/README.md
76+
#PRELAUNCH_SCRIPT=
77+
7278
# for testing use a smaller disk size 128G
7379
DISK=1000G

deployment/cvm-deployment/deploy-launcher-guide.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ USER_CONFIG_FILE_PATH=user-config.toml
162162
DISK=1000G
163163
```
164164

165+
> **Never set `PRELAUNCH_SCRIPT` for a real deployment.** It bakes a script into
166+
> the app-compose that runs as root inside the CVM before the node starts.
167+
> Attestation verification rejects any app-compose carrying one, so such a CVM
168+
> can never join the network; it exists only to collect test fixtures (see
169+
> `localnet/tee/scripts/rust-launcher/README.md`). The `.env` file is sourced
170+
> under `set -a`, so a leftover line takes effect silently — `deploy-launcher.sh`
171+
> prints a warning when it finds one.
172+
165173
---
166174

167175
Based on: [Original Dstack deploy script](https://github.com/Dstack-TEE/dstack/blob/be9d0476a63e937eda4c13659547a25088393394/kms/dstack-app/deploy-to-vmm.sh)

0 commit comments

Comments
 (0)