{"id":27884552,"url":"https://github.com/oasisprotocol/demo-rofl-chatbot","last_synced_at":"2025-05-05T06:37:57.572Z","repository":{"id":278710186,"uuid":"934253155","full_name":"oasisprotocol/demo-rofl-chatbot","owner":"oasisprotocol","description":null,"archived":false,"fork":false,"pushed_at":"2025-03-10T11:50:35.000Z","size":98232,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-03-10T12:26:29.431Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oasisprotocol.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-17T14:24:24.000Z","updated_at":"2025-03-10T11:50:37.000Z","dependencies_parsed_at":"2025-02-21T09:33:35.150Z","dependency_job_id":"7da8e4cb-fffb-46e6-8948-13768a88fd08","html_url":"https://github.com/oasisprotocol/demo-rofl-chatbot","commit_stats":null,"previous_names":["oasisprotocol/demo-rofl-chatbot"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oasisprotocol%2Fdemo-rofl-chatbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oasisprotocol%2Fdemo-rofl-chatbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oasisprotocol%2Fdemo-rofl-chatbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oasisprotocol%2Fdemo-rofl-chatbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oasisprotocol","download_url":"https://codeload.github.com/oasisprotocol/demo-rofl-chatbot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252454923,"owners_count":21750507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-05T06:37:56.949Z","updated_at":"2025-05-05T06:37:57.556Z","avatar_url":"https://github.com/oasisprotocol.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Demo Chat Bot Running on Oasis ROFL\n\nThis is a simple showcase of a ollama-based chatbot running inside Oasis ROFL\nTDX.\n\n**Check the live demo running on Sapphire Testnet [here][live-demo].**\n\n![screenshot](./screenshot.png)\n\n[live-demo]: https://playground.oasis.io/demo-rofl-chatbot\n\n## Features\n\n- fully distributed and redundant large language model via the [Oasis Sapphire\n  blockchain] and [Oasis ROFL]\n- e2e encrypted transactions and queries\n- integrated on-chain Sign-in With Ethereum service for logging in\n- compute-intensive LLM computation running offchain inside TEE\n\n[Oasis Sapphire blockchain]: https://oasisprotocol.org\n[Oasis ROFL]: https://docs.oasis.io/build/rofl\n\n## Components\n\n- `contracts` contains the Sapphire smart contract which confidentially stores\n  the prompts and answers. It also makes sure that only an **authorized\n  TEE-based Oracle** is allowed to read prompts and write answers back.\n- `oracle` a python-based oracle running inside a ROFL TEE that listens for\n  prompts on the Sapphire smart contract, relays it to the ollama service and\n  writes the answer back to the smart contract.\n- `ollama` is a chat bot running inside a ROFL TEE that waits for prompts from\n  `oracle`, generates a response using a preconfigured model and returns it to\n  the `oracle`.\n- `frontend` is a React frontend that makes sure the user is properly logged in\n  via Sign-In With Ethereum (SIWE) protocol and that the user's prompts are\n  end-to-end encrypted when submitted to the Sapphire chain.\n\n## How does the ROFL Chat Bot work?\n\n![ROFL flow diagram](./rofl-chatbot-flow.svg)\n\n## Verification\n\nSecurity is hard. But let's go through the required verification steps in order\nto prove that the chat bot deployed above is really secure.\n\nAssumptions:\n\n- the Oasis ROFL TEE stack is audited and secure (check out [this wonderful\n  article] by [Jernej Kos](https://github.com/kostko) on different ROFL stages)\n- the Oasis Sapphire blockchain is not compromised\n\n[this wonderful article]: https://x.com/JernejKos/status/1898030773636366410\n\n### How do I know my prompts are really private?\n\n1. Check out the **verified** smart contract for storing prompts and answers:\n   [`0xcD0F0eFfAFAe5F5439f24F01ab69b2CBaC14cC56`][smart-contract].\n2. Notice that `getPrompts()` and `getAnswers()` are protected with the modifier\n   `onlyUserOrOracle`.\n\n[smart-contract]: https://repo.sourcify.dev/contracts/full_match/23295/0xcD0F0eFfAFAe5F5439f24F01ab69b2CBaC14cC56/sources/src/\n\n### Fine, but how do I know that the \"Oracle account\" isn't used outside of the TEE?\n\nThe Oracle keypair is generated [inside ROFL TEE]!\n\n[inside ROFL TEE]: https://github.com/oasisprotocol/demo-rofl-chatbot/blob/main/oracle/src/RoflUtility.py#L30-L39\n\n### But then there's a chicken-and-egg problem. How did you set the Oracle address in the smart contract, if it hasn't been generated yet?\n\n1. The Oracle account is set after it's being generated via the `setOracle()`\n   setter in the contract.\n2. This setter is protected with the `onlyTEE` modifier which calls a Sapphire\n   [`roflEnsureAuthorizedOrigin`] subcall. This call checks whether the\n   transaction really originated from the TEE by verifying the unique signature\n   corresponding to the app ID.\n\nNote: Careful readers will notice the trusted oracle address can also be set via\nthe contract constructor. This is only used for testing. But don't trust us,\n**verify** the deliberately unencrypted contract create transaction\n[here][contract-create].\n\n[`roflEnsureAuthorizedOrigin`]: https://api.docs.oasis.io/sol/sapphire-contracts/contracts/Subcall.sol/library.Subcall.html#roflensureauthorizedorigin\n[contract-create]: https://explorer.oasis.io/testnet/sapphire/tx/0x94a6d75bbdfb33e894896245c43259f5d388b64a6466e7652b9d0b78200c1c4d\n\n### But the key can leak somewhere inside the TEE containers?\n\nGranted, the [trusted compute base] (TCB) for ROFL TDX containers is not small.\nIn our case, you need to audit the `compose.yaml` file along with the `oracle`\nand `ollama` containers that there is no point in the code where they access the\n[`appd` endpoint] for generating the Oracle account keypair apart from where its \naddress is stored to the contract.\n\n[trusted compute base]: https://en.wikipedia.org/wiki/Trusted_computing_base\n[`appd` endpoint]: https://docs.oasis.io/build/rofl/features#key-generation\n\n### I audited all components. How do I know that this code is the one that is actually deployed?\n\nRun [`oasis rofl build --verify`][oasis-rofl-build-verify]. This command is part\nof the [Oasis CLI] and it will compile all components to check that the obtained\nEnclave ID (i.e. the hash derived from the compiled containers above including\nall ROFL TEE boot stages) matches the one that is currently active on the\nblockchain and which Oasis nodes can spin up.\n\nBut there's more. You also need to verify **any previous upgrades of this ROFL**\nto prove that the keys didn't leak in the past. You can audit [previously\ndeployed versions] and verify them with the same command.\n\n[Oasis CLI]: https://github.com/oasisprotocol/cli\n[oasis-rofl-build-verify]: https://docs.oasis.io/general/manage-tokens/cli/rofl#build\n[previously deployed versions]: https://explorer.oasis.io/testnet/sapphire/address/oasis1qpupfu7e2n6pkezeaw0yhj8mcem8anj64ytrayne?method=rofl.Update\n\n## Testing and Deployment\n\n***NOTE:*** If you just cloned this folder, don't forget to also fetch the\nsubmodules:\n\n```shell\ngit submodule init\ngit submodule update\n```\n\nThe easiest way to spin up all components described above is to use:\n\n- [Podman] version 4.9.x or above\n- [Podman Compose] version 1.3.x or above\n\n[Podman]: https://podman.io/\n[Podman Compose]: https://github.com/containers/podman-compose\n\n### Localnet deployment\n\n```shell\npodman-compose -f compose.localnet.yaml up\n```\n\nOnce all containers are up and running, open your web browser at\n`http://localnet:5173`.\n\n### Testnet deployment\n\nNote: The steps below are using the `oasisprotocol` GitHub organization to store\nthe `oracle` container. Replace it with your own organization to fit your needs.\nDon't forget to update `compose.yaml` accordingly.\n\n1. `podman build -f Dockerfile.oracle -t ghcr.io/oasisprotocol/demo-rofl-chatbot:latest .`\n   \n2. `podman push --digestfile demo-rofl-chatbot.default.orc.digest ghcr.io/oasisprotocol/demo-rofl-chatbot:latest`\n\n3. Update `compose.yaml` `services.oracle.image` field with\n   `ghcr.io/oasisprotocol/demo-rofl-chatbot:latest@sha256:` followed by the content of\n   `demo-rofl-chatbot.default.orc.digest`\n\n4. `oasis rofl build --update-manifest`\n\n5. `oasis rofl update`\n\n6. Copy over `demo-rofl-chatbot.default.orc` to your [Oasis node]\n\n7. Add a path to your .orc file to `runtime.paths` in `config.yml` of your\n   Oasis node and restart it.\n\n8. `cd frontend; yarn; yarn build` and copy the content of `dist` folder to the\n   root of your web server (e.g. `playground.oasis.io/demo-rofl-chatbot`).\n\n[Oasis node]: https://docs.oasis.io/node/run-your-node/paratime-client-node#configuring-tee-paratime-client-node\n\n### Troubleshooting\n\n- In case of persistent storage image redundancy error on your Oasis node,\n  remove the\n  `/serverdir/runtimes/images/000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c/rofl.rofl1qrtetspnld9efpeasxmryl6nw9mgllr0euls3dwn/`\n  folder.\n- Make sure you fund your node (for ROFL instance registration transaction gas\n  on every epoch) and the Oracle account (for relaying answers back to the\n  chain).\n- The QGSD service on Oasis node may be buggy from time to time. If you get the\n  quote size errors in your Oasis node log, restarting it with `service qgsd\n  restart` helps.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foasisprotocol%2Fdemo-rofl-chatbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foasisprotocol%2Fdemo-rofl-chatbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foasisprotocol%2Fdemo-rofl-chatbot/lists"}