WASI(WebAssembly 系統介面)
/ WAH-zee /
一個赤裸的 Wasm 模組像被封在盒子裡:它能運算,卻無法開啟檔案、讀取時鐘、取得亂數或與網路溝通,因為核心規範刻意不給它任何觸及外部世界的途徑。那麼 Wasm 要怎麼在瀏覽器之外執行有用的程式?WASI,也就是 WebAssembly 系統介面,正是主機提供給模組、像系統呼叫一樣的一組標準化函式,讓它能以受控且尊重沙箱的方式做到那些事。
具體而言,WASI 對 Wasm 程式扮演的角色,相當於 POSIX 對一般 Unix 程式所扮演的,但是圍繞「能力(capability)」重新設計過。一般原生程式呼叫 open() 時可以給任意路徑,由核心逐次決定是否允許;而一個 WASI 程式只能對主機事先交給它的資源動作。經典的例子是檔案存取:主機預先開啟一個目錄並把它的把柄(handle)交給模組;模組接著可以開啟該目錄底下的路徑,卻沒有辦法稱呼它之上或之外的任何東西——不存在能觸及整個檔案系統的環境權威(ambient authority)。WASI 為檔案、時鐘、亂數、環境變數等定義了這類介面,模組按名稱匯入它們;若主機不提供某個匯入,那項能力對客體而言就根本不存在。
它之所以重要,是因為 WASI 讓同一個 .wasm 能作為真正的伺服器程式、無伺服器函式或受沙箱的外掛來執行,同時保持被侷限:你正好只授予模組所需的目錄、時鐘與通訊端,別無其他,這比把帳號完整權力交給一個原生二進位檔要嚴格得多。要老實談成熟度:WASI 正透過版本演進(早期的「preview 1」與較新、以組件模型為基礎的設計),像完整網路這類功能涵蓋仍在底定,而且並非每個執行環境都支援相同的部分——所以它確實有前景,也確實仍在變動中。
$ wasmtime run --dir=/srv/data app.wasm # app.wasm 只能 open() /srv/data 底下的檔案;它根本無法稱呼 /etc/passwd, # 因為主機只預先開啟了那一個目錄,且未授予其他任何能力
WASI 是以能力為基礎的:程式只能對主機預先開啟的資源動作。不存在能觸及檔案系統其餘部分的環境權威。
WASI 既未完成也非普世通用:它橫跨多個版本(preview 1 對上組件模型設計),網路等領域仍在穩定中,各執行環境實作的部分也不同。請把「我的 Wasm 用了 WASI」理解為「它匯入了主機選擇提供的那些 WASI 函式」,而非一個固定、完整、等同 POSIX 的東西。