Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.memwal.ai/llms.txt

Use this file to discover all available pages before exploring further.

Run the MemWal relayer with a TEE deployment pattern when you want the default SDK flow without giving the host operator direct access to plaintext memory payloads. The goal is a tamper-resistant, hardware-attested deployment: incoming memories may still be plaintext at the relayer API boundary, but the relayer processes them inside a TEE and sends SEAL-encrypted ciphertext out to Walrus. This pattern keeps the existing relayer behavior: clients send plaintext to the relayer, the relayer embeds and SEAL-encrypts it, encrypted blobs go to Walrus, and PostgreSQL stores searchable vector metadata. The difference is that the plaintext boundary moves from a normal host process into the enclave.
This is a deployment pattern, not a separate relayer implementation. Validate the manifest fields against the Nautilus version you deploy with, and use the reference files in services/server/deploy/nautilus as the MemWal-specific starting point.
This template is not a complete Sui Nautilus application by itself. A full Nautilus integration also needs enclave attestation or measurement verification and, when required by your trust model, Move-side verification of the TEE output or registered enclave identity.

What This Provides

LayerStatus
Relayer runtimeUses the existing Rust relayer and TypeScript sidecar
TEE-oriented imageProvides a wrapper Containerfile and entrypoint checks
Runtime configProvides a manifest example and secret/env template
Local smoke testVerifies Docker image boot, sidecar readiness, /health, and /metrics
Nautilus deploymentRequires your Nautilus CLI/platform to build and run the enclave image
Attestation verificationMust be wired through your Nautilus/Sui verification path before clients rely on it

Architecture Flow

Write path:
  1. Client sends plaintext to the TEE relayer.
  2. The relayer validates delegate-key auth and generates embeddings inside the enclave.
  3. The sidecar SEAL-encrypts the plaintext inside the enclave.
  4. The sidecar uploads only SEAL ciphertext to Walrus.
  5. PostgreSQL stores owner, namespace, blob_id, blob size, and pgvector embeddings.
Recall path:
  1. Client sends a plaintext query to the TEE relayer.
  2. The relayer embeds the query and searches pgvector by owner + namespace.
  3. The sidecar downloads matching ciphertext blobs from Walrus and SEAL-decrypts inside the enclave.
  4. The relayer returns plaintext matches to the authenticated client.

Reference Template

Template files:
FilePurpose
services/server/deploy/nautilus/README.mdOperator checklist and file map
services/server/deploy/nautilus/ContainerfileTEE wrapper image that adds the runtime entrypoint
services/server/deploy/nautilus/MakefileLocal build, run, and health-smoke helpers
services/server/deploy/nautilus/run.shRuntime entrypoint with required-env validation
services/server/deploy/nautilus/host-forwarder.shOptional host-side VSOCK bridge helper for Nitro-style deployments
services/server/deploy/nautilus/nautilus.toml.exampleReference Nautilus manifest values for this service
services/server/deploy/nautilus/runtime.env.exampleRuntime environment and secret mapping
Copy the template before editing:
cp services/server/deploy/nautilus/nautilus.toml.example .nautilus.toml
cp services/server/deploy/nautilus/runtime.env.example .env.nautilus
Then replace placeholder values and wire .env.nautilus into your Nautilus or CI secret mechanism. Do not bake secrets into the enclave image. Build the reference image from the repo root:
make -C services/server/deploy/nautilus build
That target first builds the existing services/server/Dockerfile runtime image, then builds the TEE wrapper image from Containerfile. Use Nautilus to build and deploy the enclave image from that payload, then pin the image measurement or attestation identity produced by the deployment. The exact build/publish/run commands are Nautilus-version specific; the MemWal requirements are the runtime variables and external endpoints listed below. For a local container smoke test with a filled env file:
make -C services/server/deploy/nautilus run-local ENV_FILE=.env.nautilus
make -C services/server/deploy/nautilus smoke RELAYER_URL=http://127.0.0.1:8000
Local Docker smoke tests only prove that the image and relayer entrypoint boot. They do not prove the process is running inside a TEE and do not produce a Nautilus attestation or onchain verification result.

Required Runtime Variables

These map directly to the existing self-hosted relayer config.
VariableSecretNotes
DATABASE_URLyesPostgreSQL connection string. pgvector must exist before boot
REDIS_URLyesRequired for rate limits and Redis-backed caches
MEMWAL_PACKAGE_IDnoMemWal package used for SEAL policy and blob metadata
MEMWAL_REGISTRY_IDnoAccount registry object ID
SUI_NETWORKnomainnet or testnet
SUI_RPC_URLnoSui fullnode endpoint reachable from the enclave
SERVER_SUI_PRIVATE_KEYyesPrimary server key for SEAL decrypt authorization
SERVER_SUI_PRIVATE_KEYSyesOptional upload key pool; takes priority for Walrus uploads
SEAL_SERVER_CONFIGS or SEAL_KEY_SERVERSmaybeOptional SEAL override. Defaults use the Mysten testnet committee aggregator where available; use SEAL_SERVER_CONFIGS for custom committees
OPENAI_API_KEYyesEmbedding and LLM provider key
OPENAI_API_BASEnoOpenAI-compatible base URL
WALRUS_PUBLISHER_URLnoWalrus upload endpoint
WALRUS_AGGREGATOR_URLnoWalrus download endpoint
WALRUS_UPLOAD_RELAY_URLnoUpload relay override if required by the sidecar
PORTnoRelayer HTTP port; default 8000
SIDECAR_URLnoKeep inside the enclave, usually http://127.0.0.1:9000
SIDECAR_AUTH_TOKENyesShared secret for Rust-to-sidecar calls; sidecar refuses to start without it
LOG_FORMATnoSet json for production logs
ALLOWED_ORIGINSnoBrowser CORS allowlist
Keep BENCHMARK_MODE unset or false in TEE deployments. Benchmark mode stores plaintext in PostgreSQL and bypasses SEAL/Walrus storage.

External Endpoints

The enclave must be allowed to reach:
  • PostgreSQL
  • Redis
  • Sui RPC
  • Walrus publisher
  • Walrus aggregator
  • Walrus upload relay, if configured
  • SEAL key servers or committee aggregators. On testnet, the built-in default is Mysten’s initial committee aggregator. Mainnet uses the legacy independent key server default until an official committee aggregator is available.
  • OpenAI-compatible embedding and LLM provider
If your Nautilus deployment requires an explicit outbound allowlist, mirror the values from runtime.env.example. Prefer private networking for PostgreSQL and Redis. Public AI, Sui, Walrus, and SEAL endpoints should still be egress-limited to exact hosts. For Nitro-style deployments that require explicit host-side VSOCK bridges, host-forwarder.sh can expose the relayer on the host and forward configured external endpoints from the enclave to TCP services. It reads the same runtime env file and only starts optional outbound proxies when the matching *_PROXY_VSOCK_PORT variables are set.

Nautilus Completion Checklist

To turn this template into a complete Nautilus deployment, the operator still needs to perform the platform-specific steps for the Nautilus version in use:
  1. Generate or adapt the Nautilus manifest using nautilus.toml.example as the MemWal-specific input.
  2. Build the enclave artifact with the installed Nautilus toolchain or CI workflow.
  3. Deploy the enclave artifact to the target TEE host or Nautilus provider.
  4. Record the enclave measurement, PCRs, or attestation identity produced by that build.
  5. Register or publish the expected identity through the Nautilus/Sui verification path used by the deployment.
  6. Require clients, gateway policy, or Move-side verification to check that identity before trusting the endpoint as a Nautilus deployment.

Secrets Handling

  • Inject secrets at runtime through Nautilus/CI secrets, not through Docker build args.
  • Keep SERVER_SUI_PRIVATE_KEY, SERVER_SUI_PRIVATE_KEYS, SIDECAR_AUTH_TOKEN, DATABASE_URL, REDIS_URL, OPENAI_API_KEY, ENOKI_API_KEY, and SEAL API keys out of git.
  • Restrict host access to the runtime env file and any Nautilus secret store.
  • Disable debug consoles and broad shell access on production enclave hosts.
  • Rotate the server wallet keys if the host-side secret delivery path is exposed.

Operational Verification

After any local or TEE deployment, check the public health endpoint:
curl "$TEE_RELAYER_URL/health"
Check metrics if your ingress exposes them to trusted operators:
curl "$TEE_RELAYER_URL/metrics"
For Nautilus/TEE deployments, also verify the platform-specific attestation or measurement output. The local Docker smoke test does not cover this step. Run a remember/recall smoke test through the TEE endpoint:
TEE_RELAYER_URL=https://tee-relayer.example.com \
MEMWAL_DELEGATE_KEY=... \
MEMWAL_ACCOUNT_ID=0x... \
pnpm dlx tsx <<'TS'
import { MemWal } from "@mysten-incubation/memwal";

const namespace = `tee-smoke-${Date.now()}`;
const memwal = MemWal.create({
  key: process.env.MEMWAL_DELEGATE_KEY!,
  accountId: process.env.MEMWAL_ACCOUNT_ID!,
  serverUrl: process.env.TEE_RELAYER_URL!,
  namespace,
});

await memwal.health();
const memory = `TEE smoke memory ${new Date().toISOString()}`;
const job = await memwal.remember(memory);
await memwal.waitForRememberJob(job.job_id);
const recall = await memwal.recall("What smoke memory was stored?", 5);

if (!recall.results.some((item) => item.text.includes("TEE smoke memory"))) {
  throw new Error("TEE remember/recall smoke test failed");
}

console.log({ namespace, job_id: job.job_id, recalled: recall.results.length });
TS
Inspect logs for:
  • Rust relayer startup: sidecar readiness, PostgreSQL connection, Redis connection, Walrus endpoints, and WalrusSealEngine.
  • TypeScript sidecar startup and /health.
  • SEAL encrypt/decrypt errors.
  • Walrus upload/download errors.
  • Sui RPC or account-resolution errors.
  • Rate-limit fallback logs, which indicate Redis trouble.
Logs should contain request IDs, route labels, lengths, and error classes. They should not contain memory text, recall queries, prompts, delegate keys, or database URLs.

Failure Modes

SymptomLikely CauseCheck
/health failsRelayer process, sidecar boot, or ingress issueEnclave process logs and sidecar readiness logs
remember stays runningWalrus upload, wallet signing, or job queue failureremember_jobs, Apalis job rows, sidecar Walrus logs
recall returns empty after smoke writeWrong namespace/account, pgvector issue, or upload job incompletePoll remember job, verify owner + namespace, check PostgreSQL migrations
SEAL decrypt failsWrong server wallet, delegate auth, SEAL config, key server outage, or committee aggregator outageSEAL_SERVER_CONFIGS, SERVER_SUI_PRIVATE_KEY, key server or aggregator reachability
Embedding calls failAI endpoint blocked or invalid API keyOPENAI_API_BASE, OPENAI_API_KEY, outbound allowlist
TLS/cert errors to DB or RedisHost rewrite/proxy broke hostname validationPreserve original hostnames when proxying TLS endpoints
Plaintext appears in logsLogging hygiene regression or debug middlewareDisable debug logs and scrub host/enclave log sinks

Security Considerations

TEE deployment reduces trust in the relayer host, but it does not make the default SDK path end-to-end encrypted. Nautilus adds value only when the attested enclave identity is verified by clients, gateway policy, or onchain logic before the endpoint is trusted.
  • Plaintext exists inside the enclave while handling remember, recall, analyze, ask, and restore.
  • SEAL encryption begins inside the sidecar before Walrus upload. Walrus should only receive encrypted bytes.
  • Treat the enclave as tamper-resistant, not magically tamper-proof. Attestation and measurement pinning are what let clients distinguish the intended TEE image from a normal host process.
  • PostgreSQL stores vectors and metadata, not production plaintext. Do not enable BENCHMARK_MODE.
  • External embedding and LLM providers may see plaintext unless you run those services inside the enclave or switch to a provider/trust model you accept.
  • TLS should terminate inside the enclave or use an equivalent enclave-protected channel. If a host load balancer terminates TLS before forwarding to the enclave, the host can observe plaintext.
  • The host still controls availability, traffic routing, and endpoint allowlists. TEE protects confidentiality and integrity of code/data inside the enclave, not uptime.
  • Client-side, gateway, or onchain attestation verification is required for the strongest story. Publish the expected Nautilus image measurement and require that verification path to check it. Without verification, users still trust that the advertised endpoint is the enclave deployment.
  • Keep structured logs, metrics labels, traces, and error bodies free of plaintext and secrets.
If you need the relayer to never see plaintext at all, use the manual SDK flow instead of the default relayer-handled path.