WASI Deep Dive
WASI ไม่ได้แค่เปิดเผย system call — แต่ออกแบบใหม่ว่าโปรแกรมจะได้รับสิทธิ์เข้าถึงทรัพยากรระบบ แทนที่โมเดล POSIX ซึ่งโปรเซสสืบทอด ambient authority จาก user ID, WASI ใช้ capability-based security: module สามารถใช้ทรัพยากรได้เฉพาะเมื่อรันไทม์ส่ง capability มาให้อย่างชัดเจน
ความปลอดภัยแบบ capability-based
หัวข้อที่มีชื่อว่า “ความปลอดภัยแบบ capability-based”ในโปรเซส Unix ทั่วไป การเปิด /etc/passwd สำเร็จตราบใดที่ UID ของโปรเซสมีสิทธิ์อ่าน ไม่มี sandboxing ที่ขอบเขตแอปพลิเคชัน
ใน WASI module ไม่มี ambient access เลย รันไทม์ทำหน้าที่เป็นยาม:
- เพื่ออ่านจาก filesystem host ต้องส่ง pre-opened directory file descriptor ผ่าน
--dir - เพื่อเข้าถึง environment variable host ต้องอนุญาตผ่าน
--env - โดยค่าเริ่มต้น module WASI มีสิทธิ์เข้าถึง filesystem ศูนย์, network ศูนย์ และ environment variable ศูนย์
ซึ่งหมายความว่าคุณสามารถรัน binary .wasm ที่ไม่น่าเชื่อถือได้อย่างปลอดภัย สิ่งเลวร้ายที่สุดที่ module ที่ถูก compromise สามารถทำได้ถูกจำกัดเฉพาะสิ่งที่ได้รับมาเท่านั้น
WASI Preview 1 vs Preview 2
หัวข้อที่มีชื่อว่า “WASI Preview 1 vs Preview 2”WASI ผ่านการแก้ไขหลักสองครั้ง:
| Preview 1 (0.1) | Preview 2 (0.2) | |
|---|---|---|
| สถานะ | Stable, รองรับอย่างกว้างขวาง | Stable ตั้งแต่ต้นปี 2024 |
| สไตล์ interface | C-like imports แบบ flat (fd_write, path_open) | Component Model WIT interface |
| Target triple | wasm32-wasi / wasm32-wasip1 | wasm32-wasip2 |
| Networking | ไม่อยู่ใน core (vendor extension) | wasi:sockets อยู่ใน core |
| Toolchain | Rust stable, WASI SDK | cargo component, wasm-tools |
สำหรับงาน production ส่วนใหญ่ในปัจจุบัน Preview 1 (wasm32-wasip1) ยังเป็นค่าเริ่มต้นที่ปลอดภัยและไม่มีอะไรน่าตกใจ แต่ Preview 2 (wasm32-wasip2) ก็ไม่ใช่ tooling ใหม่เอี่ยมแล้วเช่นกัน — ใน Rust compiler ทั้ง wasm32-wasip1 และ wasm32-wasip2 เป็น Tier 2 target เท่ากันในปัจจุบัน และ WASI 0.2 ก็เป็น stable release มาตั้งแต่มกราคม 2024 ตอนนี้มี WASI 0.3 (Preview 3) อยู่ในสถานะ preview แล้ว ซึ่งแทนที่โมเดล polling/streams แบบ explicit ของ 0.2 ด้วย async แบบ native ผ่าน future/stream type ของ Component Model — แต่ยังไม่ใช่ stable release ดังนั้นถ้าเจอ claim เรื่อง “0.3” ที่ไหน ให้มองว่าเป็นเรื่องอนาคต ยังไม่ได้ ship จริง
การคอมไพล์ Rust ไป WASI
หัวข้อที่มีชื่อว่า “การคอมไพล์ Rust ไป WASI”เพิ่ม target หนึ่งครั้ง แล้ว build ตามปกติ:
# Install the WASI targetrustup target add wasm32-wasip1
# Build a release binarycargo build --target wasm32-wasip1 --release# Output: target/wasm32-wasip1/release/my_app.wasmmain.rs ของ Rust ขั้นต่ำสำหรับ WASI:
fn main() { println!("Hello from WASI!"); let args: Vec<String> = std::env::args().collect(); println!("Args: {:?}", args);}println! map ไปยัง WASI fd_write import บน file descriptor 1 (stdout) std::env::args() ใช้ WASI args_get / args_sizes_get imports ทั้งคู่เป็นส่วนหนึ่งของ Preview 1
Entry point _start
หัวข้อที่มีชื่อว่า “Entry point _start”เมื่อ wasmtime (หรือรันไทม์ WASI ใด ๆ) รัน binary .wasm จะมองหา exported function ชื่อ _start นี่คือเทียบเท่า WASI ของ main()
Rust compiler สร้าง _start อัตโนมัติเมื่อคอมไพล์ด้วย main function และ target wasm32-wasip1 คุณสามารถตรวจสอบด้วย wasm-objdump:
wasm-objdump -x target/wasm32-wasip1/release/my_app.wasm | grep export# ...# - func[N] <_start> -> "_start"flowchart TD
RT["wasmtime / wasmer\n(runtime)"]
subgraph "Capability grants"
D["--dir /data\n(pre-opened fd)"]
E["--env KEY=VAL"]
A["argv via --"]
end
RT -->|"pre-opens"| D
RT -->|"injects"| E
RT -->|"passes"| A
D --> M["Wasm Module\n(_start)"]
E --> M
A --> M ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| WASI capability-based security | ปลอดภัยกว่า POSIX ambient authority มาก — module ใช้ได้เฉพาะทรัพยากรที่ runtime ส่งมาให้อย่างชัดเจนเท่านั้น | ยังไม่ compatible กับ POSIX เต็มรูปแบบ native library จำนวนมากที่ assume ambient filesystem/network access จะ port เข้า WASI ไม่ราบรื่น |
| Server-side Wasm (WASI runtime) vs container | Cold-start ระดับ microsecond เหมาะกับงาน edge/serverless ที่ต้อง spin up บ่อย | Container ecosystem ยังมี tooling, orchestration และ library support ที่ mature และครบกว่ามาก |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- คาดหวังว่า filesystem หรือ network จะ “ใช้งานได้เลย” เหมือนโปรแกรม native ทั่วไป โดยไม่ grant capability ผ่าน
--dirหรือ--envอย่างชัดเจน — module จะ fail แบบเงียบ ๆ หรือโยน permission error - คิดว่า WASI Preview 1 compatible กับ POSIX API เต็มรูปแบบ แล้วพยายาม port native library ที่ assume ambient access ตรง ๆ โดยไม่ปรับ
- ไม่ track ว่า Preview 2 และ Component Model ยังเป็น standard ที่พัฒนาอยู่ — วางแผน production บน
wasm32-wasip2วันนี้อาจต้องรับมือกับ breaking change ของ interface ในอนาคต
💡 ตัวอย่างจากของจริง
Fastly Compute รัน untrusted customer code เป็น Wasm module พร้อม capability sandboxing แบบ WASI บนเครือข่าย edge ของตัวเอง ทำให้แต่ละ request ได้ sandbox ที่ปลอดภัยโดยไม่ต้องพึ่ง container isolation