This guide walks you through deploying a Morpheus TEE-hardened provider node on SecretVM (SCRT Labs’ confidential VM platform). By the end you’ll have a provider running inside a hardware-secured Intel TDX enclave that consumers can cryptographically verify before sending prompts. Most of the operator work after deploy is graphical: MyProvider against your SecretVM HTTPS URL, plus looking up models on active.mor.org/status. Swagger remains a fallback. For deeper details (cosign verification, RTMR3 recomputation, attestation manifest inspection) see TEE reference. For the trust-chain conceptual picture see TEE overview.

What you’ll need

  • A funded wallet with MOR + ETH on Base Mainnet (or Base Sepolia for testnet).
  • The wallet’s private key — this stays encrypted inside the TEE.
  • An RPC endpoint for Base Mainnet (e.g. wss://base-mainnet.g.alchemy.com/v2/<your_key>).
  • Your AI model backend reachable via a private URL (e.g. http://my-model:8080/v1/chat/completions).
  • A SecretVM account at https://secretai.scrtlabs.com — sign up to get an API key.
  • (Recommended) secretvm-cli: sudo npm install --global secretvm-cli.
  • (Recommended) MyProvider for registration and bidding after the VM is healthy.

Step 0: Pick the model you will serve

Before minting anything on chain, see what already exists and at what price:
  • If a matching model Id already exists and (for TEE) it carries a tee tag — plan to bid on that Id and put it in MODELS_CONFIG_CONTENT below.
  • If you need TEE and no suitable tee-tagged model exists — you will register a new model with tag tee after deploy (Step 5).
  • Or browse the human UI: active.mor.org/status.
Full decision table: Register on chain → Step 0.

Step 1: Get the Docker Compose file

Each CI/CD build produces a deployed compose file pinning the TEE image by SHA-256 digest — that’s what SecretVM uses to compute RTMR3. Download docker-compose.tee.deployed.yml from the latest GitHub Release — the digest is already filled in. You can also use the template at proxy-router/docker-compose.tee.yml and replace the image tag yourself. The compose includes a Traefik TLS sidecar that uses SecretVM’s auto-generated certs to serve the API on HTTPS port 443. The full compose body is reproduced in TEE reference → Step 1.
Use the digest-pinned version. Tags like :latest are mutable; the digest is not. Using the digest ensures RTMR3 will match the CI/CD-computed golden value.

Step 2: Prepare your secrets

Create a .env file with your 5 provider-specific secrets:
MODELS_CONFIG_CONTENT must be single-line JSON. Schema: models-config.json. If Step 0 already gave you an existing on-chain Id, put that value in modelId now. If you will mint a new tee model after deploy, use a placeholder and replace it via MyProvider Model Configuration Sync (Step 5) before posting a bid you care about.

Step 3: Deploy on SecretVM

  1. Go to https://secretai.scrtlabs.com/secret-vms/create
  2. Docker Compose: paste the contents of your compose file.
  3. Encrypted Secrets: enter your 5 variables.
  4. Advanced features:
SettingRecommendedNotes
PlatformIntel TDXRequired to match CI/CD golden values
Additional FilesEmptyAdding files changes RTMR3
Enable PersistenceOnPreserves data across reboots
Enable UpgradesOnAllows updates without reprovisioning
Hide Runtime InfoOffKeeps the /docker-compose endpoint accessible for verification
  1. Click Deploy.

Step 4: Verify the node is running

Once provisioned (typically 2-3 minutes):
The API is served on HTTPS port 443 via Traefik. Expected:
Verify the attestation endpoint (separate port, direct from SecretVM):
Returns a long hex string — your hardware-signed TDX attestation quote. SecretVM already terminates TLS on port 443, so the hosted GUI at myprovider.mor.org can talk to your node without mixed-content issues.
1

Open MyProvider

Go to myprovider.mor.org. Connect with:
  • URL: https://<your-secretvm-url>/
  • Username / password: from COOKIE_CONTENT (e.g. admin:yourpassword)
2

Register provider

Provider tab → verify the public :3333 endpoint → create provider (min 0.2 MOR stake). Approve Diamond spend if prompted.
3

Bid — prefer an existing model

If Step 0 found a suitable model (including tee when you need TEE): Models & Bids → Available Models → Add Bid using that Id. Set price from the competitor check.
4

Only if needed — create a tee-tagged model

If no suitable tee model exists, use Create Model & Bid and include tag tee (comma-separated tags field). The tee tag is what triggers consumer-side attestation; without it, consumers treat you as a standard provider.
5

Sync models-config

Use Model Configuration Sync to generate updated MODELS_CONFIG_CONTENT, then update SecretVM encrypted secrets and redeploy/restart if the on-chain modelId changed from your Step 2 placeholder. Details: MyProvider GUI.
Swagger fallback: https://<your-secretvm-url>/swagger/index.html — same contract calls as Register on chain.

Step 6: Verify your attestation

Quick check (SecretVM portal)

  1. Go to https://secretai.scrtlabs.com/attestation
  2. Paste your compose file contents.
  3. Enter your VM URL.
  4. Click Verify.
Three layers must pass: hardware (genuine Intel TDX), VM (known SecretVM firmware/kernel), software/RTMR3 (your image + compose match what CI/CD built).

Programmatic check (cosign)

What consumers see, what your P-Node does

The two-hop trust chain — see TEE overview for the full conceptual breakdown.
  • Phase 1 (consumer ↔ your P-Node): the consumer’s proxy-router fetches your :29343/cpu quote, verifies via SecretAI portal, checks TLS binding, compares RTMR3 against the cosign-signed golden values, and re-checks with a ~50 ms fast path on every prompt.
  • Phase 2 (your P-Node ↔ backend): your P-Node fetches the backend’s :29343/cpu, pins TLS, replays workload RTMR3 from :29343/docker-compose, verifies GPU evidence via NVIDIA NRAS, and re-checks per prompt. Per-model state is exposed at GET /v1/models/attestation.
Forward compatibility: a v6.0.0+ C-Node only needs to understand Phase 1; Phase 2 is your P-Node’s job. Any v6+ consumer works with any v7+ provider, gaining Phase 2 transparently.

Troubleshooting

SymptomLikely causeFix
Healthcheck returns nothingVM still provisioningWait 2-3 min, check secretvm-cli vm list
Attestation quote emptyPort 29343 not exposedSecretVM exposes it automatically — check VM status
RTMR3 mismatchWrong compose content or rootfs versionUse the exact deployed compose from CI/CD artifacts (byte-for-byte)
TLS binding failsUsing a proxy/CDN that terminates TLSThe consumer must connect directly — no TLS-terminating intermediaries on :29343
tee model not getting sessionsConsumers on older versionsConsumers need v6.0.0+ for Phase 1
Phase 2 failing silently on consumerPhase 2 runs in your P-NodeCheck GET /v1/models/attestation on your node

Updating your node

The VM reboots with the new image. Verify with /healthcheck and the attestation portal.

Further reading