feat(wasm): harden module integrity and symlink policy

This commit is contained in:
Chummy
2026-02-25 14:21:10 +00:00
committed by Chum Yin
parent 0b172c4554
commit 163f2fb524
9 changed files with 314 additions and 5 deletions
+17 -1
View File
@@ -96,7 +96,9 @@ Recommended path:
1. Start with `dev` for module integration (`capability_escalation_mode = "clamp"`).
2. Move to `staging` and fix denied escalation paths.
3. Promote to `prod` with minimal permissions.
3. Pin module digests with `runtime.wasm.security.module_sha256`.
4. Promote to `prod` with minimal permissions.
5. Set `runtime.wasm.security.module_hash_policy = "enforce"` after all module pins are in place.
Example apply flow:
@@ -104,6 +106,20 @@ Example apply flow:
cp dev/config.wasm.staging.toml target/.zeroclaw/config.toml
```
Example SHA-256 pin generation:
```bash
sha256sum tools/wasm/*.wasm
```
Then copy each digest into:
```toml
[runtime.wasm.security.module_sha256]
calc = "<64-char sha256>"
formatter = "<64-char sha256>"
```
## Local CI/CD (Docker-Only)
Use this when you want CI-style validation without relying on GitHub Actions and without running Rust toolchain commands on your host.
+6
View File
@@ -21,5 +21,11 @@ allowed_hosts = ["localhost:3000", "127.0.0.1:8080", "api.dev.internal"]
[runtime.wasm.security]
require_workspace_relative_tools_dir = true
reject_symlink_modules = true
reject_symlink_tools_dir = true
strict_host_validation = true
capability_escalation_mode = "clamp"
module_hash_policy = "warn"
[runtime.wasm.security.module_sha256]
# Pin digests by module name (without ".wasm") before promoting to enforce mode.
# calc = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+6
View File
@@ -21,5 +21,11 @@ allowed_hosts = []
[runtime.wasm.security]
require_workspace_relative_tools_dir = true
reject_symlink_modules = true
reject_symlink_tools_dir = true
strict_host_validation = true
capability_escalation_mode = "deny"
module_hash_policy = "warn"
[runtime.wasm.security.module_sha256]
# Production recommendation: pin all deployed modules and then set module_hash_policy = "enforce".
# calc = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
+6
View File
@@ -21,5 +21,11 @@ allowed_hosts = ["api.staging.internal", "cdn.staging.internal:443"]
[runtime.wasm.security]
require_workspace_relative_tools_dir = true
reject_symlink_modules = true
reject_symlink_tools_dir = true
strict_host_validation = true
capability_escalation_mode = "deny"
module_hash_policy = "warn"
[runtime.wasm.security.module_sha256]
# Populate pins and switch module_hash_policy to "enforce" after validation.
# calc = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"