安全模型
Walis 會執行任意 shell。下面每一個決定都源自這件事。
誰能做什麼
| 層級 | 控制 |
|---|---|
| 登入 | 預設開啟。建立第一位管理員要輸入伺服器啟動時印出的設定碼(開發環境在本機可免)。效果會延續到 session 之後的管理員操作(API 金鑰、重設密碼或 OTP、授予管理員、關閉登入或稽核)會再要求輸入密碼 |
| 角色 | admin、operator、viewer |
| 任務層級 | 每個任務各有檢視角色與執行角色 |
| 外掛 | 安裝需要 admin——外掛是程式碼 |
看不到的任務回 404 而不是 403,不透露它存在。
傳輸
全新安裝接受任何位址以 HTTP 連線,沒有憑證也能完成第一次連線。session cookie 一律是 HttpOnly 與 SameSite=Strict,請求確實經由 TLS 送達時才標記 Secure。
TLS 就緒之後,設定 Security__RequireHttps=true。之後從其他機器連到 /api、/mcp、/metrics 而沒有經過 HTTPS 的請求會收到 426,所有 cookie 都標記 Secure。由反向代理處理 TLS 時, 只有列在 Security__TrustedProxies 的反向代理才算數(同機的反向代理填 127.0.0.1,::1);其他來源送來的轉送標頭會被忽略。
AllowedHosts 限制 Walis 回應的主機名稱,預設接受任何名稱。
建置隔離
建置以服務帳號執行,這表示它原本讀得到 Walis 自己的資料庫——裡面有密碼雜湊、 API 金鑰雜湊與雲端憑證。
建置環境是一份白名單。 建置只繼承 PATH、USER、LOGNAME、SHELL、語系、暫存目錄與 TLS 憑證那幾個變數,其餘一概沒有。服務的連線字串與機密不是被過濾掉的——它們從來就沒放進去。
macOS 上每個步驟以 sandbox-exec 包住,禁止讀寫資料目錄、資料庫所在目錄、備份目的地、安裝目錄(current、releases、var)、服務帳號的家目錄與你自己加的路徑,最後再放行任務的工作目錄;同時拒絕向其他程序送訊號、查詢 Mach 服務與讀取其他程序的資訊。任務還可開啟「拒絕網路」,或由管理員標為「信任任務:不套用沙箱」(供自我更新使用)。
其他平台預設以未隔離方式執行。 Windows 與 Linux 上 Walis 沒有對應的沙箱,遠端執行器本身也不套用沙箱, 所以在那些地方,腳本讀得到執行它的帳號能讀的一切;在內建執行器上,這包括資料目錄。建置日誌會註明, 設定頁也會顯示警告。這個預設是為了每個平台第一次建置就能執行,前提是能編輯任務的人都可信任(若以 Production 監聽非 loopback 位址,全新的資料庫一開始就會開啟「沒有隔離邊界時拒絕執行」,直到管理員明確切換並留下接受紀錄)。
不符合這個前提時,由管理員開啟「沒有隔離邊界時拒絕執行」。之後 Windows 或 Linux 上的內建執行器會拒絕執行建置;遠端執行器要由外部隔離(容器、VM)、自己這樣宣告,而且管理員把它的名字列進「已置於外部隔離的執行器」,才領得到工作。只在請求裡宣稱自己有外部隔離的執行器會被拒絕; 核准必須來自伺服器自己的設定。
你可以再加禁止路徑,也可以限制任務只能在白名單的工作目錄底下執行。
就算有沙箱,這也不是完整隔離——同一個使用者、同一台機器。它擋的是實際會發生的問題 (建置腳本順手把資料庫讀走),而不是已經能以你的身分執行程式碼的攻擊者。
自動觸發
下游任務是被一筆建置觸發的,不是被人,所以沒有 session 可以檢查。Walis 拿上游任務的執行角色 當呼叫者的權限:operator 就能跑的任務,觸發不了需要管理員的任務。 沒有這條規則,在低權限任務上多加一行就成了通往高權限任務的側門。
鏈長到十層就停,所以循環會終止。
金鑰與機密
API 金鑰的格式是 walis_<前綴>_<124 位元祕密>。資料庫只存 domain-separated SHA-256 lookup hash ——祕密是機器產生的高熵值,不像密碼,所以這裡用固定成本的雜湊才是對的。明文只顯示一次。
每把金鑰有用途。新金鑰預設是 mcp,只到得了 /mcp。runner 金鑰綁定單一執行器名稱, 只能替它註冊、心跳、認領與回報。任何用途的金鑰都不能碰登入、帳號與金鑰本身。系統設定可限制允許連入 /mcp 的來源位址(IPv4/IPv6/CIDR),每把金鑰也能綁定自己的來源位址白名單。
資料庫裡的機密(AI 供應商金鑰、機密環境變數、系統設定裡的密碼與雲端憑證、password 建置參數、TOTP 秘密)在寫入前以 AES-256-GCM(enc:v2:,綁定資料表與欄位)加密,主金鑰來自 Security:EncryptionKey 或資料目錄自動產生的 secret.key(0600)。password 型別的建置參數存在標了 [JsonIgnore] 的欄位,不可能經由 API 回應流出去, 值也會列入日誌遮蔽清單。
外掛
外掛回傳字串,由 Walis 執行。沙箱(Jint、沒有 I/O、四道資源上限)有其意義, 但真正的控制點是:你在安裝前讀得到它產生的腳本,而且能力必須宣告並經過核准。
備份
壓縮檔裡有密碼雜湊與雲端金鑰,所以只要啟用備份或設了任何目的地就強制要有通關密語。 加密是有驗證的(PBKDF2-SHA256、各自驗證的 AES-256-GCM 區塊加上驗證過的結束標記), 被改過或被截斷的壓縮檔會在還原任何內容之前就被拒絕;還原端點只接受這種格式。
安全中心與態勢監控
Walis 提供管理員專屬的安全中心(/security)與聚合端點(GET /api/security-center),持續監控系統安全態勢:
- 態勢健檢:涵蓋強制登入、OTP 覆蓋率、安全告警通知、沙箱與外部隔離邊界、工作目錄白名單、Webhook 密鑰、MCP 防火牆、主機加密金鑰與機密完整性等 10 項標準檢查。
- 特權與例外盤點:即時審視不受沙箱限制或未限制網路的任務、已獲網路與機密信任的外掛、無 IP 白名單或無期限的高風險金鑰、帳號權限與執行器狀態。
- 威脅與暴力鎖定管理:自動追蹤因連續密碼錯誤而遭時間窗鎖定的帳號與 IP,支援管理員即時手動解除鎖定(
DELETE /api/security-center/lockouts?key=...)。 - 安全政策與稽核日誌:彙整防護政策即時開關,並提供支援多條件篩選與 CSV 匯出的完整操作稽核。