Skip to content

Commit 6d23c43

Browse files
h4x3rotabclaude
andcommitted
docs: improve on-chain governance guide
- Add ALCHEMY_API_KEY to prerequisites and deploy command - Add KMS_CONTRACT_ADDRESS export after deployment (critical fix) - Clarify KMS_CONTRACT_ADDR vs KMS_CONTRACT_ADDRESS usage - Add sample outputs for all commands - Add compose hash computation instructions - Add cross-references to related docs - Writing guide: add procedural documentation section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 3740eb9 commit 6d23c43

3 files changed

Lines changed: 192 additions & 35 deletions

File tree

.agent/WRITING_GUIDE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,30 @@ When describing components for security researchers:
5353
| Docker Compose native | VMM | Direct parsing, no translation |
5454
| Reproducible OS | VMM | Deterministic image builds |
5555
| Confidential GPUs | VMM + hardware | NVIDIA H100/Blackwell allocation |
56+
57+
## Procedural Documentation (Guides & Tutorials)
58+
59+
### Test Before You Document
60+
- **Run every command** before documenting it — reading code is not enough
61+
- Commands may prompt for confirmation, require undocumented env vars, or fail silently
62+
- Create a test environment and execute the full flow end-to-end
63+
64+
### Show What Success Looks Like
65+
- **Add sample outputs** after commands so users can verify they're on track
66+
- For deployment commands, show the key values users need to note (addresses, IDs)
67+
- For validation commands, show both success and failure outputs
68+
69+
### Environment Variables
70+
- **List all required env vars explicitly** — don't assume users will discover them
71+
- If multiple tools use similar-but-different var names, clarify which is which
72+
- Show the export pattern once, then reference it in subsequent commands
73+
74+
### Avoid Expert Blind Spots
75+
- If you say "add the hash", explain how to compute the hash
76+
- If you reference a file, explain where to find it
77+
- If a value comes from a previous step, remind users which step
78+
79+
### Cross-Reference Related Docs
80+
- Link to prerequisite guides (don't repeat content)
81+
- Link to detailed guides for optional deep-dives
82+
- Use anchor links for specific sections when possible

docs/deployment.md

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,23 @@ Start VMM:
172172

173173
### 2. Deploy KMS as CVM
174174

175-
> **TODO:** This section needs a proper rewrite covering auth server configuration. The current instructions are incomplete.
175+
Production KMS requires three components running together:
176+
- **KMS**: The key management service inside a CVM
177+
- **auth-api**: Webhook server that validates requests against smart contracts
178+
- **Ethereum RPC**: Access to the blockchain (via light client or external RPC)
176179

177-
Production KMS deployment requires:
178-
- KMS running inside a CVM
179-
- Auth server for authorization (webhook mode, not dev mode)
180-
- OS image whitelisting
180+
#### Prerequisites: Deploy DstackKms Contract
181+
182+
Before deploying KMS, you need a DstackKms contract on an Ethereum-compatible network:
183+
184+
```bash
185+
cd dstack/kms/auth-eth
186+
npm install
187+
npx hardhat compile
188+
PRIVATE_KEY=<your-key> npx hardhat kms:deploy --with-app-impl --network <network>
189+
```
190+
191+
Note the deployed contract address (e.g., `0xFE6C45aE66344CAEF5E5D7e2cbD476286D651875`).
181192

182193
#### Deploy KMS CVM
183194

@@ -189,13 +200,29 @@ cd dstack/kms/dstack-app/
189200
Edit the generated `.env` file:
190201

191202
```bash
203+
# VMM connection
192204
VMM_RPC=unix:../../vmm-data/vmm.sock
205+
206+
# Network configuration
193207
KMS_RPC_ADDR=0.0.0.0:9201
194208
GUEST_AGENT_ADDR=127.0.0.1:9205
195-
GIT_REV=HEAD
209+
210+
# Auth server configuration (required for production)
211+
KMS_CONTRACT_ADDR=0xFE6C45aE66344CAEF5E5D7e2cbD476286D651875
212+
ETH_RPC_URL=https://rpc.phala.network
213+
214+
# OS image verification
196215
OS_IMAGE=dstack-0.5.5
216+
IMAGE_DOWNLOAD_URL=https://github.com/Dstack-TEE/meta-dstack/releases/download/v{version}/dstack-{version}.tar.gz
217+
218+
# Build reference
219+
GIT_REV=HEAD
197220
```
198221

222+
The compose file (`docker-compose.yaml`) includes:
223+
- **auth-api**: Connects to the smart contract via `ETH_RPC_URL`
224+
- **kms**: Configured with webhook auth mode pointing to auth-api
225+
199226
Run the script again to deploy:
200227

201228
```bash
@@ -224,25 +251,41 @@ The KMS will display its public key and TDX quote:
224251

225252
![KMS Bootstrap Result](assets/kms-bootstrap-result.png)
226253

227-
#### Configure Auth Server
228-
229-
> **TODO:** Document auth server setup for production KMS.
230-
231254
#### Whitelist OS Image
232255

233-
The OS image hash must be whitelisted before apps can run. This is required for both offchain and onchain governance.
256+
The OS image hash must be whitelisted in the DstackKms contract before apps can run:
257+
258+
```bash
259+
cd dstack/kms/auth-eth
260+
npx hardhat kms:add-image --network <network> 0x<os-image-hash>
261+
```
234262

235-
> **TODO:** Document OS image whitelisting for offchain auth server.
263+
The `os_image_hash` is in the `digest.txt` file from the [meta-dstack release](https://github.com/Dstack-TEE/meta-dstack/releases).
236264

237-
For on-chain governance, see [On-Chain Governance](./onchain-governance.md).
265+
For detailed smart contract operations, see [On-Chain Governance](./onchain-governance.md).
238266

239267
---
240268

241269
### 3. Deploy Gateway as CVM
242270

243-
> **TODO:** This section is incomplete. Gateway registration with auth server needs to be documented.
271+
The Gateway must be registered as an app in the DstackKms contract before deployment.
244272

245-
Deploy the Gateway CVM:
273+
#### Register Gateway App
274+
275+
```bash
276+
cd dstack/kms/auth-eth
277+
npx hardhat kms:create-app --network <network> --allow-any-device
278+
```
279+
280+
Note the App ID from output (e.g., `0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08`).
281+
282+
Set it as the gateway app in the KMS contract:
283+
284+
```bash
285+
npx hardhat kms:set-gateway --network <network> <app-id>
286+
```
287+
288+
#### Deploy Gateway CVM
246289

247290
```bash
248291
cd dstack/gateway/dstack-app/
@@ -252,32 +295,55 @@ cd dstack/gateway/dstack-app/
252295
Edit `.env`:
253296

254297
```bash
298+
# VMM connection
255299
VMM_RPC=unix:../../vmm-data/vmm.sock
300+
301+
# Cloudflare (for DNS-01 ACME challenge)
256302
CF_API_TOKEN=your_cloudflare_api_token
303+
304+
# Domain configuration
257305
SRV_DOMAIN=example.com
258306
PUBLIC_IP=$(curl -s ifconfig.me)
259-
ACME_STAGING=yes
307+
308+
# Gateway app ID (from registration above)
309+
GATEWAY_APP_ID=0x32467b43BFa67273FC7dDda0999Ee9A12F2AaA08
310+
311+
# Gateway URLs
312+
MY_URL=https://gateway.example.com:9202
313+
BOOTNODE_URL=https://gateway.example.com:9202
314+
315+
# Other settings
316+
ACME_STAGING=no # Set to 'yes' for testing
260317
OS_IMAGE=dstack-0.5.5
261318
```
262319

263-
Deploy:
320+
Run the script again - it will show the compose hash:
264321

265322
```bash
266323
./deploy-to-vmm.sh
267-
# Press 'y' to confirm
324+
# Output: Compose hash: 0x700a50336df7c07c82457b116e144f526c29f6d8...
325+
```
326+
327+
**Before pressing 'y'**, whitelist the compose hash:
328+
329+
```bash
330+
cd ../../kms/auth-eth
331+
npx hardhat app:add-hash --network <network> --app-id <gateway-app-id> 0x<compose-hash>
268332
```
269333

270-
Update `vmm.toml` with KMS and Gateway URLs:
334+
Then return and confirm deployment.
335+
336+
#### Update VMM Configuration
337+
338+
After Gateway is running, update `vmm.toml` with KMS and Gateway URLs:
271339

272340
```toml
273341
[cvm]
274342
kms_urls = ["https://kms.example.com:9201"]
275343
gateway_urls = ["https://gateway.example.com:9202"]
276344
```
277345

278-
Restart dstack-vmm.
279-
280-
> **TODO:** Document Gateway registration with offchain auth server.
346+
Restart dstack-vmm to apply changes.
281347

282348
---
283349

@@ -349,9 +415,22 @@ gateway_urls = ["https://gateway.example.com:9202"]
349415

350416
After setup, deploy apps via the VMM dashboard or CLI.
351417

352-
> **TODO:** Document app registration with offchain auth server.
418+
### Register App
419+
420+
Each app needs to be registered in the DstackKms contract:
421+
422+
```bash
423+
cd dstack/kms/auth-eth
424+
npx hardhat kms:create-app --network <network> --allow-any-device
425+
```
426+
427+
Note the App ID from output. Then whitelist your compose hash:
428+
429+
```bash
430+
npx hardhat app:add-hash --network <network> --app-id <app-id> 0x<compose-hash>
431+
```
353432

354-
For on-chain governed apps, see [On-Chain Governance](./onchain-governance.md).
433+
For detailed smart contract operations, see [On-Chain Governance](./onchain-governance.md).
355434

356435
### Deploy via UI
357436

@@ -360,7 +439,7 @@ Open `http://localhost:9080`:
360439
![App Deploy](assets/app-deploy.png)
361440

362441
- Select the OS image
363-
- Enter the App ID (from auth server registration)
442+
- Enter the App ID (from registration above)
364443
- Upload your `docker-compose.yaml`
365444

366445
After startup, click **Dashboard** to view:

docs/onchain-governance.md

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,54 +14,95 @@ On-chain governance adds:
1414
- Production dstack deployment with KMS and Gateway as CVMs (see [Deployment Guide](./deployment.md))
1515
- Ethereum wallet with funds on Sepolia testnet (or your target network)
1616
- Node.js and npm installed
17+
- Alchemy API key (for Sepolia) - get one at https://www.alchemy.com/
1718

1819
## Deploy DstackKms Contract
1920

2021
```bash
2122
cd dstack/kms/auth-eth
2223
npm install
2324
npx hardhat compile
24-
PRIVATE_KEY=<your-key> npx hardhat kms:deploy --with-app-impl --network sepolia
25+
PRIVATE_KEY=<your-key> ALCHEMY_API_KEY=<your-key> npx hardhat kms:deploy --with-app-impl --network sepolia
2526
```
2627

27-
Note the deployed contract address.
28+
The command will prompt for confirmation. Sample output:
29+
30+
```
31+
✅ DstackApp implementation deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3
32+
DstackKms Proxy deployed to: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
33+
Implementation deployed to: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
34+
```
35+
36+
Note the proxy address (e.g., `0x9fE4...`).
37+
38+
Set environment variables for subsequent commands:
39+
40+
```bash
41+
export KMS_CONTRACT_ADDRESS="<DstackKms-proxy-address>"
42+
export PRIVATE_KEY="<your-private-key>"
43+
export ALCHEMY_API_KEY="<your-alchemy-key>"
44+
```
2845

2946
## Configure KMS for On-Chain Auth
3047

31-
Update KMS to use webhook auth mode pointing to your auth-api service.
48+
The KMS CVM includes an auth-api service that connects to your DstackKms contract. Configure it via environment variables in the KMS CVM:
3249

33-
> **TODO:** Document auth-api service deployment and KMS webhook configuration.
50+
```bash
51+
KMS_CONTRACT_ADDR=<your-dstack-kms-contract-address>
52+
ETH_RPC_URL=<ethereum-rpc-endpoint>
53+
```
54+
55+
Note: The auth-api uses `KMS_CONTRACT_ADDR`, while Hardhat tasks use `KMS_CONTRACT_ADDRESS`.
56+
57+
The auth-api validates boot requests against the smart contract. See [Deployment Guide](./deployment.md#2-deploy-kms-as-cvm) for complete setup instructions.
3458

3559
## Whitelist OS Image
3660

3761
```bash
38-
cd dstack/kms/auth-eth
39-
npm install
4062
npx hardhat kms:add-image --network sepolia 0x<os-image-hash>
4163
```
4264

43-
The `os_image_hash` is in the `digest.txt` file from the image build.
65+
Output: `Image added successfully`
66+
67+
The `os_image_hash` is in the `digest.txt` file from the guest OS image build (see [Building Guest Images](./deployment.md#building-guest-images)).
4468

4569
## Register Gateway App
4670

4771
```bash
4872
npx hardhat kms:create-app --network sepolia --allow-any-device
4973
```
5074

51-
Note the App ID from the output.
75+
Sample output:
76+
77+
```
78+
✅ App deployed and registered successfully!
79+
Proxy Address (App Id): 0x75537828f2ce51be7289709686A69CbFDbB714F1
80+
```
81+
82+
Note the App ID (Proxy Address) from the output.
5283

5384
Set it as the gateway app:
5485

5586
```bash
5687
npx hardhat kms:set-gateway --network sepolia <app-id>
5788
```
5889

59-
Add the compose hash to the whitelist:
90+
Output: `Gateway App ID set successfully`
91+
92+
Add the gateway's compose hash to the whitelist. To compute the compose hash:
93+
94+
```bash
95+
sha256sum /path/to/gateway-compose.json | awk '{print "0x"$1}'
96+
```
97+
98+
Then add it:
6099

61100
```bash
62101
npx hardhat app:add-hash --network sepolia --app-id <app-id> <compose-hash>
63102
```
64103

104+
Output: `Compose hash added successfully`
105+
65106
## Register Apps On-Chain
66107

67108
For each app you want to deploy:
@@ -72,15 +113,25 @@ For each app you want to deploy:
72113
npx hardhat kms:create-app --network sepolia --allow-any-device
73114
```
74115

116+
Note the App ID from the output.
117+
75118
### Add Compose Hash
76119

120+
Compute your app's compose hash:
121+
122+
```bash
123+
sha256sum /path/to/your-app-compose.json | awk '{print "0x"$1}'
124+
```
125+
126+
Then add it:
127+
77128
```bash
78129
npx hardhat app:add-hash --network sepolia --app-id <app-id> <compose-hash>
79130
```
80131

81132
### Deploy via VMM
82133

83-
Use the App ID when deploying through the VMM dashboard or CLI.
134+
Use the App ID when deploying through the VMM dashboard or [VMM CLI](./vmm-cli-user-guide.md).
84135

85136
## Smart Contract Reference
86137

0 commit comments

Comments
 (0)