콘텐츠로 이동

WASM 플러그인

기능 게이팅된 WASM 플러그인 시스템: 매니페스트, 기능 선언, 권한, 서명 검증.

Revka는 WebAssembly 플러그인을 로드하여 런타임을 커스텀 도구, 채널, 메모리 백엔드, 옵저버 훅으로 확장할 수 있습니다. 각 플러그인은 manifest.toml.wasm 모듈을 포함하는 디렉터리입니다. 호스트는 로컬 디스크에서 플러그인을 탐색하고, 선택적으로 매니페스트의 Ed25519 서명을 검증한 뒤, 로드된 플러그인 목록을 CLI와 게이트웨이 API를 통해 노출합니다.

이 서브시스템 전체는 plugins-wasm Cargo 기능 플래그로 컴파일 시점에 게이팅됩니다. 표준 Revka 빌드에는 포함되지 않으므로, revka plugin CLI 서브커맨드와 GET /api/plugins 엔드포인트는 해당 기능을 포함하여 빌드된 바이너리에서만 존재합니다. 커스텀 WASM 확장을 개발하거나, 배포용으로 패키징하거나, 운영자가 로드할 플러그인을 제한하려는 경우에 이 페이지를 참고하세요.

플러그인 시스템은 두 가지 조건을 모두 충족해야 합니다.

  1. 빌드 게이트 — Revka를 해당 기능과 함께 컴파일해야 합니다.

    Terminal window
    cargo build --release --features plugins-wasm

    plugins-wasmfull 기능 세트에 포함되므로, --features full 빌드에도 포함됩니다.

  2. 설정 게이트config.toml에서 시스템을 활성화해야 합니다.

    [plugins]
    enabled = true

기능이 컴파일에서 제외된 경우, CLI 서브커맨드와 API 라우트가 아예 존재하지 않습니다. 기능이 포함되어 있지만 [plugins] enabled = false인 경우, API는 plugins_enabled: false와 빈 플러그인 목록을 반환하며 플러그인 도구는 등록되지 않습니다.

전체 기능 매트릭스는 Cargo 기능 플래그 & ADR을, config.toml 로드 방식은 설정 개요를 참고하세요.

모든 플러그인 설정은 [plugins] 아래에 위치하며, 서명 정책은 [plugins.security]에 중첩됩니다.

[plugins]
enabled = true # 마스터 스위치 (기본값: false)
plugins_dir = "~/.revka/plugins" # 플러그인 위치 (기본값 표시)
auto_discover = false # 시작 시 자동 탐색 (기본값: false)
max_plugins = 50 # 최대 플러그인 수 (기본값: 50)
[plugins.security]
signature_mode = "disabled" # "disabled" | "permissive" | "strict" (기본값: "disabled")
trusted_publisher_keys = [] # 16진수 인코딩된 Ed25519 퍼블리셔 공개 키 목록
타입기본값의미
plugins.enabledboolfalse플러그인 시스템의 마스터 스위치입니다.
plugins.plugins_dirstring~/.revka/plugins플러그인 서브 디렉터리가 위치하는 디렉터리입니다. 앞의 ~/는 홈 디렉터리로 확장됩니다.
plugins.auto_discoverboolfalse시작 시 플러그인을 자동으로 탐색하고 로드합니다.
plugins.max_pluginsusize50로드할 수 있는 최대 플러그인 수입니다.
plugins.security.signature_modestring"disabled"서명되지 않았거나 검증할 수 없는 플러그인을 처리하는 방식입니다. 서명 모드를 참고하세요.
plugins.security.trusted_publisher_keysstring[][]신뢰하는 퍼블리셔의 16진수 인코딩된 Ed25519 공개 키 목록입니다.

각 플러그인은 plugins_dir 아래에 별도의 디렉터리로 존재합니다. 호스트는 해당 디렉터리를 스캔하여 manifest.toml이 포함된 서브 디렉터리를 플러그인 후보로 처리합니다.

~/.revka/plugins/
└── my-plugin/
├── manifest.toml # 필수
└── plugin.wasm # 컴파일된 모듈 (manifest.wasm_path에서 지정한 경로)

디스크의 플러그인 디렉터리 이름이 매니페스트의 name과 일치할 필요는 없지만, CLI를 통해 설치할 경우 호스트는 manifest.name을 딴 디렉터리로 플러그인을 복사합니다.

매니페스트는 호스트의 PluginManifest로 역직렬화되는 TOML 파일입니다. name, version, wasm_path, capabilities는 필수이며, 나머지는 선택 사항입니다.

name = "my-plugin"
version = "0.1.0"
description = "What this plugin does"
author = "Acme Corp"
wasm_path = "plugin.wasm" # .wasm 경로, 이 매니페스트 기준 상대 경로
capabilities = ["tool"] # tool, channel, memory, observer 중 하나 이상
permissions = ["http_client", "file_read"]
# 선택 사항 — 서명된 플러그인에만 존재:
signature = "<base64url Ed25519 signature>"
publisher_key = "<hex Ed25519 public key>"
필드타입필수 여부의미
namestring고유한 플러그인 식별자입니다.
versionstring플러그인 버전 문자열입니다.
descriptionstring아니오사람이 읽을 수 있는 설명입니다.
authorstring아니오작성자 이름 또는 조직명입니다.
wasm_pathstring매니페스트 기준 .wasm 파일의 상대 경로입니다.
capabilitiesstring[]플러그인이 제공하는 기능입니다 (아래 참고).
permissionsstring[]아니오플러그인이 요청하는 호스트 기능입니다 (아래 참고). 기본값은 빈 목록입니다.
signaturestring아니오정규화된 매니페스트에 대한 Base64url 인코딩된 Ed25519 서명입니다.
publisher_keystring아니오서명자의 16진수 인코딩된 Ed25519 공개 키입니다.

capabilities는 플러그인의 확장 유형을 선언합니다. 값은 snake_case로 직렬화됩니다.

기능의미
tool하나 이상의 호출 가능한 도구를 제공합니다.
channel메시징 채널 구현을 제공합니다.
memory메모리 백엔드를 제공합니다.
observer옵저버 / 메트릭 백엔드를 제공합니다.

플러그인은 하나 이상의 기능을 선언할 수 있습니다. 현재 호스트는 tool 기능을 가진 플러그인만 에이전트의 도구 레지스트리에 연결합니다 — 플러그인 도구를 참고하세요.

permissions는 플러그인이 요청하는 호스트 기능의 집합입니다. 매니페스트에서 보조적인 메타데이터로 기록 및 보고되며, 값은 snake_case로 직렬화됩니다.

권한부여 내용
http_clientHTTP 요청을 수행합니다.
file_read파일 시스템에서 읽습니다 (샌드박스 내).
file_write파일 시스템에 씁니다 (샌드박스 내).
env_read환경 변수를 읽습니다.
memory_read에이전트 메모리를 읽습니다.
memory_write에이전트 메모리에 씁니다.

[plugins] enabled = true인 경우, 런타임은 plugins_dir에 대한 플러그인 호스트를 구성하고, tool 기능을 가진 모든 플러그인을 에이전트 레지스트리의 도구로 등록합니다. 도구 이름은 플러그인의 manifest.name이며, 설명은 매니페스트의 description에서 가져옵니다.

현재 등록된 각 플러그인 도구는 다음의 고정된 단일 파라미터 스키마를 노출합니다.

{
"type": "object",
"properties": {
"input": { "type": "string", "description": "Input for the plugin" }
},
"required": ["input"]
}

플러그인 매니페스트는 Ed25519로 서명할 수 있습니다. 서명 대상은 정규화된 매니페스트signaturepublisher_key 줄을 제거한 TOML 내용 — 이므로, 플러그인은 서명하는 파일 안에 자신의 서명을 포함할 수 있습니다. 다른 필드를 편집하면 서명이 무효화됩니다.

signature_mode는 서명되지 않았거나 검증할 수 없는 플러그인을 호스트가 처리하는 방식을 제어합니다.

모드동작
disabled기본값. 서명 검사를 하지 않습니다. 탐색된 모든 플러그인이 로드됩니다.
permissive가능한 경우 검증합니다. 서명 없음, 미신뢰, 또는 유효하지 않은 플러그인은 경고를 기록하지만 여전히 로드됩니다.
strict서명되지 않은 플러그인, trusted_publisher_keys에 없는 키로 서명된 플러그인, 서명 검증에 실패한 플러그인을 거부합니다.

검증은 두 단계로 이루어집니다. 먼저 매니페스트의 publisher_keytrusted_publisher_keys에 존재해야 합니다 (대소문자 구분 없는 16진수 비교) — 그렇지 않으면 플러그인은 미신뢰 상태가 됩니다. 그런 다음 정규화된 매니페스트 바이트에 대해 Ed25519 서명을 검증합니다. strict 모드에서는 미신뢰 퍼블리셔, 유효하지 않은 서명, 또는 서명 누락 모두 탐색 중 해당 플러그인을 건너뛰게 합니다.

잠긴 호스트를 운영하려면 플러그인에 서명하고 키를 고정하세요.

[plugins.security]
signature_mode = "strict"
trusted_publisher_keys = [
"a1b2c3d4e5f6...your-publisher-public-key-hex...",
]

이 내용이 Revka의 전반적인 신뢰 모델에서 어떤 위치를 차지하는지는 보안 모델을 참고하세요.

plugins-wasm 빌드에서 revka plugin 서브커맨드는 플러그인 디렉터리를 관리합니다.

Terminal window
revka plugin list

설치된 각 플러그인을 name vX.Y.Z — description 형식으로 출력하거나, No plugins installed.를 출력합니다.

전역 플래그 및 환경 설정은 CLI 개요를 참고하세요.

게이트웨이는 대시보드에서 플러그인 상태를 표시할 수 있도록 로드된 플러그인 목록을 노출합니다. 이 라우트는 plugins-wasm 빌드에서만 존재합니다.

GET /api/plugins — Bearer 토큰이 필요합니다.

GET /api/plugins
Authorization: Bearer rk_<token>

응답:

{
"plugins_enabled": true,
"plugins_dir": "~/.revka/plugins",
"plugins": [
{
"name": "my-plugin",
"version": "0.1.0",
"description": "What this plugin does",
"capabilities": ["tool"],
"loaded": true
}
]
}
필드의미
plugins_enabled[plugins] enabled를 반영합니다. false인 경우 plugins는 항상 비어 있습니다.
plugins_dir설정된 플러그인 디렉터리입니다 (미확장, 예: ~/.revka/plugins).
plugins[].name / version / description매니페스트에서 가져옵니다.
plugins[].capabilities매니페스트의 기능 목록입니다.
plugins[].loaded해석된 .wasm 파일이 디스크에 존재하면 true입니다.

기능이 활성화되어 있지만 플러그인 디렉터리가 존재하지 않는 경우, plugins는 빈 배열입니다. 이 엔드포인트는 페어링된 Bearer 토큰이 필요합니다 — 토큰 발급 방법은 페어링 및 인증을 참고하세요.