Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement a plugin that can retrieve Marlin TEE remote attestations #935

Merged
merged 3 commits into from
Jan 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ NEAR_NETWORK=testnet # or mainnet
ZKSYNC_ADDRESS=
ZKSYNC_PRIVATE_KEY=

# Marlin
TEE_MARLIN= # Set "yes" to enable the plugin
TEE_MARLIN_ATTESTATION_ENDPOINT= # Optional, default "http://127.0.0.1:1350"

# Ton
TON_PRIVATE_KEY= # Ton Mnemonic Seed Phrase Join With Empty String
TON_RPC_URL= # ton rpc
Expand Down
1 change: 1 addition & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@elizaos/plugin-ton": "workspace:*",
"@elizaos/plugin-sui": "workspace:*",
"@elizaos/plugin-tee": "workspace:*",
"@elizaos/plugin-tee-marlin": "workspace:*",
"@elizaos/plugin-multiversx": "workspace:*",
"@elizaos/plugin-near": "workspace:*",
"@elizaos/plugin-zksync-era": "workspace:*",
Expand Down
2 changes: 2 additions & 0 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { createNodePlugin } from "@elizaos/plugin-node";
import { solanaPlugin } from "@elizaos/plugin-solana";
import { suiPlugin } from "@elizaos/plugin-sui";
import { TEEMode, teePlugin } from "@elizaos/plugin-tee";
import { teeMarlinPlugin } from "@elizaos/plugin-tee-marlin";
import { tonPlugin } from "@elizaos/plugin-ton";
import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era";
import { cronosZkEVMPlugin } from "@elizaos/plugin-cronoszkevm";
Expand Down Expand Up @@ -593,6 +594,7 @@ export async function createAgent(
getSecret(character, "CRONOSZKEVM_PRIVATE_KEY")
? cronosZkEVMPlugin
: null,
getSecret(character, "TEE_MARLIN") ? teeMarlinPlugin : null,
getSecret(character, "TON_PRIVATE_KEY") ? tonPlugin : null,
getSecret(character, "SUI_PRIVATE_KEY") ? suiPlugin : null,
getSecret(character, "STORY_PRIVATE_KEY") ? storyPlugin : null,
Expand Down
100 changes: 99 additions & 1 deletion docs/docs/packages/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,9 @@ console.log("Webhook creation response:", response);
- **Validation**: Always validate input parameters to ensure compliance with expected formats and supported networks.
- **Error Handling**: Monitor logs for errors during webhook creation and adjust retry logic as needed.

### 10. Fuel Plugin (`@elizaos/plugin-fuel`)
---

#### 10. Fuel Plugin (`@elizaos/plugin-fuel`)

The Fuel plugin provides an interface to the Fuel Ignition blockchain.

Expand Down Expand Up @@ -634,6 +636,102 @@ The Fuel plugin provides an interface to the Fuel Ignition blockchain.

- `FUEL_WALLET_PRIVATE_KEY`: Private key for secure transactions

---

#### 11. Marlin TEE Plugin (`@elizaos/plugin-tee-marlin`)

Makes Eliza TEE-aware by using the [Marlin Oyster](https://github.com/marlinprotocol/oyster-monorepo) platform tooling with the goal of making Eliza agents verifiable and private.

**Configuration:**

Add the following to your `.env` file to enable the plugin:
```
TEE_MARLIN=yes
```

**Actions:**

- `REMOTE_ATTESTATION`: Lets Eliza respond with a remote attestation that users can verify. Just ask Eliza for an attestation! E.g. "Attest yourself", "Give me a remote attestation".

**REMOTE_ATTESTATION Configuration:**

The agent fetches the remote attestation from an attestation server whose URL can be configured in the `.env` file:
```
# Optional, default is http://127.0.0.1:1350
TEE_MARLIN_ATTESTATION_ENDPOINT="http://127.0.0.1:1350"
```

**REMOTE_ATTESTATION Usage:**

Just ask Eliza for a remote attestation!

```
You: attest yourself
◎ LOGS
Creating Memory
9d211ea6-a28d-00f9-9f9d-edb290984734
attest yourself

["◎ Generating message response.."]

["◎ Generating text..."]

ℹ INFORMATIONS
Generating text with options:
{"modelProvider":"anthropic","model":"small"}

ℹ INFORMATIONS
Selected model:
claude-3-haiku-20240307

◎ LOGS
Creating Memory

Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started.

◎ LOGS
Evaluating
GET_FACTS

◎ LOGS
Evaluating
UPDATE_GOAL

["✓ Normalized action: remoteattestation"]

["ℹ Executing handler for action: REMOTE_ATTESTATION"]

["◎ Agent: Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started."]

["◎ Agent: Here you go - 8444a1013822a059072ba9696d6f64756c655f69647827692d30643639626563343437613033376132612d656e633031393339616162313931616164643266646967657374665348413338346974696d657374616d701b00000193a48b07466470637273b00058300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158300101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010258300202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020358300303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030458300404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040558300505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050658300606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060758300707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070858300808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080958300909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090a58300a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b58300b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c58300c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d58300d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e58300e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f58300f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f6b63657274696669636174655901d2308201ce30820153a0030201020211009935f9942d285aa30828cabeb617806f300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532355a300f310d300b060355040313046c6561663076301006072a8648ce3d020106052b8104002203620004869282968b06cf61b9c30c3bbfa176725cae0634e8c052536f1aacff52f3703087f1a8246f7036b1bfe26379a350434f3b409090bfef6e951cd1ce41828954bf4b5b0cc6266e3c0863f015384272d990ff4a18af353f884500a4adb37f1cc411a371306f300e0603551d0f0101ff0404030203b8301d0603551d250416301406082b0601050507030106082b06010505070302301d0603551d0e041604149af6c17c9ae3d807b3596b0b05db7b30764ae11b301f0603551d2304183016801403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030369003066023100b1eac6ba5d6207e4cfc38336be2a8760a4154c5693b24689ec585291573fecdab2d9cb354de88895c25a470925c838d9023100f0c0ec3a4407ce81768c07d9288585bcf84f26f557555a8be7e8edb4826a4ed0f258708b4250a84cb5fab4ff7214098e68636162756e646c65815901943082019030820117a003020102020101300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532365a300f310d300b06035504031304726f6f743076301006072a8648ce3d020106052b81040022036200046c79411ebaae7489a4e8355545c0346784b31df5d08cb1f7c0097836a82f67240f2a7201862880a1d09a0bb326637188fbbafab47a10abe3630fcf8c18d35d96532184985e582c0dce3dace8441f37b9cc9211dff935baae69e4872cc3494410a3453043300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100301d0603551d0e0416041403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030367003064023034d6ba1fc45688510f92612bdb7fb1b0228872e8a78485ece2471a390e0185ab235c27892d4c35a952dcb3e5c641dabf023022b6d4c766800b7d3f9cc0129fc08bf687f8687b88a107eacbad7a7b49f6be1f73f801dd69f858376353d60f3443da9d6a7075626c69635f6b6579f669757365725f64617461f6656e6f6e6365f658600bbafbc2fd273b3aebb8c31062391eff1e32ec67e91cb0d1ce4398545beb8d665d18711e91c52e045551a6ba2a0c9971aa6c2a7a0640c0cd2a00c0c9ba9c24de5d748669e8d7fea9d9d646055e054c537531d3ad1b8dbc592e18a70121777e62"]
```

**Mock attestation server:**

For local development and testing, you can use a [mock attestation server](https://github.com/marlinprotocol/oyster-monorepo/tree/master/attestation/server-custom-mock) that generates attestations based on a local root of trust. See the linked README for more detailed information.

**From source:**

Requires Rust to be installed.

```
git clone https://github.com/marlinprotocol/oyster-monorepo
cd oyster-monorepo/attestation/server-custom-mock

# Listens on 127.0.0.1:1350 by default
cargo run

# To customize listening interface and port
cargo run --ip-addr <ip>:<port>
```

**Using Docker:**

```
# The server runs on 1350 inside Docker, can remap to any interface and port
docker run --init -p 127.0.0.1:1350:1350 marlinorg/attestation-server-custom-mock
```

### Writing Custom Plugins

Create a new plugin by implementing the Plugin interface:
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-tee-marlin/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
95 changes: 95 additions & 0 deletions packages/plugin-tee-marlin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Marlin TEE Plugin

A plugin for making agents on Eliza verifiable through the use of Trusted Execution Environments (TEEs). The plugin leverages the [Marlin Oyster](https://docs.marlin.org/user-guides/oyster/) platform and [SDKs](https://github.com/marlinprotocol/oyster-monorepo).

## Configuration

Add the following to your `.env` file to enable the plugin:
```
TEE_MARLIN=yes
```

## Actions

### REMOTE_ATTESTATION

The `REMOTE_ATTESTATION` action fetches a remote attestation from an attestation server which allows the user to verify if an agent is running inside a TEE environment.

#### Configuration

The agent fetches the remote attestation from an attestation server whose URL can be configured in the `.env` file:
```
# Optional, default is http://127.0.0.1:1350
TEE_MARLIN_ATTESTATION_ENDPOINT="http://127.0.0.1:1350"
```

#### Usage

Just ask Eliza for a remote attestation!

```
You: attest yourself
◎ LOGS
Creating Memory
9d211ea6-a28d-00f9-9f9d-edb290984734
attest yourself

["◎ Generating message response.."]

["◎ Generating text..."]

ℹ INFORMATIONS
Generating text with options:
{"modelProvider":"anthropic","model":"small"}

ℹ INFORMATIONS
Selected model:
claude-3-haiku-20240307

◎ LOGS
Creating Memory

Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started.

◎ LOGS
Evaluating
GET_FACTS

◎ LOGS
Evaluating
UPDATE_GOAL

["✓ Normalized action: remoteattestation"]

["ℹ Executing handler for action: REMOTE_ATTESTATION"]

["◎ Agent: Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started."]

["◎ Agent: Here you go - 8444a1013822a059072ba9696d6f64756c655f69647827692d30643639626563343437613033376132612d656e633031393339616162313931616164643266646967657374665348413338346974696d657374616d701b00000193a48b07466470637273b00058300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158300101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010258300202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020358300303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030458300404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040558300505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050658300606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060758300707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070858300808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080958300909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090a58300a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b58300b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c58300c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d58300d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e58300e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f58300f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f6b63657274696669636174655901d2308201ce30820153a0030201020211009935f9942d285aa30828cabeb617806f300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532355a300f310d300b060355040313046c6561663076301006072a8648ce3d020106052b8104002203620004869282968b06cf61b9c30c3bbfa176725cae0634e8c052536f1aacff52f3703087f1a8246f7036b1bfe26379a350434f3b409090bfef6e951cd1ce41828954bf4b5b0cc6266e3c0863f015384272d990ff4a18af353f884500a4adb37f1cc411a371306f300e0603551d0f0101ff0404030203b8301d0603551d250416301406082b0601050507030106082b06010505070302301d0603551d0e041604149af6c17c9ae3d807b3596b0b05db7b30764ae11b301f0603551d2304183016801403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030369003066023100b1eac6ba5d6207e4cfc38336be2a8760a4154c5693b24689ec585291573fecdab2d9cb354de88895c25a470925c838d9023100f0c0ec3a4407ce81768c07d9288585bcf84f26f557555a8be7e8edb4826a4ed0f258708b4250a84cb5fab4ff7214098e68636162756e646c65815901943082019030820117a003020102020101300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532365a300f310d300b06035504031304726f6f743076301006072a8648ce3d020106052b81040022036200046c79411ebaae7489a4e8355545c0346784b31df5d08cb1f7c0097836a82f67240f2a7201862880a1d09a0bb326637188fbbafab47a10abe3630fcf8c18d35d96532184985e582c0dce3dace8441f37b9cc9211dff935baae69e4872cc3494410a3453043300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100301d0603551d0e0416041403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030367003064023034d6ba1fc45688510f92612bdb7fb1b0228872e8a78485ece2471a390e0185ab235c27892d4c35a952dcb3e5c641dabf023022b6d4c766800b7d3f9cc0129fc08bf687f8687b88a107eacbad7a7b49f6be1f73f801dd69f858376353d60f3443da9d6a7075626c69635f6b6579f669757365725f64617461f6656e6f6e6365f658600bbafbc2fd273b3aebb8c31062391eff1e32ec67e91cb0d1ce4398545beb8d665d18711e91c52e045551a6ba2a0c9971aa6c2a7a0640c0cd2a00c0c9ba9c24de5d748669e8d7fea9d9d646055e054c537531d3ad1b8dbc592e18a70121777e62"]
```

#### Mock attestation server

For local development and testing, you can use a [mock attestation server](https://github.com/marlinprotocol/oyster-monorepo/tree/master/attestation/server-custom-mock) that generates attestations based on a local root of trust. See the linked README for more detailed information.

##### From source

Requires Rust to be installed.

```
git clone https://github.com/marlinprotocol/oyster-monorepo
cd oyster-monorepo/attestation/server-custom-mock

# Listens on 127.0.0.1:1350 by default
cargo run

# To customize listening interface and port
cargo run --ip-addr <ip>:<port>
```

##### Docker

```
# The server runs on 1350 inside Docker, can remap to any interface and port
docker run --init -p 127.0.0.1:1350:1350 marlinorg/attestation-server-custom-mock
```
3 changes: 3 additions & 0 deletions packages/plugin-tee-marlin/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintGlobalConfig from "../../eslint.config.mjs";

export default [...eslintGlobalConfig];
19 changes: 19 additions & 0 deletions packages/plugin-tee-marlin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@elizaos/plugin-tee-marlin",
"version": "0.1.0",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@elizaos/core": "workspace:*",
"tsup": "8.3.5"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"lint": "eslint . --fix"
},
"peerDependencies": {
"whatwg-url": "7.1.0"
}
}
48 changes: 48 additions & 0 deletions packages/plugin-tee-marlin/src/actions/remoteAttestation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";

export const remoteAttestationAction = {
name: "REMOTE_ATTESTATION",
similes: ["REMOTE_ATTESTATION", "TEE_REMOTE_ATTESTATION", "TEE_ATTESTATION"],
description: "Generate a remote attestation to prove that the agent is running in a TEE",
handler: async (
runtime: IAgentRuntime,
message: Memory,
_state: State,
_options: any,
callback: HandlerCallback,
) => {
try {
const endpoint = runtime.getSetting("TEE_MARLIN_ATTESTATION_ENDPOINT") ?? "http://127.0.0.1:1350";
const response = await fetch(`${endpoint}/attestation/hex`);
callback({
text: `Here you go - ${await response.text()}`,
action: "NONE",
});
return true;
} catch (error) {
console.error("Failed to fetch remote attestation: ", error);
return false;
}
},
validate: async (runtime: IAgentRuntime) => {
return true;
},
examples: [
[
{
user: "user",
content: {
text: "Attest yourself",
action: "REMOTE_ATTESTATION",
},
},
{
user: "user",
content: {
text: "Generate a remote attestation",
action: "REMOTE_ATTESTATION",
},
},
],
],
};
21 changes: 21 additions & 0 deletions packages/plugin-tee-marlin/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Plugin } from "@elizaos/core";
import { remoteAttestationAction } from "./actions/remoteAttestation";

export const teeMarlinPlugin: Plugin = {
name: "Marlin TEE Plugin",
description:
"TEE plugin with actions to generate remote attestations",
actions: [
/* custom actions */
remoteAttestationAction,
],
evaluators: [
/* custom evaluators */
],
providers: [
/* custom providers */
],
services: [
/* custom services */
],
};
10 changes: 10 additions & 0 deletions packages/plugin-tee-marlin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../core/tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src"
},
"include": [
"src/**/*.ts"
]
}
19 changes: 19 additions & 0 deletions packages/plugin-tee-marlin/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["src/index.ts"],
outDir: "dist",
sourcemap: true,
clean: true,
format: ["esm"], // Ensure you're targeting CommonJS
external: [
"dotenv", // Externalize dotenv to prevent bundling
"fs", // Externalize fs to use Node.js built-in module
"path", // Externalize other built-ins if necessary
"@reflink/reflink",
"@node-llama-cpp",
"https",
"http",
"agentkeepalive",
],
});
Loading
Loading