Fluxheim 1.7.8
Fluxheim 1.7.8 Release Notes
Fluxheim 1.7.8 starts the optional WASI Preview 1 capability boundary for
non-request-body policy plugins. This is a narrow access-decision preview, not
general-purpose WASI application hosting.
Added
- Propagate the
wasm-wasifeature through the root, config, server, and
fluxheim-wasmcrates. - Add the
wasi-previewABI and host-call namespace pair. - Add
[wasm.plugins.wasi]with independentclocksandrandomnessgrants,
both disabled by default. - Add
wasm.max_total_preview_concurrent_executions, defaulting to and capped
at32, for both WASI and proxy-ABI preview access hooks. - Add real WASI modules proving explicit randomness and clock grants work under
the normal Fluxheim sandbox. - Add live native HTTP/1 coverage proving a granted WASI policy continues into
normal route handling while an ungranted import fails closed before origin
dispatch. - Add a checked-in WASI randomness policy/config example and include it in the
standalone Wasm smoke. - Restore native-request GeoIP context lookup using the trusted-proxy-aware
client address for HTTP/1 and HTTP/2 policy evaluation. - Decode CIRCL Geo Open combined Country and ASN databases, including their
provider-specific string ASN field. - Add an opt-in, checksum-pinned CIRCL real-database smoke proving country and
ASN policy on static, direct-proxy, and load-balanced request paths.
Security
- Normalize IPv4-mapped and IPv4-compatible IPv6 DNS results before stream
rebinding checks, closing access to embedded loopback, private, link-local,
metadata, carrier-grade NAT, benchmark, and other reserved IPv4 addresses. - Keep both stream copy directions in persistent pinned futures and drive one
shared idle deadline from their latest successful transfer. Partial writes
can no longer be cancelled and silently discarded when reverse traffic wins
the dispatcher race. - Clear each successfully forwarded plaintext prefix and clear complete stream
copy buffers on drop throughsanitization. - Reject zero, oversized, or overflowing weighted-stream totals inside
StreamUpstreamSelector, preserving the config limits at the public runtime
construction boundary. - Make configuration snapshots transactional and recoverable with mutation-wide
private locking, explicit parent/generation history, create-new publication,
temporary/orphan cleanup, retryable rollback, persisted self-healing state,
redacted invalid-ID diagnostics, and typed clock errors. - Add optional HMAC-SHA-256 manifests backed by an external bounded key file.
Config and metadata are verified before rollback parsing; legacy stores are
reported as unverified rather than silently authenticated. - Persist an authenticated generation high-water mark and per-manifest
generation witnesses so pruning cannot reuse audit generations and freshness
scans remain bounded without rereading complete snapshot configurations. - Preserve authenticated manifests created before generation witnesses. A
fully verified all-legacy store with no generation counter bootstraps from
its highest generation, persists authenticated state first, migrates its
manifests, and publishes the next snapshot atmax + 1. Missing state still
fails closed for V2 and mixed stores. - Route snapshot SHA-256 and HMAC-SHA-256 through the selected Ring,
OpenSSL-FIPS, or AWS-LC-FIPS provider, returning provider failures to the
administrative caller instead of aborting the data plane. - Require owner-only snapshot state and integrity-key files, keep integrity
keys outside the snapshot store, and authenticate intentional pruning
boundaries. - Add resilient listing plus snapshot
show,diff,verify,doctor, and
protectedpruneoperations. Snapshot TOML remains plaintext and needs
encrypted storage or backups when confidentiality is required. - Enforce OpenSSL cipher allow-lists across protocol families. A policy with
only TLS 1.3 suites disables TLS 1.2, and a policy with only TLS 1.2 suites
disables TLS 1.3, preventing inherited acceptor defaults from negotiating an
unconfigured suite. Move to OpenSSL's Mozilla v5 acceptor baseline so the
legacy v4 template cannot suppress configured TLS 1.3 listeners. - Replace synchronous rustls TLS-ALPN challenge loading on ClientHello with a
bounded, atomically replaced in-memory SNI certificate table. Remote
handshakes perform lookup only and cannot trigger file parsing or loader
logging. - Limit certificate chains to 1 MiB and 16 certificates, private-key files to
64 KiB, and client-auth CA bundles to 8 MiB and 4096 certificates in both
downstream TLS providers. - Keep transient rustls private-key PEM and decoded DER bytes in
sanitization::SecretVecuntil provider parsing completes. Read key files
directly into protected storage so partial I/O and concurrent-growth errors
also wipe initialized key bytes. - Decode Rustls private-key PEM payloads through base64-ng's staged
constant-time-oriented decoder and report only the redacted decode-error
class, never an offending secret-adjacent byte or input index. - Disable default provider features for rustls and tokio-rustls. Normal Ring
builds no longer include AWS-LC; AWS-LC remains explicitly selected by the
rustls FIPS profile. - Keep
base64-ngout of default and OpenSSL-onlyfluxheim-tlsdependency
graphs; it is now activated only by the Rustls key-parsing boundary. - Validate each declared
wasi_snapshot_preview1import before instantiation.
Clock imports requireclocks = true;random_getrequires
randomness = true. - Keep environment, arguments, inherited stdio, filesystem, sockets/network,
polling, and process-exit imports unavailable in this preview, regardless of
capabilities granted for clocks or randomness. - Build a fresh WASI context per execution without inherited process state.
- Cap each granted
random_getcall at 4096 bytes so guest-selected host work
cannot request the full memory budget in one operation. - Restrict
wasi-previewtoaccess-decision, require explicit preview-ABI
allowance, require pinned module digests for that security phase, and retain
fail-closed composition. - Include WASI grants in compiled-module identity equality so differently
authorized modules cannot share an identity. - Isolate preview hooks from native policy hooks with separate process-wide
admission and 32-slot blocking-work pools, preventing preview saturation
from consuming nativefluxheim-policy-v1capacity. - Apply one absolute PHP-FPM request deadline to request transmission and full
FastCGI response collection, discarding timed-out pooled connections. - Open managed PHP-FPM executables without following symlinks, validate the
opened file and every ancestor for trusted ownership and modes, and execute
through the retained descriptor to close path-replacement races. - Run each managed PHP-FPM pool in a dedicated process group and terminate the
complete group on shutdown, failed status checks, and watchdog restarts. - Unlink request-body spool files immediately after secure creation while
retaining a descriptor for retry replay. Give every reader an independent
logical offset backed by bounded positional reads so overlapping readers
cannot corrupt each other's request body stream. - Hold PHP memory bodies and bounded spool-read buffers in
sanitization::SecretVec, clear consumed spool buffers immediately, and
clear full buffer capacity on cancellation, error, or drop. - Read each verified GeoIP database into an exact admitted-length buffer and
probe growth with a separate stack byte, preventing a one-byte in-place
append from triggering largeVeccapacity growth before rejection. - Validate public
GeoContextconstruction, canonicalize accepted two-letter
ASCII countries to uppercase, and reject ASN zero before policy consumers can
observe malformed security state. - Replace inherited managed PHP-FPM
PATHhandling with a fixed allowlisted
search path after clearing the child environment. - Render unavailable directory-listing timestamps as
-after checked epoch
and year-9999 bounds, preventing attacker-influenced file metadata from
reaching panic-prone timestamp formatters in release builds. - Replace unchecked
SafeRelativePathcomponent insertion with a validating
single-normal-component API so the public type preserves its traversal-safety
invariant for current and future static-serving callers. - Enforce crate-level hard ceilings for Wasm module, memory, table, fuel,
execution-timeout, and compile-timeout limits, with matching config rejection
and checkedInstantdeadline arithmetic. - Reject Wasm admission values above Tokio's semaphore capacity before
constructing a semaphore, and create compilation workers through the fallible
named thread builder instead of the panicking convenience API. - Check the absolute execution deadline before and after every synchronous host
callback so late callback results fail as timeouts. Keep blocking callbacks
prohibited until a killable subprocess runner exists. - Require in-process native Wasm callbacks to be panic-free and total for every
guest integer, and property-test all current guest-ID decoders over arbitrary
i32inputs. Keep panic-prone or third-party native callbacks behind the
future subprocess-isolation boundary.
Validation
cargo test --locked -p fluxheim-wasm --features wasi
cargo test --locked -p fluxheim-config --features wasm-wasi wasm_wasi
cargo test --locked -p fluxheim-server --features wasm-wasi native_wasm_wasi
cargo test --locked -p fluxheim-stream
cargo test --locked -p fluxheim-snapshot
cargo test --locked -p fluxheim-tls --no-default-features --features tls-rustls,acme
cargo test --locked -p fluxheim-tls --no-default-features --features tls-openssl,acme
scripts/smoke_wasm_sandbox.sh
cargo test --locked -p fluxheim-php-fpm
scripts/smoke_wordpress_php_fpm.sh
scripts/smoke_fluxheim_php_wolfi.sh
scripts/smoke_geoip_circl.sh
scripts/smoke_admin_listener.shOperator Notes
- Build with
wasm-wasi; the feature remains absent from default images and
incompatible withprivacy-mode. - Set
[wasm].allow_preview_abi = true, then declare both
abi = "wasi-preview"andhost_call_namespace = "wasi-preview". - Grant only the capability the module imports. Unsupported imports are config
or execution errors and security-decision hooks fail closed. - This release does not grant request bodies, environment, filesystem, network,
stdio, arguments, or process-control access. - The clock grant exposes the full-resolution host clock. Avoid granting it to
untrusted multi-tenant plugins colocated with secret-dependent computation. - Document the rootless Podman ownership mapping required for trusted read-only
config mounts, including explicitpodman unshare chown, an opt-in:U
alternative, and an in-container verification command. - Existing authenticated snapshot stores created before generation witnesses
upgrade automatically on their next locked snapshot creation only when every
retained legacy manifest verifies. Seedocs/config-snapshots.mdfor the
fail-closed mixed-store and external anti-rollback requirements. - CIRCL Geo Open users should follow
docs/geoip.mdfor dataset attribution,
trusted installation, pinned checksums, schema details, and the opt-in live
database proof. The large network download remains outside normal CI gates.
Checksums And Signatures
- Commit:
b5a05744b994302cad28612fd542b3957478f794 - Local gate: GitHub CI green before tag; local release metadata checks passed
- CodeQL/code scanning: no open release-blocking alerts before tag
- Source archive checksums:
c3194178c40ed80c1343dd58d228c88355ce42b2e220771aa3e7e5ab3e5497a4 fluxheim-1.7.8.tar.gz37021b43b385cdf4f8c8641da80f8938da42b09f0ea4cd1b2c525d6ca4acb2b6 fluxheim-1.7.8.zip
- Binary checksums:
- x86_64:
3d521d8495ca375c5b294bc3ab1674113fb42cfc9077bd075c11af450c640ebd fluxheim-1.7.8-full-x86_64-linux.tar.gz946a782e943eff2f104795f76625874997ab70ea458cf3fcc0a997ff57563635 fluxheim-1.7.8-cache-x86_64-linux.tar.gz7e44296595f982aa160ef281510fa8496819a97696d4376583d229ea8d7afe03 fluxheim-1.7.8-proxy-x86_64-linux.tar.gz1d2e528611e33901fb05b22f451fbd7347ed26f8eafe942e41283ae136e69006 fluxheim-1.7.8-php-x86_64-linux.tar.gz82f91c9a5fc9e3d36825bfaaf309431e88675fb7a794b3400c26843634efa06d fluxheim-1.7.8-load-balancer-x86_64-linux.tar.gzc2a62959de4cb0de5b4c6a702e669ff1229a9f01fd4ee31ec3dd842f9e9eefe9 fluxheim-1.7.8-config-tester-x86_64-linux.tar.gz
- aarch64:
d5257311ba44dfc7b6b3f05121156d223e6dd74d8f2fb9bdb60d2d4fffeff55b fluxheim-1.7.8-full-aarch64-linux.tar.gz478238adfb07a7155a3cfd7d7a3fa16b618a5e166d47a4b6e8a7097e178d3627 fluxheim-1.7.8-cache-aarch64-linux.tar.gz281bafeb3275cab9c9b785582c80ba8d4198e6a560ad310fd3e2d4497437e18b fluxheim-1.7.8-proxy-aarch64-linux.tar.gz2a90707a5c626d17dbf108500955a859be10788f8cdfae0f6981b511ded32b23 fluxheim-1.7.8-php-aarch64-linux.tar.gzd75e8c962cebf94bae16cecfb5f79e92f06bef48f8c7f94d1444193f1867301c fluxheim-1.7.8-load-balancer-aarch64-linux.tar.gzb274e6cf61c67b9fa16bab7e00b13d3b44f9076deb21866e783e073bf37e46f9 fluxheim-1.7.8-config-tester-aarch64-linux.tar.gz
- macos:
2d4674caff67a3b2038ea6cc3550252ac57a1a7b31bb3564755d7c654da7a092 fluxheim-1.7.8-dev-aarch64-macos.tar.gz
- x86_64:
- SBOM checksums:
4f4b406af1c8d2cea51dfb380131c36bbb71b2616fc719aa51af3c7178a40179 fluxheim.spdx.jsone6a666da528b7919c305287ce102f3acd43beb6ee4e9311eb448cd22b316bc61 fluxheim.cyclonedx.json
- Reproducible build:
177bd4c7d6858e52b69e0dfba08d15e7bc88efb342e700b15aa02542de6deb55x86_64b33ae8ebb600b229652eb35e78edd9f3aaa7c0602ded5f0fdea6db141fc1596caarch64f12ff88fb13f18251722babbfc7d8a336eb6980d033a3ff085903c52f518922fmacos
- Full Build Container digests:
- Wolfi:
ghcr.io/valkyoth/fluxheim@sha256:65b0ec4b2a173abc0cea6739c00048ecbc2d8440778b4e395c5afe624c4e04e6 - Alpine:
ghcr.io/valkyoth/fluxheim@sha256:6462fa8bf2c5474c94a77a2464c181fc606888f4c5bf9c79fc25d7aac0024c9f - SUSE Micro:
ghcr.io/valkyoth/fluxheim@sha256:91ffb1f4ea1348c8af7715e3c28cd3e39767dbe048f3b40ed87bc99b926d6f1f - Debian:
ghcr.io/valkyoth/fluxheim@sha256:9584cba3b59d8930fa324b60bf71d2ec3d6d6ececfcc9eb03a47b6ea02447d43
- Wolfi:
- Cache Build Container digests:
- Wolfi:
ghcr.io/valkyoth/fluxheim@sha256:1d3c28a0375f12cf5c31bb6a461573c23ab931b77806372787564fcc9c4d70d5 - Alpine:
ghcr.io/valkyoth/fluxheim@sha256:01dfa51ae2faf669f02ac8aac615431cf3b42aa699713fdc04a74eccc80bf9d9 - SUSE Micro:
ghcr.io/valkyoth/fluxheim@sha256:133992977765501b643674e80e12a154723c309c090b856cd41a0654226ba360 - Debian:
ghcr.io/valkyoth/fluxheim@sha256:7e9fb73f6d6c8bc77aac11ea613f672c6a51131ffbb77574d79e3fb7cf3304e7
- Wolfi:
- Proxy Build Container digests:
- Wolfi:
ghcr.io/valkyoth/fluxheim@sha256:dce3f37b1b5054ee4bc885f7e97ec15f92db25bec9b9adc6c08833f1aad6e481 - Alpine:
ghcr.io/valkyoth/fluxheim@sha256:3286412105f05db0da33a8ae3b40a08785f65e0e4a51189118c4a51122bbcb42 - SUSE Micro:
ghcr.io/valkyoth/fluxheim@sha256:0f21d68713e8125e856f6606c44005a64feb66fc779b3c4c0fec3dc6963f85ec - Debian:
ghcr.io/valkyoth/fluxheim@sha256:546f1c0f62184dde3cb9ce21a283acfd71b7dbe6356637e6a4716af5e61f91b6
- Wolfi:
- PHP Build Container digests:
- Wolfi:
ghcr.io/valkyoth/fluxheim@sha256:8fcf582d0ae1ac20771b7723700d03f2db64130d110bb39404975427a85e616f - Alpine:
ghcr.io/valkyoth/fluxheim@sha256:3a864626ac2c8de0c67cf2c3f65893fd89baa8167a1b7bc651fbac31d66bbb67 - SUSE Micro:
ghcr.io/valkyoth/fluxheim@sha256:51539343bf419842d88e494efc6dd5ebba41e65d4f6ed06dfd71b6aedd5359d7 - Debian:
ghcr.io/valkyoth/fluxheim@sha256:0e1ce1e37f295e7c392f245a2b5b217ff5b504efe83841df00577f1b2aa05fe7
- Wolfi:
- Load Balancer Build Container digests:
- Wolfi:
ghcr.io/valkyoth/fluxheim@sha256:07803a0d072eb0a1c7117f78dc0e19cf078b7edf7c78f64f9171da4884f23785 - Alpine:
ghcr.io/valkyoth/fluxheim@sha256:5efed1e1d711b6e199031e386b8503b2150606c0835d80fb87a3a32800d4f968 - SUSE Micro:
ghcr.io/valkyoth/fluxheim@sha256:9015d89b4620f7cc9709a62ffb2ea9f0eb487b378cd87cfd3a0118704c1f2491 - Debian:
ghcr.io/valkyoth/fluxheim@sha256:43737bc3084861045f957571e26ab1b1c55db40d217f27f4393f602bff7f961d
- Wolfi:
- Tag signature:
Good "git" signature for 1921261+eldryoth@users.noreply.github.com with ED25519 key SHA256:EoLRQ5k4J5pYz3UMFmkrV798gYFNkToGS2xEPvebqB4