Skip to content

Commit 230dabd

Browse files
committed
Complete Wasm example build and acceptance workflow
1 parent b370f3c commit 230dabd

12 files changed

Lines changed: 143 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ behavior when the change improves security or project direction.
2323
route-policy coverage.
2424
- Complete the VCL-like cache-policy example gate with schema validation and
2525
live pass, variant, TTL, metadata, tag-purge, and negative mutation coverage.
26+
- Add a deterministic builder for all migration policies that emits real Wasm
27+
modules and SHA-256 sums under `target/`, plus one complete Wasm smoke shared
28+
by the human launcher and release gate.
29+
- Fix the human test starter's Wasm entry so sandbox and policy scripts are no
30+
longer passed as unused arguments to the registry validator.
2631

2732
### Security
2833

crates/fluxheim-wasm/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ wasi = ["runtime", "dep:wasmtime-wasi"]
1717
name = "wasm_sandbox_smoke"
1818
required-features = ["runtime"]
1919

20+
[[example]]
21+
name = "build_policy_examples"
22+
2023
[dependencies]
2124
sha2 = "0.11.0"
2225
thiserror = "2.0.18"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
use std::fmt::Write as _;
2+
use std::path::Path;
3+
use std::process::ExitCode;
4+
5+
use sha2::{Digest as _, Sha256};
6+
7+
const OUTPUT_DIR: &str = "target/wasm-policy-examples";
8+
const POLICY_SOURCES: &[(&str, &str)] = &[
9+
(
10+
"irules-access-policy",
11+
include_str!("../../../examples/wasm/irules-access-policy.wat"),
12+
),
13+
(
14+
"openresty-header-policy",
15+
include_str!("../../../examples/wasm/openresty-header-policy.wat"),
16+
),
17+
(
18+
"haproxy-spoe-routing-policy",
19+
include_str!("../../../examples/wasm/haproxy-spoe-routing-policy.wat"),
20+
),
21+
(
22+
"cache-lookup-policy",
23+
include_str!("../../../examples/wasm/cache-lookup-policy.wat"),
24+
),
25+
(
26+
"cache-store-policy",
27+
include_str!("../../../examples/wasm/cache-store-policy.wat"),
28+
),
29+
];
30+
31+
fn main() -> ExitCode {
32+
match build_examples() {
33+
Ok(()) => ExitCode::SUCCESS,
34+
Err(error) => {
35+
eprintln!("wasm policy example build failed: {error}");
36+
ExitCode::FAILURE
37+
}
38+
}
39+
}
40+
41+
fn build_examples() -> Result<(), Box<dyn std::error::Error>> {
42+
let output = Path::new(OUTPUT_DIR);
43+
std::fs::create_dir_all(output)?;
44+
let mut checksums = String::new();
45+
46+
for (name, source) in POLICY_SOURCES {
47+
let bytes = wat::parse_str(source)?;
48+
let file_name = format!("{name}.wasm");
49+
std::fs::write(output.join(&file_name), &bytes)?;
50+
let digest = Sha256::digest(&bytes);
51+
for byte in digest {
52+
write!(&mut checksums, "{byte:02x}")?;
53+
}
54+
writeln!(&mut checksums, " {file_name}")?;
55+
}
56+
57+
std::fs::write(output.join("SHA256SUMS"), checksums)?;
58+
println!("built Wasm policy examples in {OUTPUT_DIR}");
59+
Ok(())
60+
}

docs/wasm-policy-example-parity.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,9 @@ Before `1.7` is complete:
200200
- every example must have a matching negative test that proves the sandbox does
201201
not expose filesystem, network, env, admin APIs, secrets, request bodies, or
202202
raw cache objects without explicit future capabilities.
203+
204+
`v1.7.9` provides `scripts/build_wasm_policy_examples.sh` for deterministic
205+
source-to-module builds and digest output, while `scripts/smoke_wasm_all.sh`
206+
is the single orchestration entry used by both `scripts/test_starter.py` and
207+
the opt-in stable/deep release gate. This avoids treating multiple script paths
208+
as arguments to one launcher command and keeps human and CI coverage aligned.

examples/wasm/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@ These examples are source-level policy examples. Build the `.wat` files to
55
`wasm.plugin_roots`, and pin the module SHA-256 in config before enabling it in
66
production.
77

8+
Build every checked-in migration policy and generate exact SHA-256 digests
9+
with:
10+
11+
```sh
12+
scripts/build_wasm_policy_examples.sh
13+
```
14+
15+
The command writes real modules and `SHA256SUMS` under
16+
`target/wasm-policy-examples/`. Copy the required modules into a configured
17+
plugin root, replace each example config's digest placeholder with the emitted
18+
digest, and keep the deployed file owner-only or otherwise protected by the
19+
documented plugin-root trust policy. The builder has no output-path argument;
20+
it cannot be redirected into a configured production root accidentally.
21+
822
`irules-access-policy.wat` and `irules-access-policy.toml` demonstrate the
923
F5 iRules-style access-policy mapping. Fluxheim first classifies the request
1024
through configured vhosts, routes, methods, trusted-client ACLs, and TLS

packaging/rpm/fluxheim.spec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ fi
160160
- Add the nginx Lua/OpenResty-style bounded header-policy example.
161161
- Add the HAProxy Lua/SPOE-style bounded route and load-balancer example.
162162
- Complete the VCL-like cache-policy example and live operational smoke.
163+
- Add deterministic Wasm example builds and one shared complete Wasm gate.
163164
- Harden snapshot opens against pathname races and isolate corruption fixtures
164165
behind safe store primitives.
165166

release-notes/RELEASE_NOTES_1.7.9.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ products.
2727
parity example. The live smoke now proves pass, MISS/HIT, bounded variants,
2828
image-only TTL/tag/header metadata, expiry, tag purge, non-image isolation,
2929
and fail-closed invalid mutations.
30+
- Add a deterministic policy builder that emits deployable `.wasm` files and
31+
`SHA256SUMS` under `target/wasm-policy-examples/`.
32+
- Add one complete Wasm smoke shared by `scripts/test_starter.py` and the
33+
opt-in stable/deep release gate, fixing the launcher's previous multi-script
34+
command wiring.
3035

3136
## Security
3237

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/env sh
2+
set -eu
3+
4+
output="target/wasm-policy-examples"
5+
6+
cargo run --locked -p fluxheim-wasm --example build_policy_examples --quiet
7+
8+
for name in \
9+
irules-access-policy \
10+
openresty-header-policy \
11+
haproxy-spoe-routing-policy \
12+
cache-lookup-policy \
13+
cache-store-policy
14+
do
15+
test -s "$output/$name.wasm"
16+
grep -q " $name.wasm$" "$output/SHA256SUMS"
17+
done
18+
19+
(cd "$output" && sha256sum -c SHA256SUMS)
20+
21+
echo "wasm policy example build: ok"

scripts/smoke_wasm_all.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env sh
2+
set -eu
3+
4+
scripts/build_wasm_policy_examples.sh
5+
scripts/validate-wasm-config-registry.sh
6+
scripts/smoke_wasm_sandbox.sh
7+
scripts/smoke_wasm_policy_examples.sh
8+
9+
echo "wasm complete smoke: ok"

scripts/stable_release_gate.sh

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,8 @@ else
131131
fi
132132

133133
if [ "${FLUXHEIM_GATE_WASM:-0}" = "1" ]; then
134-
echo "stable release gate: Wasm config registry and sandbox smoke"
135-
scripts/validate-wasm-config-registry.sh
136-
scripts/smoke_wasm_sandbox.sh
137-
scripts/smoke_wasm_policy_examples.sh
134+
echo "stable release gate: complete Wasm smoke"
135+
scripts/smoke_wasm_all.sh
138136
else
139137
echo "stable release gate: skipping Wasm sandbox smoke; set FLUXHEIM_GATE_WASM=1 to enable"
140138
fi

0 commit comments

Comments
 (0)