Skip to content

Commit 3e613dc

Browse files
feat: near kms integration
1 parent 9e273d0 commit 3e613dc

22 files changed

Lines changed: 3866 additions & 53 deletions

Cargo.lock

Lines changed: 618 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

kms/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ tempfile.workspace = true
4747
serde-duration.workspace = true
4848
dstack-verifier = { workspace = true, default-features = false }
4949
dstack-mr.workspace = true
50+
base64.workspace = true
51+
52+
# BLS12-381 for MPC key derivation
53+
blstrs = "0.7"
54+
elliptic-curve = "0.13"
55+
hkdf = "0.12.4"
56+
bs58 = "0.5"
57+
rand_core = { version = "0.6", features = ["getrandom"] }
58+
59+
# NEAR integration
60+
near-api = "0.8"
61+
near-crypto = "0.26" # Still needed for InMemorySigner in onboard_service.rs
5062

5163
[features]
5264
default = []

kms/README.md

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ CVMs running in dstack support three boot modes:
3333
## KMS Implementation
3434

3535
### Components
36+
37+
#### Ethereum/Base/Phala KMS
38+
3639
1. **dstack-kms**
3740
- Main RPC service for app key requests
3841
- Quote verification and boot info validation
@@ -56,11 +59,49 @@ CVMs running in dstack support three boot modes:
5659
- Controls permissions for individual apps
5760
- Maintains the allowed compose hashes for each app
5861

62+
#### NEAR KMS
63+
64+
1. **dstack-kms** (same as above)
65+
- Can be configured to use NEAR auth API instead of Ethereum
66+
67+
2. **dstack-kms-auth-near**
68+
- NEAR Protocol chain interface for permission checks
69+
- Two-step validation (same as auth-eth):
70+
1. KMS control contract check
71+
2. App control contract check
72+
- Handles hex → NEAR AccountId conversion
73+
- See [auth-near README](auth-near/README.md) for details
74+
75+
3. **NEAR Authorization Contracts**
76+
- `near-dstack-kms` (Rust contract)
77+
- Maintains a registry for all Applications
78+
- Maintains the allowed KMS Instance MRs
79+
- Maintains the allowed OS Images
80+
- Supports MPC-based root key derivation from NEAR MPC network
81+
- Factory method `register_app()` for deploying app contracts
82+
- `near-dstack-app` (Rust contract)
83+
- Deployed as subaccounts: `{app_id}.{kms_contract_id}`
84+
- Controls permissions for individual apps
85+
- Maintains the allowed compose hashes and device IDs per app
86+
87+
4. **MPC Key Derivation** (NEAR-specific)
88+
- KMS can derive deterministic root keys from NEAR MPC network
89+
- Uses BLS12-381 cryptography for secure key derivation
90+
- All KMS instances derive the same keys when using the same MPC domain
91+
- Falls back to local key generation if MPC config is incomplete
92+
5993
### Deployment
60-
The first two components are deployed as an dstack app on dstack in Local-Key-Provider mode.
94+
95+
The KMS components are deployed as a dstack app on dstack in Local-Key-Provider mode.
6196
The docker compose file would look like [this](dstack-app/docker-compose.yaml).
6297

63-
The solidity contracts are deployed on an ethereum compatible chain.
98+
**Authorization Contracts:**
99+
- **Ethereum/Base/Phala**: Solidity contracts deployed on an Ethereum-compatible chain
100+
- **NEAR**: Rust contracts deployed on NEAR Protocol (see [near-kms README](../near-kms/README.md))
101+
102+
**App Contract Deployment:**
103+
- **Ethereum**: Use Hardhat tasks (`app:deploy`, `app:add-hash`) or factory method `deployAndRegisterApp()`
104+
- **NEAR**: Use CLI commands (`bun run app:deploy`, `bun run app:add-hash`) or KMS contract's `register_app()` method
64105

65106

66107
## Trustness
@@ -89,12 +130,25 @@ On startup, the KMS node will either:
89130
- Onboard: Obtain root keys from an existing KMS instance
90131

91132
#### Bootstrapping
133+
134+
**Ethereum/Base/Phala KMS:**
92135
During bootstrapping, the KMS node generates two root keys:
93136
1. CA root key: Used to issue x509 certificates for Apps, enabling HTTPS traffic
94137
2. K256 root key: Used to derive Ethereum-compatible keys for Apps
95138

96139
After generating the root keys, their public portions can be obtained along with the corresponding TDX quote and registered in the DstackKms contract.
97140

141+
**NEAR KMS with MPC:**
142+
When configured with NEAR MPC, the KMS node derives deterministic root keys from the NEAR MPC network:
143+
1. Generates ephemeral BLS12-381 G1 keypair
144+
2. Calls MPC contract's `request_app_private_key()` with derivation path "kms-root-key"
145+
3. Receives encrypted response and decrypts using ephemeral private key
146+
4. Verifies MPC signature using BLS pairing
147+
5. Derives 32-byte root key using HKDF
148+
6. Converts root key to CA, tmp CA, RPC, and K256 keys using deterministic key derivation
149+
150+
All KMS instances using the same MPC domain will derive identical root keys, enabling seamless replication without key transfer. If MPC configuration is incomplete, the system automatically falls back to local key generation (same as Ethereum).
151+
98152
#### KMS Self Replication
99153
When deploying a new KMS instance (`B`) using an existing instance (`A`), the process follows these steps:
100154

@@ -117,9 +171,14 @@ Once onboarded, the KMS node begins listening for app key provisioning requests.
117171

118172
When a KMS node receives a key provisioning request, it:
119173
1. Validates the TDX quote of the requesting App
120-
2. Queries the DstackKms contract for provisioning allowance
174+
2. Queries the authorization contract (DstackKms or near-dstack-kms) for provisioning allowance
121175
3. If allowed, generates and sends the keys to the App
122176

177+
**NEAR-specific notes:**
178+
- App contracts are deployed as subaccounts: `{app_id}.{kms_contract_id}`
179+
- Compose hashes are stored as hex strings (without `0x` prefix)
180+
- Use `auth-near` CLI commands for app deployment and compose hash management (see [auth-near README](auth-near/README.md#cli-commands))
181+
123182
### Attestation
124183

125184
#### Vanilla TDX Quote attestation

kms/auth-near/COMPATIBILITY.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# NEAR Integration Compatibility Notes
2+
3+
## Gateway Compatibility
4+
5+
The gateway handles app IDs as hex-encoded strings internally. For NEAR:
6+
- App IDs in attestations are still bytes (as per dstack spec)
7+
- auth-near converts hex app_id to NEAR AccountId format when calling contracts
8+
- Gateway routing uses app_id from SNI parsing - works with any string format
9+
- **Status**: ✅ Compatible - no changes needed
10+
11+
## Guest Agent Compatibility
12+
13+
The guest-agent uses app_id as `Vec<u8>` internally:
14+
- App IDs come from attestation (bytes)
15+
- Encoded/decoded as hex strings when needed
16+
- auth-near handles the conversion to NEAR AccountId format
17+
- **Status**: ✅ Compatible - no changes needed
18+
19+
## App ID Format Considerations
20+
21+
- **Attestation**: App IDs are always bytes (hex-encoded)
22+
- **NEAR Contracts**: Expect AccountId (string format like "app.near")
23+
- **Conversion**: auth-near converts hex → AccountId when calling NEAR contracts
24+
- **Storage**: Gateway/guest-agent store app_id as hex strings internally
25+
26+
## Potential Future Enhancements
27+
28+
1. **App ID Mapping**: Consider a mapping layer if hex addresses need to map to NEAR AccountIds
29+
2. **SNI Parsing**: Gateway SNI parsing works with any string format, but ensure AccountId format is URL-safe
30+
3. **Validation**: Add validation to ensure AccountId format is valid NEAR account ID
31+
32+

0 commit comments

Comments
 (0)