Skip to content

Commit b102a92

Browse files
committed
feat: support Intel SGX using gramine
1 parent 4c658d7 commit b102a92

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,7 @@ coverage
5454
.eslintcache
5555

5656
agent/content
57+
58+
eliza.manifest
59+
eliza.manifest.sgx
60+
eliza.sig

Makefile

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright (C) 2024 Gramine contributors
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
5+
NODEJS_DIR ?= /usr/bin
6+
7+
ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine)
8+
9+
ifeq ($(DEBUG),1)
10+
GRAMINE_LOG_LEVEL = debug
11+
else
12+
GRAMINE_LOG_LEVEL = error
13+
endif
14+
15+
.PHONY: all
16+
all: eliza.manifest
17+
ifeq ($(SGX),1)
18+
all: eliza.manifest.sgx eliza.sig
19+
endif
20+
21+
.PHONY: eliza.manifest
22+
eliza.manifest: eliza.manifest.template
23+
gramine-manifest \
24+
-Dlog_level=$(GRAMINE_LOG_LEVEL) \
25+
-Darch_libdir=$(ARCH_LIBDIR) \
26+
-Dnodejs_dir=$(NODEJS_DIR) \
27+
$< >$@
28+
29+
# Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`),
30+
# for details on this workaround see
31+
# https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile
32+
eliza.manifest.sgx eliza.sig: sgx_sign
33+
@:
34+
35+
.INTERMEDIATE: sgx_sign
36+
sgx_sign: eliza.manifest
37+
gramine-sgx-sign \
38+
--manifest $< \
39+
--output $<.sgx
40+
41+
ifeq ($(SGX),)
42+
GRAMINE = gramine-direct
43+
else
44+
GRAMINE = gramine-sgx
45+
endif
46+
47+
# Start the default character:
48+
# SGX=1 make start
49+
# Start a specific character by passing arguments:
50+
# SGX=1 make start -- --character "character/your_character_file.json"
51+
.PHONY: start
52+
start: all
53+
$(GRAMINE) ./eliza --loader ts-node/esm src/index.ts --isRoot $(filter-out $@,$(MAKECMDGOALS))
54+
.PHONY: clean
55+
clean:
56+
$(RM) *.manifest *.manifest.sgx *.sig
57+
58+
.PHONY: distclean
59+
distclean: clean

eliza.manifest.template

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright (C) 2024 Gramine contributors
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
4+
# Node.js manifest file example
5+
6+
libos.entrypoint = "{{ nodejs_dir }}/node"
7+
8+
fs.start_dir = "/agent"
9+
10+
loader.log_level = "{{ log_level }}"
11+
12+
loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}"
13+
14+
# Insecure configuration for loading arguments and environment variables
15+
# Do not set these configurations in production
16+
loader.insecure__use_cmdline_argv = true
17+
loader.insecure__use_host_env = true
18+
19+
fs.mounts = [
20+
{ uri = "file:{{ gramine.runtimedir() }}", path = "/lib" },
21+
{ uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" },
22+
{ uri = "file:/usr/{{ arch_libdir }}", path = "/usr/{{ arch_libdir }}" },
23+
{ uri = "file:{{ nodejs_dir }}/node", path = "{{ nodejs_dir }}/node" },
24+
{ type = "tmpfs", path = "/tmp" },
25+
{ type = "tmpfs", path = "/agent/content_cache" },
26+
]
27+
28+
sys.enable_extra_runtime_domain_names_conf = true
29+
sys.fds.limit = 65535
30+
31+
sgx.debug = false
32+
sgx.remote_attestation = "dcap"
33+
sgx.max_threads = 64
34+
35+
# Some dependencies of Eliza utilize WebAssembly (WASM).
36+
# Initializing WASM requires a substantial amount of memory.
37+
# If there is insufficient memory, you may encounter the following error:
38+
# RangeError: WebAssembly.instantiate(): Out of memory: Cannot allocate Wasm memory for a new instance.
39+
# To address this, we set the enclave size to 64GB.
40+
sgx.enclave_size = "64G"
41+
42+
# `use_exinfo = true` is needed because Node.js uses memory mappings with `MAP_NORESERVE`, which
43+
# will defer page accepts to page-fault events when EDMM is enabled
44+
sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
45+
sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
46+
47+
sgx.trusted_files = [
48+
"file:{{ gramine.runtimedir() }}/",
49+
"file:{{ arch_libdir }}/",
50+
"file:/usr/{{ arch_libdir }}/",
51+
"file:{{ nodejs_dir }}/node",
52+
"file:characters/",
53+
"file:agent/src/",
54+
"file:agent/package.json",
55+
"file:agent/tsconfig.json",
56+
"file:package.json",
57+
"file:.env",
58+
59+
# Add these files to sgx.trusted_files in production and remove them from sgx.allowed_files.
60+
# Trusting these files requires a high-performance SGX machine due to the large number of files,
61+
# which could significantly increase startup time.
62+
# To mitigate startup time degradation, we use allowed_files in development.
63+
#
64+
# "file:node_modules/",
65+
# "file:packages/",
66+
# These files are symbolic links to node_modules,
67+
# and Gramine does not support adding symbolic link directories to sgx.trusted_files.
68+
# Therefore, we must add each directory individually to sgx.trusted_files.
69+
# "file:agent/node_modules/@elizaos/adapter-sqlite/",
70+
# "file:agent/node_modules/@elizaos/.../",
71+
]
72+
73+
# Insecure configuration. Use gramine encrypted fs to store data in production.
74+
sgx.allowed_files = [
75+
"file:agent/data/",
76+
"file:agent/model.gguf",
77+
78+
# Move these files to sgx.trusted_files in production.
79+
"file:node_modules/",
80+
"file:packages/",
81+
"file:agent/node_modules/",
82+
]
83+
84+
loader.env.SGX = "1"

0 commit comments

Comments
 (0)