# Run Palliora Node on a TEE

This document walks Palliora node operators through running their infrastructure inside a hardware‑backed Trusted Execution Environment (TEE) using Dstack.

The goal is to move from “ordinary Docker deployment” to a setup where every Palliora node runs inside an Intel TDX Confidential VM, with **hardware‑enforced isolation and remotely verifiable attestations**. Instead of trusting a generic cloud VM or Kubernetes cluster, operators will be able to show cryptographic proof that their node—and its configuration—ran in a specific, measured environment.

Dstack acts as the bridge between Palliora’s existing Docker‑based node stack and low‑level TEE features. It lets us:

* Take the standard Palliora `docker-compose.yml`.
* Run it inside a dedicated, attested CVM per deployment.
* Expose the same networking interfaces node operators expect.
* Generate TDX quotes directly from inside the node container for downstream verification.

This guide focuses on three practical outcomes:

1. **Provisioning a TEE‑ready host**\
   Renting an Intel TDX‑capable machine from a cloud provider and preparing it to run confidential workloads.
2. **Running Palliora under Dstack**\
   Installing Dstack’s components on the host, adapting Palliora’s `docker-compose.yml` for this environment, and deploying via Dstack’s UI.
3. **Proving and observing execution**\
   Pulling TDX attestation reports and node logs from inside the TEE, so operators and verifiers can build higher‑level trust tools (e.g., a Palliora trust dashboard) on top.

By the end of this document, Palliora community members should be able to reproducibly launch their own TEE‑protected nodes, without relying on a specific managed cloud, while keeping the operational model as close as possible to “just run Docker Compose.”

***

### 1. What Dstack Is <a href="#id-1-what-dstack-is" id="id-1-what-dstack-is"></a>

Dstack is an SDK and orchestration layer that runs your existing Docker apps inside **Confidential VMs (CVMs)** backed by hardware TEEs (Intel TDX, etc.).

### Core Components

* **dstack‑vmm**\
  Runs on the bare‑metal TDX host. Manages CVMs: creates, boots and stops them. Provides CVM orchestration and monitoring service right out of the box.
* **dstack‑gateway**\
  Reverse proxy on the host. Terminates TLS and routes `https://<id>-<port>.<base_domain>` to services inside CVMs.
* **dstack‑kms**\
  Key Management Service. Generates and seals keys; only unseals them inside attested CVMs, secluded from the host (prevents host/operator access). **Serves key derivation requests** from `dstack-guest-agent` inside running CVMs via RPC.
* **dstack‑guest‑agent**\
  Runs inside each CVM. Handles key derivation, remote attestation, and exposes `/var/run/dstack.sock` so containers can request TDX quotes.&#x20;
* **meta‑dstack (Yocto layer)**\
  Builds the minimal, hardened Linux image that runs inside CVMs and hosts Docker + guest‑agent. This uses the Yokto Linux guest image and provides dedicated memory/resources (secluded from the host) for confidentiality guarantees.

### Key Features

* **Drop‑in for Docker**: Use your existing `docker-compose.yml`, no app code changes.
* **Per‑app CVM isolation**: Each compose app runs in its own TDX CVM with encrypted memory.
* **Remote attestation**: Containers can request TDX quotes via `dstack.sock` and prove they ran in the expected environment.
* **Network ingress out of the box**: Gateway gives you HTTPS endpoints for node RPCs, APIs, etc., without manual nginx.

> See “[Dstack – Getting Started](https://docs.phala.com/dstack/getting-started)” for architecture and concepts.​

***

### 2. Renting an Intel TDX Machine <a href="#id-2-renting-an-intel-tdx-machine" id="id-2-renting-an-intel-tdx-machine"></a>

To self‑host Dstack, you need a VM that supports Intel TDX Confidential VMs (C3‑class or similar) on your cloud provider.

### Typical Requirements

* **Machine family**: Intel Sapphire Rapids with TDX enabled (for example, C3 `c3-standard-*` on some providers).
* **vCPU/RAM**: At least 8 vCPU, 32–64 GB RAM for comfortable Dstack builds and CVMs.
* **Disk**: 200+ GB SSD (Balanced PD/NVMe).
* **OS**: Recent Linux with TDX‑capable kernel (e.g., Ubuntu 24.04 LTS with `TDX_CAPABLE` flag).
* **Security:** Enable Confidential VM service > Intel TDX under security menu.

### Checklist When Creating the Host VM

* Enable **Confidential VM / Intel TDX** in the provider’s UI.
* Use a **TDX‑capable** OS image (check provider docs for “TDX\_CAPABLE” images).
* Ensure firewall/security groups allow:
  * SSH: 22 (admin access)
  * Dstack‑vmm UI: 9080
  * Dstack‑gateway HTTP/HTTPS: 80, 443, and optionally 9070 for the gateway dashboard.\[[docs.phala](https://docs.phala.com/dstack/getting-started)]​

Example firewall rule (conceptually):

```bash
bash# conceptual: open needed ports to your IP or trusted ranges
allow tcp:22,tcp:80,tcp:443,tcp:9070,tcp:9080 to host_ip
```

***

### 3. Installing and running Dstack (vmm, gateway, kms) <a href="#id-3-installing-dstack-vmm-gateway-kms" id="id-3-installing-dstack-vmm-gateway-kms"></a>

On your Intel TDX host VM, follow the[ upstream Dstack- Get started guide](https://docs.phala.com/dstack/getting-started#install-dependencies).

### 3.1 Summary of Dstack setup

```bash
bash# Install build deps (example for Ubuntu)
sudo apt update
sudo apt install -y build-essential chrpath diffstat lz4 wireguard-tools xorriso

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Clone meta-dstack
git clone https://github.com/Dstack-TEE/meta-dstack.git --recursive
cd meta-dstack
mkdir build && cd build

# Generate config template
../build.sh hostcfg
# Edit build-config.sh to match your environment (domain, ports, etc.)
vim ./build-config.sh

# Re-run host build
../build.sh hostcfg
# You should now see artifacts:
ls
# certs images dstack-kms kms.toml run dstack-vmm vmm.toml dstack-gateway gateway.toml
```

You can either **download a prebuilt CVM guest image**:

```bash
../build.sh dl 0.5.2
```

or **build it from source**:

```bash
../build.sh guest
```

### 3.2 Run Core Services

Run three terminals on the host:

```bash
./dstack-kms -c kms.toml
```

```bash
sudo ./dstack-gateway -c gateway.toml
```

```bash
./dstack-vmm -c vmm.toml
```

* `dstack-vmm` UI: `http://<host-ip>:9080`
* `dstack-gateway` dashboard: `https://<host-domain-or-ip>:9070` (if configured)

***

### 4. Preparing Palliora’s docker-compose for Dstack <a href="#id-4-preparing-pallioras-docker-compose-for-dstack" id="id-4-preparing-pallioras-docker-compose-for-dstack"></a>

Palliora’s existing compose uses host‑mounted genesis config and private ECR images. For TDX+Dstack we’ll make it **TEE‑friendly and easy for operators**.

### 4.a Genesis Config from Remote

Instead of mounting a local path like:

```
volumes:
    - "./palliora-manas.json:/root/palliora-manas.json"
```

Publish the Palliora genesis config in a **public Google Drive/GitHub repo/Gist**, then adjust compose to fetch it on container start.

Example pattern:

```
services:
  # New service to fetch the config file
  fetch-config:
    image: alpine:3.19
    volumes:
      - palliora-config-data:/root
    working_dir: /root
    command: wget -O /root/palliora-manas.json "https://drive.google.com/uc?export=download&id=1VX0Ei12kvGU2nnjXlzjMfAd53tVAaF42"
    restart: "no"
    
  palliora-node:
    image: public-registry/palliora-node:latest
    entrypoint: ["/bin/sh", "-c"]
    volumes:
      - palliora-config-data:/root/
volumes:
  palliora-config-data:
```

I've hosted one on Google Drive at <https://drive.google.com/uc?export=download&id=1VX0Ei12kvGU2nnjXlzjMfAd53tVAaF42>

### 4.b Switch to Public Images

To avoid ECR auth complexity for community operators we've pushed Palliora images to a **public registry** on public AWS ECR and reference them directly in compose:

```
services:
  palliora-node:
    image: public.ecr.aws/palliora/palliora/node:latest
```

This removes the need for AWS credentials or ECR login inside TEEs.

### 4.c Mount `/var/run/dstack.sock` for Attestation

To allow the node container to request TDX quotes, mount the Dstack socket as documented.

Example Palliora service snippet:

```
palliora-node:
    image: public.ecr.aws/palliora/palliora/node:latest
    working_dir: /
    volumes:
      - /var/run/dstack.sock:/var/run/dstack.sock
      - palliora-config-data:/root/
```

The `/var/run/dstack.sock` path is provided by the dstack guest‑agent inside the CVM; the mount just passes it into your container.

Here's the compiled changes to Palliora's docker-compose.yml

{% file src="/files/NZqKAxISIo34usmGP8cX" %}

***

### 5. Deploying Palliora via Dstack UI <a href="#id-5-deploying-palliora-via-dstack-ui-no-phala-mentio" id="id-5-deploying-palliora-via-dstack-ui-no-phala-mentio"></a>

For the community doc, describe deployment entirely via the generic Dstack‑vmm UI.

### 5.1 Open Dstack-vmm

Navigate to:

```
http://<your-tdx-host-ip>:9080
```

You’ll see the **dstack‑vmm web interface**.

### 5.2 Upload and Deploy docker-compose

* Click **“Deploy App”** (or equivalent button).
* Paste or upload the Palliora `docker-compose.yml` prepared in section 4.
* (Optional) Configure **Encrypted Environment Variables** if Palliora needs secrets, incase of using private ECR images — they are encrypted client‑side and only decrypted inside the CVM.
* Click **Deploy**.

Dstack will:

1. Create a new TDX CVM.
2. Boot the Yocto guest image with guest‑agent.
3. Pull the public Palliora node image.
4. Start the Palliora containers inside the CVM.

### 5.3 Checking Status

In the vmm UI:

* **Logs**: For CVM boot logs and container startup; use the **\[Logs]** button.
* **Dashboard**: See container status, resource usage, and guest‑agent health.

{% hint style="info" %}
On shutdown, TEE setup will wipe away the ollama and model installations to enable a clean slate boot expected from the TEE. In order to persist it, we need to move the ollama dir into the persistent storage of the TEE.
{% endhint %}

5.4 Palliora Setup

Once you have the Palliora client running, next up is setting up:\
1\. Ollama

2. Installing models
3. Creating a Palliora account
4. Staking
5. Finally joining as a guardian

For the above steps, you can follow our [Becoming a Guardian](/participate/become-a-guardian.md) guide.

***

### 6. Getting TDX Attestations and Logs from the TEE <a href="#id-6-getting-tdx-attestations-and-logs-from-the-tee" id="id-6-getting-tdx-attestations-and-logs-from-the-tee"></a>

Once the Palliora node is running inside the TDX CVM, operators can generate attestation reports and fetch logs programmatically or use the Trust-Centre to verify attestations automatically.

### 6.1 Trust Centre

A comprehensive open-source platform for managing and verifying Trusted Execution Environment (TEE) attestations in the dstack ecosystem. The Trust Center provides end-to-end verification of hardware attestation, OS integrity, source code authenticity, and domain ownership for TEE-protected applications.

Repo: <https://github.com/Phala-Network/trust-center>

\
The following is verified automatically by the Trust Centre client:

* **Verify Hardware Authenticity**: Cryptographically prove your app runs on genuine Intel TDX and Nvidia CC hardware
* **Confirm Code Integrity**: Verify the exact Docker compose configuration deployed matches your source code
* **Validate OS Security**: Ensure the operating system hasn’t been tampered with
* **Prove Zero Trust**: For gateway deployments, verify domain certificates are managed entirely within the TEE

For automated verification of your application’s attestation, see the [Trust Centre Technical Documentation](https://docs.phala.com/dstack/trust-center-technical) which explains how to use these quotes with the Trust Centre verification platform.

### 6.2 Requesting a TDX Quote from the Container

With `/var/run/dstack.sock` mounted, use the documented curl command from inside the Palliora container:

```bash
# inside the palliora-node container
curl -X POST --unix-socket /var/run/dstack.sock \
  -H 'Content-Type: application/json' \
  -d '{
        "reportData": "0x1234deadbeef00000000000000000000000000000000000000000000000000"
      }' \
  http://dstack/GetQuote | jq .
```

Or, with the newer interface

```bash
curl --unix-socket /var/run/dstack.sock \
  "http://localhost/GetQuote?report_data=0x1234deadbeef" | jq .
```

### Code integrity verification

* `reportData` is a **64‑byte app‑defined field** (hex string) that is hashed into the TDX report; Palliora can use it to bind the quote to a particular genesis hash or config version.
* The response JSON contains:
  * The TDX quote (base64)
  * The embedded `report_data`
  * Measurement fields and signatures

***

### Recap

* You rented a TDX‑capable machine.
* Installed and ran Dstack (vmm, gateway, kms).
* Adapted Palliora’s `docker-compose.yml` for Dstack (remote genesis, public images, `dstack.sock` mount).
* Deployed via the Dstack UI.
* Verified attestation through Trust Centre/Retrieved TDX quotes from inside the TEE.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.palliora.org/participate/run-palliora-node-on-a-tee.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
