聯絡 EN 中文

drust

開源 Rust BaaS:每個租戶一個 SQLite,原生 MCP 給 AI agent

一眼看懂

問題
我在慈濟基金會擔任資訊主管,團隊常常要開新的小東西:活動網站、表單、內部工具、AI 實驗。
我做了什麼
drust 是一支 Rust 單一執行檔的自架 Backend-as-a-Service。
成果
支撐慈濟 6 個使用中的網站與工具,有 2,600+ 個測試,以 AGPL-3.0 開源。
我的角色
獨力完成
期間
2026-04 → 2026-08

展現的能力

每一項都連到能力頁上對應的能力與等級。

問題

我在慈濟基金會擔任資訊主管,團隊常常要開新的小東西:活動網站、表單、內部工具、AI 實驗。每一個都需要後端,但每個專案各架一套 Postgres 或 Supabase,維運和備份都太重。我也希望 AI agent 能直接操作這些資料,不必每個專案都寫一層膠水程式,同時不能讓 A 專案的資料漏到 B 專案。

我做了什麼

drust 是一支 Rust 單一執行檔的自架 Backend-as-a-Service。每個租戶(一個專案)有自己的 SQLite 檔、一組 REST API,以及一個 AI agent 可以直接連的 MCP endpoint。此外還有 row-level security、Realtime、向量搜尋、WebAssembly 邊緣函式、各租戶獨立的 OAuth、可續傳的 S3 上傳、自動產生型別化客戶端程式碼,以及管理介面。TypeScript SDK drust-js 也是我寫的。

運作方式

  • 一個 meta.sqlite 存管理員、租戶與 token;每個租戶的資料在 tenants/<id>/data.sqlite。
  • 讀取走唯讀連線,並由 SQLite 的 authorizer 把關,跨租戶 ATTACH 在 SQL 層就會被拒絕。
  • 寫入只能透過結構化的 REST 或 MCP 工具,每個租戶有一把寫入鎖。
  • 每個 MCP server 一連上就先給一份「意圖 → 工具」對照表,agent 第一次連線就知道從哪裡開始。

關鍵決策

  • 寫入路徑永遠不收原始 SQL。 使用者輸入只會以結構化 filter 的形式、用參數綁定編譯進 SQL,owner 規則和 RLS policy 才能確實執行。使用者 token 一律不能用 raw query 和 MCP,因為 drust 無法改寫自由格式的 SQL。
  • MCP 介面是為模型設計的。 每個錯誤都附 suggested_fix,破壞性工具支援 dry_run。v1.37 我刪掉 4 個重複工具(57 → 52),讓模型第一次就挑對,之後隨新功能增加,目前是 76 個;並寫了一個小型評測,讓 Claude 跑 5 個固定任務來量測效果。
  • 邊緣函式在同一個行程內執行,沙盒由 wasmtime 負責。 限制靠 epoch deadline、resource limiter 和空的 WASI context。這是刻意放棄行程層級 W^X 的取捨,理由寫在部署檔裡。

成果

drust 目前是 v1.66,AGPL-3.0 授權,提供多架構 Docker 映像與公開 SDK。我請 AI agent 對自己的實例做了兩輪安全評估:第一輪找到 1 個 High 等級的授權漏洞,我已修掉;之後針對 v1.41.3 的灰箱測試結果是 Critical 0、High 0、Medium 1、Low 2。在慈濟,它是 9 個專案的後端:6 個使用中的網站與工具(60 週年活動網、60impact、年報、七月吉祥月、浴佛節網站、MasterSlides)、正在遷移到 drust 的純素內容網站,以及 2 個原型/POC(語音收集工具、LINE 需求收集)。整個專案用 Claude Code 開發,靠 repo 內的指引與 skills 跑 spec → plan → implement → review 的循環。