Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
189 commits
Select commit Hold shift + click to select a range
57c2e8b
.
DSharifi Feb 27, 2026
b2621f8
wip
DSharifi Feb 27, 2026
f08c453
wip
DSharifi Feb 27, 2026
315a833
.
DSharifi Feb 27, 2026
07b3be5
wip
DSharifi Feb 27, 2026
cbf5afa
chore: enforce docker_content_trust at compile time
DSharifi Mar 2, 2026
8044407
created json
DSharifi Mar 2, 2026
34302f6
it compiles
DSharifi Mar 2, 2026
2965cde
wip
DSharifi Mar 2, 2026
795576a
wip
DSharifi Mar 3, 2026
c1ca0b2
wip
DSharifi Mar 3, 2026
d2ddedc
use const MPC_IMAGE_HASH_EVENT
DSharifi Mar 4, 2026
391be02
add deref to bounded vec
DSharifi Mar 4, 2026
1253c03
compiles
DSharifi Mar 4, 2026
9fe5b9a
wip
DSharifi Mar 4, 2026
422178a
wip
DSharifi Mar 5, 2026
cba7733
wip
DSharifi Mar 5, 2026
4b2f887
fix bug
DSharifi Mar 5, 2026
70c6fb1
.
DSharifi Mar 5, 2026
1b9bc08
fix sha256 prefix
DSharifi Mar 5, 2026
9b36896
fix docker args
DSharifi Mar 5, 2026
8a7c676
add some json examples of new config
DSharifi Mar 5, 2026
5815988
allow dynamically passthrough envs
DSharifi Mar 5, 2026
a357365
remove todo panics
DSharifi Mar 5, 2026
107a166
use backon for retries
DSharifi Mar 5, 2026
3913f97
inline the backon
DSharifi Mar 5, 2026
5e69675
add snapshot tests
DSharifi Mar 5, 2026
055f0af
use DockerSha256Digest
DSharifi Mar 5, 2026
4bde6c6
cleanup
DSharifi Mar 5, 2026
40289e1
fix bugs
DSharifi Mar 5, 2026
110d985
remove dead constants
DSharifi Mar 5, 2026
58b4421
rename to constants
DSharifi Mar 5, 2026
6b78e67
update image hashes watcher tests
DSharifi Mar 5, 2026
8294a99
cargo clippy on launcher tests
DSharifi Mar 5, 2026
86811bd
cargo clippy launcher interface tests
DSharifi Mar 5, 2026
dcbe19a
let claude add tests
DSharifi Mar 5, 2026
e658af4
add more tests
DSharifi Mar 5, 2026
4281065
rename to ApprovedHashes
DSharifi Mar 6, 2026
154e27b
update docker build launcher
DSharifi Mar 6, 2026
06dc89d
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 6, 2026
a696478
update cargo lock
DSharifi Mar 6, 2026
98d85fb
undo hash.rs change
DSharifi Mar 6, 2026
9d5d521
use assert_matches!
DSharifi Mar 6, 2026
b25072f
claude first pass
DSharifi Mar 6, 2026
af78d2c
testing manually with localnet works
DSharifi Mar 6, 2026
ae8e459
use envsubst
DSharifi Mar 6, 2026
a989b04
make it portable for fish
DSharifi Mar 6, 2026
62efec6
remove section comments
DSharifi Mar 6, 2026
50f27e0
cargo fmt
DSharifi Mar 6, 2026
b5aedee
Have run as standalone function
DSharifi Mar 6, 2026
0636c92
rename to run_mpc_node
DSharifi Mar 6, 2026
599d999
use pathbuf
DSharifi Mar 6, 2026
ffa3497
add todo issue links
DSharifi Mar 6, 2026
0b53d1c
fix pathbuf issue
DSharifi Mar 6, 2026
34515c2
update pytests
DSharifi Mar 6, 2026
ca80bca
fix: test config was overwriting neard config
DSharifi Mar 6, 2026
44b9a0e
reset nearcore change
DSharifi Mar 6, 2026
bc9b2fc
fix yml failure
DSharifi Mar 6, 2026
99084d1
redact secrets
DSharifi Mar 6, 2026
6f90606
fmt
DSharifi Mar 6, 2026
2867315
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 6, 2026
a210ce2
Merge branch '2331-remove-usage-of-env-variables-and-cli-flags-from-m…
DSharifi Mar 6, 2026
79c001d
change to pass forward path instead
DSharifi Mar 6, 2026
3812aa4
fmt
DSharifi Mar 6, 2026
5fa48e5
shear and sort
DSharifi Mar 6, 2026
a5cbac2
make check all fast pass
DSharifi Mar 6, 2026
3138c55
undo nearcore
DSharifi Mar 6, 2026
d8f44a6
undo launcher
DSharifi Mar 6, 2026
2ebb35f
oneshot change to toml
DSharifi Mar 9, 2026
c23fb69
Merge remote-tracking branch 'origin/main' into 2331-remove-usage-of-…
DSharifi Mar 9, 2026
7d5cc09
sort toml declaration
DSharifi Mar 9, 2026
ee45ca9
revert nearcore change
DSharifi Mar 9, 2026
3b4dcbb
pytest, dont incldue None fields
DSharifi Mar 9, 2026
b8dd3ce
Merge remote-tracking branch 'origin/2331-remove-usage-of-env-variabl…
DSharifi Mar 13, 2026
92d5c94
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 13, 2026
7d45c50
remove extra hosts functionality, see #2438
DSharifi Mar 13, 2026
4fcfdc6
use compose tempalte file
DSharifi Mar 13, 2026
eca6da3
create file and forward content in the file
DSharifi Mar 13, 2026
7534392
remove rewrite comment
DSharifi Mar 13, 2026
515d425
use write_all
DSharifi Mar 13, 2026
12d7e47
dont use tempfile for passed config, since it gets dropped
DSharifi Mar 13, 2026
1e7ec24
change to toml and forward toml file
DSharifi Mar 13, 2026
8c5c586
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 13, 2026
e7f69b7
update launcher hash :)
DSharifi Mar 13, 2026
7098969
sort deps
DSharifi Mar 13, 2026
f5d9d5c
chore: add frodo.toml file
DSharifi Mar 15, 2026
1ee4ba4
fix: install openssl
DSharifi Mar 15, 2026
104eaf7
update compose file to use new image and binary with config file acce…
DSharifi Mar 15, 2026
fcc6072
static musl build + reproducibie
DSharifi Mar 15, 2026
6943356
use same pattern for building launcher as node
DSharifi Mar 15, 2026
f120573
remove musl
DSharifi Mar 15, 2026
13f3974
update image for ci
DSharifi Mar 15, 2026
c2f7133
create toml file instead of env
DSharifi Mar 15, 2026
498caf6
change image tags
DSharifi Mar 15, 2026
9199195
update compose file
DSharifi Mar 15, 2026
b2b2cd7
revert image digest change
DSharifi Mar 15, 2026
5113f37
try new image again
DSharifi Mar 15, 2026
bcca994
use docker compose plugin
DSharifi Mar 15, 2026
7c00510
.
DSharifi Mar 15, 2026
ce6289e
include image name in template
DSharifi Mar 15, 2026
4f3f327
use new launcher
DSharifi Mar 15, 2026
717e3fb
try claude's suggestion of image digest
DSharifi Mar 15, 2026
a7c7fed
use manifest digest
DSharifi Mar 15, 2026
4b1b97d
return manifest_digest
DSharifi Mar 15, 2026
4a46c27
try new launcher
DSharifi Mar 15, 2026
6579da8
.
DSharifi Mar 15, 2026
6817d81
revert to manifest digest
DSharifi Mar 15, 2026
e7d97a1
add more logs for docker run
DSharifi Mar 15, 2026
2c906b9
run with logs
DSharifi Mar 15, 2026
b4f3b65
remove tail for debugiggng
DSharifi Mar 15, 2026
bfc7d94
add docker compose plugin
DSharifi Mar 15, 2026
940bd50
download docker-compose
DSharifi Mar 15, 2026
2e5201f
.
DSharifi Mar 15, 2026
793b940
add mpc-node invokation in the command
DSharifi Mar 15, 2026
f8daedd
update launcher again
DSharifi Mar 15, 2026
2744500
use tmp path for config path
DSharifi Mar 15, 2026
9a902d0
update launcher
DSharifi Mar 15, 2026
efc2cbb
update to write file not directory
DSharifi Mar 15, 2026
05031a0
update launcher yet again
DSharifi Mar 15, 2026
c804640
fix docker in docker issue for path
DSharifi Mar 15, 2026
220c5b3
update launcher
DSharifi Mar 15, 2026
2122c29
remove head for logs
DSharifi Mar 15, 2026
e796d29
add names for the shared volumes
DSharifi Mar 15, 2026
2140318
.
DSharifi Mar 15, 2026
fc09fee
add near init config
DSharifi Mar 15, 2026
140ba52
add near_init
DSharifi Mar 15, 2026
6b7645a
update mpc image
DSharifi Mar 15, 2026
bf1e972
.
DSharifi Mar 15, 2026
2ff4645
add more logs
DSharifi Mar 15, 2026
b264cb6
incraese resoruces
DSharifi Mar 15, 2026
ecd88a0
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 17, 2026
a076a09
update launcher image and default mpc digest
DSharifi Mar 17, 2026
1643c6e
update nontee yaml
DSharifi Mar 17, 2026
6d16646
.
DSharifi Mar 17, 2026
db0e20e
retrigger ci
DSharifi Mar 17, 2026
b4a67b4
use the image id
DSharifi Mar 17, 2026
4688f25
update image tags in user config
DSharifi Mar 17, 2026
aea06b5
add check that near_init is set
DSharifi Mar 17, 2026
24bf743
added missing near_init fields
DSharifi Mar 17, 2026
fcfb62e
remove duplicate snapshots
DSharifi Mar 17, 2026
e61d8f9
add readme.md
DSharifi Mar 17, 2026
d7ba5f8
added readme
DSharifi Mar 17, 2026
67bfc46
Merge branch 'main' into 2262-port-node-launcher-to-rust-v2
DSharifi Mar 17, 2026
9f96eb8
delete conf files
DSharifi Mar 17, 2026
1bc4f85
ude toml files for testnet
DSharifi Mar 17, 2026
67ed302
remove OOM comment
DSharifi Mar 17, 2026
62b31a6
no pub in tee-launcher
DSharifi Mar 17, 2026
8ccfccb
add issues to todos
DSharifi Mar 17, 2026
9109c58
remove spacing in comment
DSharifi Mar 17, 2026
2dae82e
inline portmappngs
DSharifi Mar 17, 2026
820cab0
use host/container
DSharifi Mar 17, 2026
faba6a2
use httpmock to test get_manifest_digest
DSharifi Mar 17, 2026
21dea25
use dockerregistry trait
DSharifi Mar 17, 2026
e4e5445
use image_id to be explicit
DSharifi Mar 17, 2026
13237ee
feature gate it to linux
DSharifi Mar 17, 2026
a10b829
delete launcher/ folder and move out files that are still relevant
DSharifi Mar 17, 2026
58b2d4c
add rw to allow launcher to create config file
DSharifi Mar 17, 2026
6e66e17
explicit false write open option
DSharifi Mar 17, 2026
949d3b5
remove tee-launcher tests
DSharifi Mar 17, 2026
353572e
fix path to launcher docker compose
DSharifi Mar 17, 2026
dbfb3b3
use relative path of the git reo
DSharifi Mar 17, 2026
09d5271
update launcher hash to current branch
DSharifi Mar 17, 2026
e4f44aa
add docs/UPDATING_LAUNCHER.md to exempt kebab case
DSharifi Mar 17, 2026
88564ae
update paths to docs launcher
DSharifi Mar 17, 2026
4a60f4c
fix broken links
DSharifi Mar 17, 2026
baf1e16
update script
DSharifi Mar 17, 2026
96c21c8
add rw for nontee as well
DSharifi Mar 17, 2026
e199a96
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 17, 2026
88ec98a
launcher intercepts tee authority config
DSharifi Mar 18, 2026
6d11ede
also intercept teeconfig
DSharifi Mar 18, 2026
0bcaff9
test interception of configs
DSharifi Mar 18, 2026
3232e15
wip logging
DSharifi Mar 18, 2026
90fd701
use initlogging in tests
DSharifi Mar 18, 2026
25f933f
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 18, 2026
71032e3
Merge remote-tracking branch 'origin/main' into 2262-port-node-launch…
DSharifi Mar 19, 2026
9f26a38
fix remaining tests
DSharifi Mar 19, 2026
52f7edb
update digests
DSharifi Mar 19, 2026
5f8647f
update toml tiles
DSharifi Mar 19, 2026
b67c455
fix user config
DSharifi Mar 19, 2026
6bd0ba9
update image tags
DSharifi Mar 19, 2026
43a0fc1
.
DSharifi Mar 19, 2026
98653e6
Merge branch 'main' into 2262-port-node-launcher-to-rust-v2
DSharifi Mar 19, 2026
2c4f2a0
update localnet scripts to generate TOML config for Rust launcher
barakeinav1 Mar 15, 2026
0b9c462
add near_init section to TOML template
barakeinav1 Mar 16, 2026
971a9d6
update test-utils attestation assets from localnet run
barakeinav1 Mar 19, 2026
f1f35f5
update VALID_ATTESTATION_TIMESTAMP
barakeinav1 Mar 19, 2026
c6451a7
Revert "add near_init section to TOML template"
barakeinav1 Mar 19, 2026
61cdfd0
Revert "update localnet scripts to generate TOML config for Rust laun…
barakeinav1 Mar 19, 2026
9e1f555
update localnet deploy scripts for Rust launcher and new contract votes
barakeinav1 Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 19 additions & 35 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:

launcher-nontee-check:
name: "MPC Launcher non-tee check"
runs-on: warp-ubuntu-2404-x64-2x
runs-on: warp-ubuntu-2404-x64-8x
timeout-minutes: 60
permissions:
contents: read
Expand All @@ -67,7 +67,7 @@ jobs:

docker-launcher-build-and-verify:
name: "Build MPC Launcher Docker image and verify"
runs-on: warp-ubuntu-2404-x64-2x
runs-on: warp-ubuntu-2404-x64-8x
timeout-minutes: 60
permissions:
contents: read
Expand All @@ -78,10 +78,25 @@ jobs:
with:
persist-credentials: false

- name: Install skopeo
- name: Allow unprivileged user namespaces (needed by repro-env/podman on Ubuntu 24.04)
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y skopeo
sudo apt-get install -y skopeo liblzma-dev podman

- name: Install repro-env
run: |
wget 'https://github.com/kpcyrd/repro-env/releases/download/v0.4.3/repro-env'
echo '2a00b21ac5e990e0c6a0ccbf3b91e34a073660d1f4553b5f3cda2b09cc4d4d8a repro-env' | sha256sum -c -
sudo install -m755 repro-env -t /usr/bin

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
cache-provider: "warpbuild"

- name: Build launcher docker image and verify its hash
shell: bash
Expand Down Expand Up @@ -383,37 +398,6 @@ jobs:
target/wasm32-unknown-unknown/release-contract/test_parallel_contract.wasm
libs/nearcore/target/release/neard

tee-launcher-tests:
name: "TEE Launcher: pytests"
runs-on: warp-ubuntu-2404-x64-2x
timeout-minutes: 60
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
with:
persist-credentials: false

- name: Setup python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.11"

- name: Setup virtualenv
run: |
python3 -m venv tee_launcher/venv
source tee_launcher/venv/bin/activate
cd tee_launcher
pip install -r requirements.txt

- name: Run pytest
run: |
source tee_launcher/venv/bin/activate
cd tee_launcher
PYTHONPATH=. pytest -vsx

fast-ci-checks:
name: "Fast CI checks"
runs-on: warp-ubuntu-2404-x64-8x
Expand Down
27 changes: 21 additions & 6 deletions .github/workflows/docker_build_launcher.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
jobs:
build-and-push-images:
name: "Build and push Docker launcher image with commit hash"
runs-on: warp-ubuntu-2404-x64-2x
runs-on: warp-ubuntu-2404-x64-8x
permissions:
contents: read

Expand All @@ -23,17 +23,32 @@ jobs:
with:
persist-credentials: false

- name: Allow unprivileged user namespaces (needed by repro-env/podman on Ubuntu 24.04)
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y skopeo liblzma-dev podman

- name: Install repro-env
run: |
wget 'https://github.com/kpcyrd/repro-env/releases/download/v0.4.3/repro-env'
echo '2a00b21ac5e990e0c6a0ccbf3b91e34a073660d1f4553b5f3cda2b09cc4d4d8a repro-env' | sha256sum -c -
sudo install -m755 repro-env -t /usr/bin

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
with:
save-if: ${{ github.ref == 'refs/heads/main' }}
cache-provider: "warpbuild"

- name: Login to Docker Hub
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Install skopeo
run: |
sudo apt-get update
sudo apt-get install -y skopeo

- name: Build and push launcher image
run: |
export LAUNCHER_IMAGE_NAME=mpc-launcher
Expand Down
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ members = [
"crates/node-types",
"crates/primitives",
"crates/tee-authority",
"crates/tee-launcher",
"crates/test-migration-contract",
"crates/test-parallel-contract",
"crates/test-utils",
Expand Down Expand Up @@ -166,7 +167,7 @@ reddsa = { git = "https://github.com/near/reddsa", rev = "c7cd92a55f7399d8d7f8c0
] }
regex = "1.12.3"
# TODO(#2053): upgrading this leads to errors
reqwest = { version = "0.12.28", features = ["multipart", "json"] }
reqwest = { version = "0.12.28", default-features = false, features = ["charset", "http2", "rustls-tls", "multipart", "json"] }
rmp-serde = "1.3.1"
rstest = { version = "0.26.1" }
rustls = { version = "0.23.37", default-features = false, features = ["std"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- /var/run/dstack.sock:/var/run/dstack.sock
- /tapp:/tapp:ro
- shared-volume:/mnt/shared:ro
- shared-volume:/mnt/shared:rw

security_opt:
- no-new-privileges:true
Expand Down
1 change: 1 addition & 0 deletions crates/mpc-attestation/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl Attestation {
.get_single_event(MPC_IMAGE_HASH_EVENT)?
.event_payload;

// TODO(#2478): decode raw bytes
let mpc_image_hash_bytes: Vec<u8> = hex::decode(mpc_image_hash_payload)
.map_err(|err| {
VerificationError::Custom(format!(
Expand Down
37 changes: 37 additions & 0 deletions crates/tee-launcher/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[package]
name = "tee-launcher"
readme = "README.md"
version = { workspace = true }
license = { workspace = true }
edition = { workspace = true }

[[bin]]
name = "tee-launcher"
path = "src/main.rs"

[features]
external-services-tests = []

[dependencies]
backon = { workspace = true }
clap = { workspace = true }
dstack-sdk = { workspace = true }
launcher-interface = { workspace = true }
near-mpc-bounded-collections = { workspace = true }
reqwest = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tempfile = { workspace = true }
thiserror = { workspace = true }
tokio = { workspace = true }
toml = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
url = { workspace = true, features = ["serde"] }

[dev-dependencies]
assert_matches = { workspace = true }
httpmock = { workspace = true }

[lints]
workspace = true
110 changes: 110 additions & 0 deletions crates/tee-launcher/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# TEE Launcher (Rust)

Secure launcher for initializing and attesting a Docker-based MPC node inside a TEE-enabled environment (e.g., Intel TDX via dstack).

Replaces the previous Python launcher (`tee_launcher/launcher.py`).

## What it does

1. Loads a TOML configuration file from `/tapp/user_config`
2. Selects an approved MPC image hash (from on-disk approved list, override, or default)
3. Validates the image by resolving it through the Docker registry and pulling by digest
4. In TEE mode: extends RTMR3 by emitting the image digest to dstack
5. Writes the MPC node config to a shared volume
6. Launches the MPC container via `docker compose up -d`

## CLI Arguments

All arguments are read from environment variables (set via docker-compose `environment`):

| Variable | Required | Description |
|----------|----------|-------------|
| `PLATFORM` | Yes | `TEE` or `NONTEE` |
| `DOCKER_CONTENT_TRUST` | Yes | Must be `1` |
| `DEFAULT_IMAGE_DIGEST` | Yes | Fallback `sha256:...` digest when the approved-hashes file is absent |

## Configuration (TOML)

The launcher reads its configuration from `/tapp/user_config` as a TOML file. This is a change from the previous Python launcher which used a `.env`-style file.

```toml
[launcher_config]
image_tags = ["latest"]
image_name = "nearone/mpc-node"
registry = "registry.hub.docker.com"
rpc_request_timeout_secs = 10
rpc_request_interval_secs = 1
rpc_max_attempts = 20
# Optional: force selection of a specific digest (must be in approved list)
# mpc_hash_override = "sha256:abcd..."
port_mappings = [
{ host = 11780, container = 11780 },
{ host = 2200, container = 2200 },
]

# Opaque MPC node configuration.
# The launcher does not interpret these fields — they are re-serialized
# to TOML and mounted into the container at /mnt/shared/mpc-config.toml
# for the MPC binary to consume via `start-with-config-file`.
[mpc_config]
# ... any fields the MPC node expects
```

### `[launcher_config]`

| Field | Default | Description |
|-------|---------|-------------|
| `image_tags` | `["latest"]` | Comma-separated Docker image tags to search |
| `image_name` | `nearone/mpc-node` | Docker image name |
| `registry` | `registry.hub.docker.com` | Docker registry hostname |
| `rpc_request_timeout_secs` | `10` | Per-request timeout for registry API calls |
| `rpc_request_interval_secs` | `1` | Initial retry interval for registry API calls |
| `rpc_max_attempts` | `20` | Maximum registry API retry attempts |
| `mpc_hash_override` | (none) | Optional: force a specific `sha256:` digest (must appear in approved list) |

| `port_mappings` | `[]` | Port mappings forwarded to the MPC container (`{ host, container }` pairs) |

### `[mpc_config]`

Arbitrary TOML table passed through to the MPC node. The launcher writes this verbatim to `/mnt/shared/mpc-config.toml`, which the container reads on startup.

## Image Hash Selection

Priority order:
1. If the approved hashes file (`/mnt/shared/image-digest.bin`) exists and `mpc_hash_override` is set: use the override (must be in the approved list)
2. If the approved hashes file exists: use the newest approved hash (first in list)
3. If the file is absent: fall back to `DEFAULT_IMAGE_DIGEST`

## File Locations

| Path | Description |
|------|-------------|
| `/tapp/user_config` | TOML configuration file |
| `/mnt/shared/image-digest.bin` | JSON file with approved image hashes (written by the MPC node) |
| `/mnt/shared/mpc-config.toml` | MPC node config (written by the launcher) |
| `/var/run/dstack.sock` | dstack unix socket (TEE mode only) |

## Key Differences from the Python Launcher

| Aspect | Python (`launcher.py`) | Rust (`tee-launcher`) |
|--------|----------------------|----------------------|
| Config format | `.env` key-value file | TOML |
| MPC node config | Environment variables passed to container | TOML file mounted into container |
| Container launch | `docker run` with flags | `docker compose up -d` with rendered template |
| RTMR3 extension | `curl` to unix socket | `dstack-sdk` native client |

## Building

```bash
cargo build -p tee-launcher --release
```

## Testing

```bash
# Unit tests
cargo nextest run -p tee-launcher

# Integration tests (requires network access and Docker Hub)
cargo nextest run -p tee-launcher --features integration-test
```
21 changes: 21 additions & 0 deletions crates/tee-launcher/mpc-node-docker-compose.tee.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
mpc-node:
image: "{{IMAGE_NAME}}@{{IMAGE}}"
container_name: "{{CONTAINER_NAME}}"
security_opt:
- no-new-privileges:true
ports: {{PORTS}}
environment:
- "DSTACK_ENDPOINT={{DSTACK_UNIX_SOCKET}}"
volumes:
- /tapp:/tapp:ro
- shared-volume:/mnt/shared
- mpc-data:/data
- "{{DSTACK_UNIX_SOCKET}}:{{DSTACK_UNIX_SOCKET}}"
command: ["/app/mpc-node", "start-with-config-file", "{{MPC_CONFIG_SHARED_PATH}}"]

volumes:
shared-volume:
name: shared-volume
mpc-data:
name: mpc-data
18 changes: 18 additions & 0 deletions crates/tee-launcher/mpc-node-docker-compose.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
services:
mpc-node:
image: "{{IMAGE_NAME}}@{{IMAGE}}"
container_name: "{{CONTAINER_NAME}}"
security_opt:
- no-new-privileges:true
ports: {{PORTS}}
volumes:
- /tapp:/tapp:ro
- shared-volume:/mnt/shared
- mpc-data:/data
command: ["/app/mpc-node", "start-with-config-file", "{{MPC_CONFIG_SHARED_PATH}}"]

volumes:
shared-volume:
name: shared-volume
mpc-data:
name: mpc-data
8 changes: 8 additions & 0 deletions crates/tee-launcher/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
pub(crate) const MPC_CONTAINER_NAME: &str = "mpc-node";
pub(crate) const IMAGE_DIGEST_FILE: &str = "/mnt/shared/image-digest.bin";
pub(crate) const DSTACK_UNIX_SOCKET: &str = "/var/run/dstack.sock";
pub(crate) const DSTACK_USER_CONFIG_FILE: &str = "/tapp/user_config";

/// Path on the shared volume where the launcher writes the MPC config and the
/// MPC container reads it. Both containers mount `shared-volume` at `/mnt/shared`.
pub(crate) const MPC_CONFIG_SHARED_PATH: &str = "/mnt/shared/mpc-config.toml";
Loading
Loading