본문으로 건너뛰기
Kreath Archive
TechProjectsBooksAbout
TechProjectsBooksAbout

내비게이션

  • Tech
  • Projects
  • Books
  • About
  • Tags

카테고리

  • AI / ML
  • 웹 개발
  • 프로그래밍
  • 개발 도구

연결

  • GitHub
  • Email
  • RSS
© 2026 Kreath Archive. All rights reserved.Built with Next.js + MDX
홈TechProjectsBooksAbout
//
  1. 홈
  2. 테크
  3. 3장: WASI — WebAssembly 시스템 인터페이스
2026년 3월 26일·프로그래밍·

3장: WASI — WebAssembly 시스템 인터페이스

WASI의 탄생 배경과 Capability-based 보안 모델, WASI Preview 2의 Worlds 개념, 비동기 지원을 위한 WASI 0.3, 그리고 1.0 로드맵을 상세히 다룹니다.

14분440자10개 섹션
webassemblyrust
공유
webassembly3 / 10
12345678910
이전2장: Wasm 런타임 아키텍처 심층 분석다음4장: 컴포넌트 모델과 WIT

학습 목표

  • WASI가 탄생한 배경과 해결하려는 문제를 이해합니다
  • Capability-based 보안 모델의 원리를 설명할 수 있습니다
  • WASI Preview 2(0.2)의 Worlds 개념과 주요 인터페이스를 파악합니다
  • WASI 0.3의 비동기 지원과 1.0 로드맵을 전망합니다

WASI의 탄생 배경

WebAssembly가 브라우저에서 동작할 때는 JavaScript와 Web API가 외부 세계와의 인터페이스 역할을 합니다. 하지만 서버에서 Wasm을 실행하려면 어떻게 해야 할까요? 파일을 읽고, 네트워크 요청을 보내고, 환경 변수를 참조하는 등의 시스템 상호작용이 필요합니다.

초기에는 각 런타임이 자체적인 호스트 API를 제공했습니다. 이는 곧 심각한 호환성 문제로 이어졌습니다. Wasmer에서 동작하는 Wasm 바이너리가 Wasmtime에서는 실행되지 않는 상황이 발생한 것입니다.

**WASI(WebAssembly System Interface)**는 이 문제를 해결하기 위해 2019년에 제안되었습니다. 운영체제의 기능에 접근하기 위한 표준화된 인터페이스를 정의하여, 어떤 런타임에서든 동일한 Wasm 바이너리가 실행될 수 있도록 하는 것이 목표입니다.

Capability-based 보안

WASI의 보안 모델은 **Capability-based Security(능력 기반 보안)**에 기반합니다. 전통적인 운영체제의 접근 제어 방식과 근본적으로 다릅니다.

전통적인 방식 (Ambient Authority)

POSIX 시스템에서 프로세스가 open("/etc/passwd", O_RDONLY)를 호출하면, 커널이 해당 프로세스의 UID/GID와 파일 권한을 비교하여 접근을 결정합니다. 프로세스는 파일 경로만 알면 접근을 시도할 수 있습니다.

WASI 방식 (Capability-based)

WASI에서는 프로그램이 파일 시스템에 접근하려면, 호스트로부터 **디스크립터(Descriptor)**를 미리 전달받아야 합니다. 이 디스크립터가 바로 "능력(Capability)"입니다.

capability-example.sh
bash
# /data 디렉터리만 읽기 전용으로 허용
wasmtime run --dir /data::readonly app.wasm
 
# /tmp에는 읽기/쓰기 허용, 네트워크는 차단
wasmtime run --dir /tmp app.wasm
Info

Capability-based 보안의 핵심 원칙은 **최소 권한(Principle of Least Privilege)**입니다. 프로그램은 명시적으로 부여받은 능력만 사용할 수 있으며, 그 범위를 벗어나는 작업은 불가능합니다. 호스트가 /data 디렉터리의 디스크립터만 전달했다면, 프로그램은 /etc에 접근하는 것 자체가 불가능합니다.

이 모델은 서드파티 코드 실행에서 특히 강력합니다. 플러그인이 할 수 있는 일을 코드 수준이 아닌 런타임 수준에서 제한할 수 있기 때문입니다.

WASI Preview 1에서 Preview 2로

Preview 1의 한계

2020년에 안정화된 WASI Preview 1은 POSIX 스타일의 파일 시스템 API를 중심으로 설계되었습니다. 단순하고 직관적이었지만, 몇 가지 근본적인 한계가 있었습니다.

  • 단일 모듈 중심: 모듈 간 상호작용을 위한 표준이 없었습니다
  • 동기 API만 지원: 네트워크 I/O 같은 비동기 작업에 비효율적이었습니다
  • 제한된 타입 시스템: 정수와 바이트 배열 수준의 저수준 인터페이스만 제공했습니다

Preview 2 (WASI 0.2)

2024년 1월에 출시된 WASI Preview 2는 **컴포넌트 모델(Component Model)**을 기반으로 완전히 재설계되었습니다. WIT(WebAssembly Interface Type)를 통해 고수준 타입을 주고받을 수 있으며, 인터페이스 정의가 언어에 독립적입니다.

example.wit
wit
package example:calculator@1.0.0;
 
interface operations {
    record input {
        a: f64,
        b: f64,
    }
 
    variant operation {
        add(input),
        subtract(input),
        multiply(input),
        divide(input),
    }
 
    calculate: func(op: operation) -> result<f64, string>;
}
 
world calculator {
    export operations;
}

Worlds 개념

WASI Preview 2의 핵심 혁신 중 하나가 **월드(World)**입니다. 월드는 Wasm 컴포넌트가 사용할 수 있는 인터페이스의 집합을 정의합니다. 쉽게 말해, "이 프로그램이 어떤 환경에서 실행되는가"를 명세하는 것입니다.

wasi-cli

커맨드라인 프로그램을 위한 월드입니다. 표준 입출력, 파일 시스템, 환경 변수, 프로세스 종료 등의 인터페이스를 포함합니다.

wasi-cli-world.wit
wit
world cli {
    include wasi:cli/imports@0.2.0;
    
    // 포함되는 인터페이스들:
    // - wasi:filesystem/types
    // - wasi:filesystem/preopens
    // - wasi:io/streams
    // - wasi:cli/stdin
    // - wasi:cli/stdout
    // - wasi:cli/stderr
    // - wasi:cli/environment
    // - wasi:clocks/wall-clock
    // - wasi:random/random
    
    export wasi:cli/run@0.2.0;
}

wasi-http

HTTP 서버 및 클라이언트를 위한 월드입니다. Spin, Fermyon Cloud 등 서버리스 플랫폼의 핵심 인터페이스입니다.

wasi-http-world.wit
wit
world http-handler {
    include wasi:http/imports@0.2.0;
    
    // 인바운드 HTTP 요청 처리
    export wasi:http/incoming-handler@0.2.0;
}

wasi-sockets

네트워크 소켓 통신을 위한 월드입니다. TCP, UDP 소켓과 DNS 조회 기능을 제공합니다.

Warning

WASI 0.2의 wasi-sockets는 아직 모든 런타임에서 완전히 구현되지 않았습니다. Wasmtime은 TCP/UDP를 지원하지만, 일부 런타임에서는 HTTP 수준의 추상화만 제공합니다. 프로덕션 배포 전에 대상 런타임의 지원 범위를 확인해야 합니다.

WASI 0.3 — 비동기의 시대

WASI 0.2가 동기 API 중심이라면, WASI 0.3은 비동기(Async) 지원을 핵심 목표로 합니다.

왜 비동기가 필요한가

현대 서버 애플리케이션은 대부분 비동기 I/O를 활용합니다. 데이터베이스 쿼리를 보내고 응답을 기다리는 동안 다른 요청을 처리하는 것이 일반적입니다. WASI 0.2에서는 이러한 비동기 패턴을 자연스럽게 표현할 수 없었습니다.

WASI 0.3의 접근 방식

WASI 0.3은 컴포넌트 모델 수준에서 async 함수와 stream, future 타입을 도입합니다.

async-example.wit
wit
// WASI 0.3 비동기 인터페이스 (예시)
interface async-operations {
    // 비동기 함수 - 호출자가 결과를 기다리는 동안
    // 다른 작업을 수행할 수 있음
    process: async func(data: list<u8>) -> result<list<u8>, string>;
    
    // 스트림 - 데이터를 점진적으로 전달
    read-stream: func() -> stream<u8>;
}

2026년 초 현재, WASI 0.3은 Wasmtime에서 실험적으로 지원되고 있습니다. 안정화까지는 시간이 더 필요하지만, 비동기 지원이 완료되면 Wasm의 서버사이드 활용도가 한 단계 더 높아질 것으로 기대됩니다.

WASI 1.0 로드맵

WASI의 최종 목표는 1.0 안정 릴리스입니다. 현재 로드맵에 따르면 2026년 말에서 2027년 초 사이에 달성될 것으로 예상됩니다.

1.0에서 기대되는 안정화 영역은 다음과 같습니다.

  • Core interfaces: filesystem, sockets, clocks, random
  • HTTP: 인바운드/아웃바운드 HTTP 처리
  • Async: 비동기 함수, stream, future
  • Key-value store: 단순 저장소 인터페이스
  • Messaging: 이벤트 기반 통신

실습 — WASI 프로그램 작성

간단한 WASI CLI 프로그램을 Rust로 작성해 보겠습니다.

src/main.rs
rust
use std::env;
use std::fs;
 
fn main() {
    // 환경 변수 읽기
    let name = env::var("USER_NAME").unwrap_or_else(|_| "World".to_string());
    println!("Hello, {}!", name);
    
    // 파일 읽기 (호스트가 허용한 경로만 접근 가능)
    match fs::read_to_string("/data/config.txt") {
        Ok(content) => println!("Config: {}", content),
        Err(e) => eprintln!("Cannot read config: {}", e),
    }
}
build-and-run.sh
bash
# WASI 타겟으로 빌드
cargo build --target wasm32-wasip2
 
# Wasmtime으로 실행
# - /data 디렉터리 접근 허용
# - USER_NAME 환경 변수 전달
wasmtime run \
  --dir /data \
  --env USER_NAME=Kreath \
  target/wasm32-wasip2/debug/hello.wasm
Tip

wasm32-wasip2는 WASI Preview 2를 타겟으로 하는 Rust 컴파일 타겟입니다. 기존의 wasm32-wasi(Preview 1)와 구분됩니다. Rust 1.82부터 Tier 2 지원이 시작되었으며, 2026년 현재 안정적으로 사용할 수 있습니다.

정리

이번 장에서는 WASI의 전체 그림을 살펴보았습니다.

  • WASI는 WebAssembly의 시스템 인터페이스를 표준화하여 런타임 간 호환성을 보장합니다
  • Capability-based 보안은 최소 권한 원칙에 기반한 강력한 격리를 제공합니다
  • WASI 0.2는 컴포넌트 모델과 WIT를 기반으로 재설계되었으며, Worlds 개념으로 실행 환경을 명세합니다
  • WASI 0.3은 비동기 지원을, 1.0은 완전한 안정화를 목표로 합니다

다음 장 미리보기

4장에서는 WASI 0.2의 기반이 되는 **컴포넌트 모델(Component Model)**을 깊이 있게 다룹니다. WIT 언어의 문법, 레코드/배리언트/리소스 타입 시스템, 컴포넌트 구성(Composition)을 통한 언어 간 상호운용성을 살펴봅니다.

이 글이 도움이 되셨나요?

관련 주제 더 보기

#webassembly#rust

관련 글

프로그래밍

4장: 컴포넌트 모델과 WIT

WebAssembly 컴포넌트 모델의 필요성, WIT IDL의 문법과 타입 시스템, 인터페이스와 월드 정의, 컴포넌트 구성을 통한 언어 간 상호운용성을 다룹니다.

2026년 3월 28일·13분
프로그래밍

2장: Wasm 런타임 아키텍처 심층 분석

WebAssembly의 스택 머신 실행 모델, 모듈/인스턴스/메모리/테이블 구조, 주요 런타임(Wasmtime, Wasmer, WasmEdge, V8) 비교, AOT와 JIT 컴파일 전략을 분석합니다.

2026년 3월 24일·14분
프로그래밍

5장: Rust에서 Wasm 빌드

Rust에서 WebAssembly를 빌드하는 전체 과정을 다룹니다. wasm-pack, cargo-component, 크기 최적화, WASI 타겟 빌드, 컴포넌트 모델 적용, HTTP 핸들러 실전 예제까지.

2026년 3월 30일·13분
이전 글2장: Wasm 런타임 아키텍처 심층 분석
다음 글4장: 컴포넌트 모델과 WIT

댓글

목차

약 14분 남음
  • 학습 목표
  • WASI의 탄생 배경
  • Capability-based 보안
    • 전통적인 방식 (Ambient Authority)
    • WASI 방식 (Capability-based)
  • WASI Preview 1에서 Preview 2로
    • Preview 1의 한계
    • Preview 2 (WASI 0.2)
  • Worlds 개념
    • wasi-cli
    • wasi-http
    • wasi-sockets
  • WASI 0.3 — 비동기의 시대
    • 왜 비동기가 필요한가
    • WASI 0.3의 접근 방식
  • WASI 1.0 로드맵
  • 실습 — WASI 프로그램 작성
  • 정리
  • 다음 장 미리보기