1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//! WASI Integration for Plugin Sandboxing
//!
//! This module provides WebAssembly System Interface (WASI) integration,
//! enabling plugins to access system resources (filesystem, environment, stdio)
//! in a controlled, capability-based manner.
//!
//! # Architecture Overview
//!
//! ```text
//! ┌─────────────────────────────────────────────────────────────────────────┐
//! │ WASI Integration Layer │
//! ├─────────────────────────────────────────────────────────────────────────┤
//! │ │
//! │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
//! │ │ Capabilities │ ──► │ WasiConfigurer │ ──► │ WasiCtx │ │
//! │ │ (from manifest)│ │ (this module) │ │ (wasmtime-wasi) │ │
//! │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
//! │ │
//! │ Capabilities: WasiConfigurer: WasiCtx: │
//! │ - fs_read: [./data] - Validates paths - preopened_dir() │
//! │ - fs_write: [./out] - Resolves symlinks - env() │
//! │ - env_read: [HOME] - Applies sandbox - inherit_stdio() │
//! │ - stdio: stdout - Builds WasiCtx - (configured) │
//! │ │
//! └─────────────────────────────────────────────────────────────────────────┘
//! │
//! ▼
//! ┌─────────────────────────────────────────────────────────────────────────┐
//! │ Plugin Execution │
//! ├─────────────────────────────────────────────────────────────────────────┤
//! │ │
//! │ 1. Permission Check (permission module) │
//! │ └─► Strategy.check(capabilities) → Allow/Deny/Prompt │
//! │ │
//! │ 2. WASI Context Build (this module) │
//! │ └─► WasiConfigurer::build(capabilities) → WasiCtx │
//! │ │
//! │ 3. Store Creation with WASI │
//! │ └─► Store::new(engine, WasiCtx) │
//! │ │
//! │ 4. Plugin Execution │
//! │ └─► Plugin can access ONLY granted resources │
//! │ │
//! └─────────────────────────────────────────────────────────────────────────┘
//! ```
//!
//! # Security Model
//!
//! WASI integration follows the **Principle of Least Privilege**:
//!
//! | Resource | Default | With Capability |
//! |----------|---------|-----------------|
//! | Filesystem Read | Denied | Allowed for declared paths only |
//! | Filesystem Write | Denied | Allowed for declared paths only |
//! | Environment Vars | Denied | Allowed for declared patterns |
//! | Stdin | Denied | Allowed if `stdio.stdin = true` |
//! | Stdout | Denied | Allowed if `stdio.stdout = true` |
//! | Stderr | Denied | Allowed if `stdio.stderr = true` |
//! | Network | Denied | Future: WASI Preview 2 |
//! | Clock/Random | Allowed | Always available (safe) |
//!
//! ## Path Security
//!
//! All filesystem paths undergo strict validation:
//!
//! 1. **Canonicalization**: Paths are resolved to absolute form
//! 2. **Symlink Resolution**: Symlinks are followed and validated
//! 3. **Traversal Prevention**: `../` patterns outside allowed paths are blocked
//! 4. **Sandbox Enforcement**: Access is restricted to declared directories
//!
//! ```text
//! Requested: ./data/../secret
//! │
//! ▼
//! Canonicalized: /home/user/project/secret
//! │
//! ▼
//! Allowed paths: [/home/user/project/data]
//! │
//! ▼
//! Result: DENIED (path escapes sandbox)
//! ```
//!
//! # Capability to WASI Mapping
//!
//! ```text
//! sen-plugin-api::Capabilities ──► wasmtime-wasi::WasiCtxBuilder
//! ─────────────────────────────────────────────────────────────────────
//!
//! fs_read: ["./data"] ──► preopened_dir("./data", DirPerms::READ)
//!
//! fs_write: ["./out"] ──► preopened_dir("./out", DirPerms::all())
//!
//! env_read: ["HOME", "MY_*"] ──► env("HOME", value)
//! env("MY_VAR1", value) // expanded
//! env("MY_VAR2", value)
//!
//! stdio.stdin: true ──► inherit_stdin()
//! stdio.stdout: true ──► inherit_stdout()
//! stdio.stderr: true ──► inherit_stderr()
//!
//! net: ["api.example.com"] ──► (Not yet implemented - Preview 2)
//! ```
//!
//! # Usage
//!
//! ## Basic Usage (with Permission System)
//!
//! ```rust,ignore
//! use sen_plugin_host::{PluginRegistry, PermissionPresets};
//! use sen_plugin_host::wasi::WasiConfigurer;
//!
//! // 1. Create registry with permissions
//! let registry = PluginRegistry::with_permissions(
//! PermissionPresets::interactive("myapp")?
//! )?;
//!
//! // 2. Load plugin (capabilities are in manifest)
//! registry.load_plugin("./plugins/data-export.wasm").await?;
//!
//! // 3. Execute (WASI context is built automatically based on capabilities)
//! // - If not yet permitted: user is prompted
//! // - If permitted: WasiCtx is configured with declared capabilities
//! let result = registry.execute("data-export", &[]).await?;
//! ```
//!
//! ## Manual WASI Configuration
//!
//! ```rust,ignore
//! use sen_plugin_host::wasi::{WasiConfigurer, WasiConfig};
//! use sen_plugin_api::Capabilities;
//!
//! // Define capabilities
//! let caps = Capabilities::default()
//! .with_fs_read(vec![PathPattern::new("./data").recursive()])
//! .with_fs_write(vec![PathPattern::new("./output")])
//! .with_env_read(vec!["HOME".into(), "PATH".into()])
//! .with_stdio(StdioCapability::stdout_stderr());
//!
//! // Build WASI context
//! let wasi_ctx = WasiConfigurer::new()
//! .with_capabilities(&caps)
//! .with_working_directory(std::env::current_dir()?)
//! .build()?;
//!
//! // Use with wasmtime Store
//! let mut store = Store::new(&engine, wasi_ctx);
//! ```
//!
//! # Network Access (Future)
//!
//! Network access via WASI is planned for a future release using WASI Preview 2:
//!
//! ```text
//! Option A: WASI Preview 2 Sockets (complex, full network stack)
//! ├── wasi:sockets/tcp
//! ├── wasi:sockets/udp
//! └── wasi:sockets/dns
//!
//! Option B: Host-Proxy HTTP (simpler, HTTP-only)
//! ├── Plugin calls: host_http_request(url, method, body)
//! ├── Host validates: net capability contains url's host
//! └── Host executes: actual HTTP request
//!
//! Current recommendation: Option B for MVP (simpler, sufficient for most CLIs)
//! ```
//!
//! # Module Structure
//!
//! - [`context`]: WASI context builder from Capabilities
//! - [`sandbox`]: Path validation and sandbox enforcement
//! - [`error`]: WASI-specific error types
//!
//! # Feature Flags
//!
//! This module requires the `wasi` feature:
//!
//! ```toml
//! [dependencies]
//! sen-plugin-host = { version = "0.8", features = ["wasi"] }
//! ```
pub use ;
pub use WasiError;
pub use ;
pub use ;