Skip to content

Commit a24476f

Browse files
committed
Update doc for verifier
1 parent cf5cc61 commit a24476f

File tree

4 files changed

+75
-60
lines changed

4 files changed

+75
-60
lines changed

sdk/curl/api.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ curl --unix-socket /var/run/dstack.sock http://dstack/GetQuote?report_data=00000
131131
{
132132
"quote": "<hex-encoded-quote>",
133133
"event_log": "quote generation log",
134-
"report_data": "<hex-encoded-report-data>"
134+
"report_data": "<hex-encoded-report-data>",
135+
"vm_config": "<json-vm-config-string>"
135136
}
136137
```
137138

verifier/README.md

Lines changed: 56 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
# dstack-verifier
22

3-
A HTTP server that provides CVM (Confidential Virtual Machine) verification services using the same verification process as the dstack KMS.
4-
5-
## Features
6-
7-
- **TDX Quote Verification**: Uses dcap-qvl to verify TDX quotes
8-
- **Event Log Verification**: Validates event logs and extracts app information
9-
- **OS Image Hash Verification**: Uses dstack-mr to ensure OS image hash matches expected measurements
10-
- **Automatic Image Download**: Downloads and caches OS images automatically when not found locally
11-
- **RESTful API**: Simple HTTP endpoints for verification requests
3+
A HTTP server that provides dstack quote verification services using the same verification process as the dstack KMS.
124

135
## API Endpoints
146

157
### POST /verify
168

17-
Verifies a CVM attestation with the provided quote, event log, and VM configuration.
9+
Verifies a dstack quote with the provided quote and VM configuration. The body can be grabbed via [getQuote](https://github.com/Dstack-TEE/dstack/blob/master/sdk/curl/api.md#3-get-quote).
1810

1911
**Request Body:**
2012
```json
2113
{
2214
"quote": "hex-encoded-quote",
2315
"event_log": "hex-encoded-event-log",
2416
"vm_config": "json-vm-config-string",
25-
"pccs_url": "optional-pccs-url"
2617
}
2718
```
2819

@@ -71,11 +62,6 @@ Health check endpoint that returns service status.
7162

7263
## Configuration
7364

74-
Configuration can be provided via:
75-
1. TOML file (default: `dstack-verifier.toml`)
76-
2. Environment variables with prefix `DSTACK_VERIFIER_`
77-
3. Command line arguments
78-
7965
### Configuration Options
8066

8167
- `host`: Server bind address (default: "0.0.0.0")
@@ -90,14 +76,16 @@ Configuration can be provided via:
9076
```toml
9177
host = "0.0.0.0"
9278
port = 8080
93-
image_cache_dir = "/var/cache/dstack-verifier"
79+
image_cache_dir = "/tmp/dstack-verifier/cache"
9480
image_download_url = "http://0.0.0.0:8000/mr_{OS_IMAGE_HASH}.tar.gz"
9581
image_download_timeout_secs = 300
96-
pccs_url = "https://pccs.example.com"
82+
pccs_url = "https://pccs.phala.network"
9783
```
9884

9985
## Usage
10086

87+
### Running with Cargo
88+
10189
```bash
10290
# Run with default config
10391
cargo run --bin dstack-verifier
@@ -106,29 +94,64 @@ cargo run --bin dstack-verifier
10694
cargo run --bin dstack-verifier -- --config /path/to/config.toml
10795

10896
# Set via environment variables
109-
DSTACK_VERIFIER_PORT=9000 cargo run --bin dstack-verifier
97+
DSTACK_VERIFIER_PORT=8080 cargo run --bin dstack-verifier
11098
```
11199

112-
## Testing
100+
### Running with Docker Compose
101+
102+
```yaml
103+
services:
104+
dstack-verifier:
105+
image: kvin/dstack-verifier:latest
106+
ports:
107+
- "8080:8080"
108+
restart: unless-stopped
109+
```
110+
111+
Save the docker compose file as `docker-compose.yml` and run `docker compose up -d`.
112+
113+
### Request verification
113114

114-
Two test scripts are provided for easy testing:
115+
Grab a quote from your app. It's depends on your app how to grab a quote.
115116

116-
### Full Test (with server management)
117117
```bash
118-
./test.sh
118+
# Grab a quote from the demo app
119+
curl https://712eab2f507b963e11144ae67218177e93ac2a24-3000.app.kvin.wang:12004/GetQuote?report_data=0x1234 -o quote.json
120+
119121
```
120-
This script will:
121-
- Build the project
122-
- Start the server
123-
- Run the verification test
124-
- Display detailed results
125-
- Clean up automatically
126-
127-
### Quick Test (assumes server is running)
122+
123+
Send the quote to the verifier.
124+
128125
```bash
129-
./quick-test.sh
126+
$ curl -s -d @quote.json localhost:8080/verify | jq
127+
{
128+
"is_valid": true,
129+
"details": {
130+
"quote_verified": true,
131+
"event_log_verified": true,
132+
"os_image_hash_verified": true,
133+
"report_data": "12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
134+
"tcb_status": "UpToDate",
135+
"advisory_ids": [],
136+
"app_info": {
137+
"app_id": "e631a04a5d068c0e5ffd8ca60d6574ac99a18bda",
138+
"compose_hash": "e631a04a5d068c0e5ffd8ca60d6574ac99a18bdaf0417d129d0c4ac52244d40f",
139+
"instance_id": "712eab2f507b963e11144ae67218177e93ac2a24",
140+
"device_id": "ee218f44a5f0a9c3233f9cc09f0cd41518f376478127feb989d5cf1292c56a01",
141+
"mrtd": "f06dfda6dce1cf904d4e2bab1dc370634cf95cefa2ceb2de2eee127c9382698090d7a4a13e14c536ec6c9c3c8fa87077",
142+
"rtmr0": "68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96",
143+
"rtmr1": "a7b523278d4f914ee8df0ec80cd1c3d498cbf1152b0c5eaf65bad9425072874a3fcf891e8b01713d3d9937e3e0d26c15",
144+
"rtmr2": "dbf4924c07f5066f3dc6859844184344306aa3263817153dcaee85af97d23e0c0b96efe0731d8865a8747e51b9e351ac",
145+
"rtmr3": "5e7d8d84317343d28d73031d0be3c75f25facb1b20c9835a44582b8b0115de1acfe2d19350437dbd63846bcc5d7bf328",
146+
"mr_system": "145010fa227e6c2537ad957c64e4a8486fcbfd8265ddfb359168b59afcff1d05",
147+
"mr_aggregated": "52f6d7ccbee1bfa870709e8ff489e016e2e5c25a157b7e22ef1ea68fce763694",
148+
"os_image_hash": "b6420818b356b198bdd70f076079aa0299a20279b87ab33ada7b2770ef432a5a",
149+
"key_provider_info": "7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343139623234353764643962386161363434366439383066313336666666373831326563643663373737343065656230653238623130643536633063303030323861356236653539646365613330376435383362643166373037363965396331313664663262636662313735386139356438363133653764653163383438326330227d"
150+
}
151+
},
152+
"reason": null
153+
}
130154
```
131-
This script assumes the server is already running and just sends a test request.
132155

133156
## Verification Process
134157

@@ -142,22 +165,3 @@ The verifier performs three main verification steps:
142165
- Compares against the verified measurements from the quote
143166

144167
All three steps must pass for the verification to be considered valid.
145-
146-
### Automatic Image Download
147-
148-
When an OS image is not found in the local cache, the verifier will:
149-
150-
1. **Download**: Fetch the image tarball from the configured URL
151-
2. **Extract**: Extract the tarball contents to a temporary directory
152-
3. **Verify**: Check SHA256 checksums to ensure file integrity
153-
4. **Validate**: Confirm the OS image hash matches the computed hash
154-
5. **Cache**: Move the validated files to the cache directory for future use
155-
156-
The download URL template uses `{OS_IMAGE_HASH}` as a placeholder that gets replaced with the actual OS image hash from the verification request.
157-
158-
## Dependencies
159-
160-
- dcap-qvl: TDX quote verification
161-
- dstack-mr: OS image measurement computation
162-
- ra-tls: Attestation handling and verification
163-
- rocket: HTTP server framework

verifier/src/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub struct VerificationRequest {
1111
pub event_log: String,
1212
pub vm_config: String,
1313
pub pccs_url: Option<String>,
14+
pub debug: Option<bool>,
1415
}
1516

1617
#[derive(Debug, Clone, Serialize)]

verifier/src/verification.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@ impl CvmVerifier {
167167
let attestation = Attestation::new(quote, event_log)
168168
.context("Failed to create attestation from quote and event log")?;
169169

170+
let debug = request.debug.unwrap_or(false);
171+
170172
let mut details = VerificationDetails {
171173
quote_verified: false,
172174
event_log_verified: false,
@@ -205,7 +207,7 @@ impl CvmVerifier {
205207

206208
// Step 3: Verify os-image-hash matches using dstack-mr
207209
if let Err(e) = self
208-
.verify_os_image_hash(&vm_config, &verified_attestation, &mut details)
210+
.verify_os_image_hash(&vm_config, &verified_attestation, debug, &mut details)
209211
.await
210212
{
211213
return Ok(VerificationResponse {
@@ -255,6 +257,7 @@ impl CvmVerifier {
255257
&self,
256258
vm_config: &VmConfig,
257259
attestation: &VerifiedAttestation,
260+
debug: bool,
258261
details: &mut VerificationDetails,
259262
) -> Result<()> {
260263
let hex_os_image_hash = hex::encode(&vm_config.os_image_hash);
@@ -328,11 +331,13 @@ impl CvmVerifier {
328331

329332
let mrs = measurement_details.measurements;
330333
let expected_logs = measurement_details.rtmr_logs;
331-
details.acpi_tables = Some(AcpiTables {
332-
tables: hex::encode(&measurement_details.acpi_tables.tables),
333-
rsdp: hex::encode(&measurement_details.acpi_tables.rsdp),
334-
loader: hex::encode(&measurement_details.acpi_tables.loader),
335-
});
334+
if debug {
335+
details.acpi_tables = Some(AcpiTables {
336+
tables: hex::encode(&measurement_details.acpi_tables.tables),
337+
rsdp: hex::encode(&measurement_details.acpi_tables.rsdp),
338+
loader: hex::encode(&measurement_details.acpi_tables.loader),
339+
});
340+
}
336341

337342
let expected_mrs = Mrs {
338343
mrtd: mrs.mrtd.clone(),
@@ -354,6 +359,10 @@ impl CvmVerifier {
354359
match expected_mrs.assert_eq(&verified_mrs) {
355360
Ok(()) => Ok(()),
356361
Err(e) => {
362+
let result = Err(e).context("MRs do not match");
363+
if !debug {
364+
return result;
365+
}
357366
let mut rtmr_debug = Vec::new();
358367

359368
if expected_mrs.rtmr0 != verified_mrs.rtmr0 {
@@ -393,7 +402,7 @@ impl CvmVerifier {
393402
details.rtmr_debug = Some(rtmr_debug);
394403
}
395404

396-
Err(e.context("MRs do not match"))
405+
result
397406
}
398407
}
399408
}

0 commit comments

Comments
 (0)