Skip to content

Fluxheim 1.7.8

Choose a tag to compare

@eldryoth eldryoth released this 12 Jul 06:43
Immutable release. Only release title and notes can be modified.
v1.7.8
b5a0574

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-wasi feature through the root, config, server, and
    fluxheim-wasm crates.
  • Add the wasi-preview ABI and host-call namespace pair.
  • Add [wasm.plugins.wasi] with independent clocks and randomness grants,
    both disabled by default.
  • Add wasm.max_total_preview_concurrent_executions, defaulting to and capped
    at 32, 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 through sanitization.
  • 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 at max + 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
    protected prune operations. 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::SecretVec until 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-ng out of default and OpenSSL-only fluxheim-tls dependency
    graphs; it is now activated only by the Rustls key-parsing boundary.
  • Validate each declared wasi_snapshot_preview1 import before instantiation.
    Clock imports require clocks = true; random_get requires
    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_get call at 4096 bytes so guest-selected host work
    cannot request the full memory budget in one operation.
  • Restrict wasi-preview to access-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 native fluxheim-policy-v1 capacity.
  • 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 large Vec capacity growth before rejection.
  • Validate public GeoContext construction, 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 PATH handling 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 SafeRelativePath component 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 checked Instant deadline 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
    i32 inputs. 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.sh

Operator Notes

  • Build with wasm-wasi; the feature remains absent from default images and
    incompatible with privacy-mode.
  • Set [wasm].allow_preview_abi = true, then declare both
    abi = "wasi-preview" and host_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 explicit podman 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. See docs/config-snapshots.md for the
    fail-closed mixed-store and external anti-rollback requirements.
  • CIRCL Geo Open users should follow docs/geoip.md for 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.gz
    • 37021b43b385cdf4f8c8641da80f8938da42b09f0ea4cd1b2c525d6ca4acb2b6 fluxheim-1.7.8.zip
  • Binary checksums:
    • x86_64:
      • 3d521d8495ca375c5b294bc3ab1674113fb42cfc9077bd075c11af450c640ebd fluxheim-1.7.8-full-x86_64-linux.tar.gz
      • 946a782e943eff2f104795f76625874997ab70ea458cf3fcc0a997ff57563635 fluxheim-1.7.8-cache-x86_64-linux.tar.gz
      • 7e44296595f982aa160ef281510fa8496819a97696d4376583d229ea8d7afe03 fluxheim-1.7.8-proxy-x86_64-linux.tar.gz
      • 1d2e528611e33901fb05b22f451fbd7347ed26f8eafe942e41283ae136e69006 fluxheim-1.7.8-php-x86_64-linux.tar.gz
      • 82f91c9a5fc9e3d36825bfaaf309431e88675fb7a794b3400c26843634efa06d fluxheim-1.7.8-load-balancer-x86_64-linux.tar.gz
      • c2a62959de4cb0de5b4c6a702e669ff1229a9f01fd4ee31ec3dd842f9e9eefe9 fluxheim-1.7.8-config-tester-x86_64-linux.tar.gz
    • aarch64:
      • d5257311ba44dfc7b6b3f05121156d223e6dd74d8f2fb9bdb60d2d4fffeff55b fluxheim-1.7.8-full-aarch64-linux.tar.gz
      • 478238adfb07a7155a3cfd7d7a3fa16b618a5e166d47a4b6e8a7097e178d3627 fluxheim-1.7.8-cache-aarch64-linux.tar.gz
      • 281bafeb3275cab9c9b785582c80ba8d4198e6a560ad310fd3e2d4497437e18b fluxheim-1.7.8-proxy-aarch64-linux.tar.gz
      • 2a90707a5c626d17dbf108500955a859be10788f8cdfae0f6981b511ded32b23 fluxheim-1.7.8-php-aarch64-linux.tar.gz
      • d75e8c962cebf94bae16cecfb5f79e92f06bef48f8c7f94d1444193f1867301c fluxheim-1.7.8-load-balancer-aarch64-linux.tar.gz
      • b274e6cf61c67b9fa16bab7e00b13d3b44f9076deb21866e783e073bf37e46f9 fluxheim-1.7.8-config-tester-aarch64-linux.tar.gz
    • macos:
      • 2d4674caff67a3b2038ea6cc3550252ac57a1a7b31bb3564755d7c654da7a092 fluxheim-1.7.8-dev-aarch64-macos.tar.gz
  • SBOM checksums:
    • 4f4b406af1c8d2cea51dfb380131c36bbb71b2616fc719aa51af3c7178a40179 fluxheim.spdx.json
    • e6a666da528b7919c305287ce102f3acd43beb6ee4e9311eb448cd22b316bc61 fluxheim.cyclonedx.json
  • Reproducible build:
    • 177bd4c7d6858e52b69e0dfba08d15e7bc88efb342e700b15aa02542de6deb55 x86_64
    • b33ae8ebb600b229652eb35e78edd9f3aaa7c0602ded5f0fdea6db141fc1596c aarch64
    • f12ff88fb13f18251722babbfc7d8a336eb6980d033a3ff085903c52f518922f macos
  • 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
  • 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
  • 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
  • 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
  • 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
  • Tag signature:
    • Good "git" signature for 1921261+eldryoth@users.noreply.github.com with ED25519 key SHA256:EoLRQ5k4J5pYz3UMFmkrV798gYFNkToGS2xEPvebqB4