This roadmap is the working implementation plan. Keep it current as features move from design to code.
Release sequencing is defined in Versioning Plan.
That plan treats 0.5.x as the basic-sites preview and 1.0.0 as the first
gateway-ready release for Fluxheim's representative real multi-site configs.
Larger modules still graduate through later minor releases.
Fluxheim 1.6.x is the Pingora-exit line. Its goal is to remove Pingora from
every normal Fluxheim build by replacing the server/listener/TLS, cache,
load-balancer, stream, HTTP type/error, upstream pooling, and HTTP proxy runtime
boundaries with Fluxheim-owned crates and standard Rust protocol libraries,
while preserving behavior with baseline evidence and parity fixtures.
Historical milestones:
Fluxheim 1.0.0 was the first gateway-ready baseline: static sites,
SNI-backed TLS vhosts, route redirects, location-style proxying,
websocket-safe proxy headers, directory listing, static aliases, cleartext ACME
challenge exceptions, default HTTP service packaging, and native systemd
deployment.
Fluxheim 1.1.0 added TLS policy hardening plus ACME runtime issuance and
renewal for Let's Encrypt and Actalis, so deployments do not depend on manual
certificate copy scripts.
The 1.2.0 cache-server baseline delivered route/vhost scoped cache policies,
memory/disk/tiered storage, request collapsing, protected purge/status
operations, cache warm and inspection commands, Prometheus/OpenTelemetry
visibility, and production Podman/ACME migration notes.
The 1.2.1 follow-up added focused opt-in local/static vhost caching so local
[vhosts.web] files and route-scoped web actions can use the same cache policy
model as proxied static content when operators explicitly enable it. The
1.2.2 line added slab/bin disk storage through
cache.disk.backend = "storage-bin" with allocator, durable index, and runtime
backend selection. 1.2.3 added optional cache encryption at rest, including
local-key and OpenBao Transit key providers plus an optional Podman/OpenBao
Transit smoke path, without forcing OpenBao on normal deployments. 1.2.4
added distributed cache metadata and peer-fill, 1.2.5 added exact bounded
range caching, and 1.2.6 added fixed-slice range composition.
1.3.0 starts the shared ingress/TLS feature-graph split so focused images can
be honest and TLS-capable without dragging in unrelated web, proxy, cache, or
load-balancer modules. 1.3.1+ is planned as the PHP
application-server line. Its first stable target is a secure php-fpm
FastCGI bridge for WordPress-style and legacy PHP deployments, with PHP
remaining disabled by default and selected only through explicit compile-time
features and per-vhost config. 1.3.2 is reserved for focused operations
improvements: an ACME companion-agent model so adding a new
managed-certificate vhost can move from pending issuance to active HTTPS
without a second manual gateway restart, plus downloadable
fluxheim-config-tester release assets for diagnosing configs when a container
cannot start.
1.3.7 continues the production PHP-FPM line with managed php-fpm process
supervision as an opt-in runtime mode under the existing php-fpm feature.
Pure-Rust PHP/phprs support is no longer planned for the 1.3 line; managed
php-fpm now covers the zero-admin PHP deployment goal without adopting an
immature interpreter. Turbine-style PHP app servers stay reverse-proxy upstreams
unless a future embeddable library API proves safer than that boundary.
1.4.0 is the production proxy parity release. Its target is the first set of
operational features operators expect when migrating from NGINX, HAProxy,
Envoy, or Caddy: rate limits, connection limits, IP ACLs, response compression,
advanced upstream selection, passive health/outlier detection, mTLS/client
certificate authentication, PROXY protocol, gRPC-safe HTTP/2 proxying,
structured access logging, host/header/cookie/redirect rewrite policy, upstream
TLS controls, active HTTP health checks, retry budgets, and connection/socket
tuning. The next 1.4.1 proxy-operations release owns the remaining discovery,
mirroring, richer rewrite, local operational visibility, and typed hook-point work.
The highest-value NGINX migration items are now explicitly first in that queue:
regex path routing first as bounded route matching, then capture-aware rewrites,
method-based routing, WebSocket/HTTP upgrade verification, and
auth_request-style external authorization subrequests. Bounded regex and
method route matching, explicit HTTP/1.1 websocket/upgrade proxying, the first
bounded auth_request subrequest hook, safe bodyless traffic mirroring, and the
first read-only Unix ops socket are the first implemented slices of this queue.
Regex routing should remain off by default and require an explicit global config
opt-in, for example server.regex_enabled = true, before any vhost or route can
use regex matchers or capture-aware rewrites. Follow-up 1.4.2 work
should cover optional GeoIP
as a bounded Geo-Context foundation before the later enterprise load-balancer
track: local MaxMind GeoIP2/ASN databases, safe path loading, atomic context
replacement on config reload, country/ASN route and ACL decisions, privacy
controls, and low-cardinality observability. The larger geo-policy ideas -
background MMDB downloading, remote lookup sidecars, adaptive rate-limit
weighting, programmable Rhai/Wasm logic, and impossible-travel anomaly engines -
are explicitly later work after the typed context is stable. The rest of
1.4.2 covered maintenance architecture, 1.4.3 split the config surface,
1.4.4 added Apple Silicon developer support, 1.4.5 added bounded
Geo-Context, 1.4.6 added the TCP stream proxy foundation, and 1.4.7
hardened streams with true per-read stream idle timeout, stream upstream
TLS/mTLS, transport-neutral stream load-balancer policy, and stronger stream
smoke/security coverage. UDP proxying and HTTP/2 server push are intentionally
deferred/skipped until a concrete requirement makes them worth the extra attack
surface.
Each 1.4.x release has a hard stop. New feature families should move to the
next planned version unless they are required to make an already-in-scope item
safe.
Palo Alto-style security asks are tracked as policy integrations around this
proxy surface: reputation/Geo decisions, TLS fingerprint signals, and future
WAF/App-ID-like classification hooks without turning Fluxheim into a full
firewall.
1.5.0 is now the active enterprise load-balancer/control-plane line after the
1.4 proxy and stream primitives. Its stop line is F5 LTM / HAProxy / Envoy
class HTTP/TCP load-balancer operations, not a full BIG-IP platform. It should
promote the load-balancer image profile, add runtime pool/member mutation,
priority groups, slow-start, persistence, richer active/adaptive health,
circuit breaking, queue and overflow behavior, locality/failure-domain policy,
admin/audit visibility, and migration fixtures. Selection work should cover
weighted least-connections, ratio/weighted least-connections, least-time/EWMA,
consistent hash/Ketama, Maglev, bounded-load consistent hashing, least
sessions where persistence tables exist, and dynamic-ratio/external load score
only after trusted input, audit, and failure semantics are defined. TLS
passthrough SNI routing belongs in this line only after a bounded ClientHello
preread parser and byte-replay model are proven. xDS/Kubernetes/Consul
discovery is a later control-plane slice after local DNS/file discovery and
runtime backend mutation are stable. UDP proxying and DNS/GSLB are not 1.5.0
goals, but they are valid 1.5.x follow-up tracks once the HTTP/TCP
load-balancer control plane is stable. WAF/ASM, VPN, firewall, NAT appliance,
and iRules-compatible scripting are separate future module families, not
load-balancer spillover.
1.5.x follow-up candidates after 1.5.0:
UDP proxying as a separately bounded transport track with explicit targets
such as DNS UDP load balancing, syslog UDP forwarding, QUIC pass-through, or
game-server UDP proxying; DNS/GSLB traffic steering as a separate control-plane
track for health-aware DNS answers, regional policy, TTL behavior, failover,
and DNSSEC/evidence requirements; and xDS/Kubernetes/Consul discovery after
runtime backend mutation has proven safe locally.
1.6 is the Pingora-exit release line. It starts with baseline evidence,
crate-boundary policy, runtime parity fixtures, dependency exception gates, and
small Fluxheim-owned runtime proof primitives, then removes Pingora dependency
surface profile by profile. The remaining 1.6.x work is intentionally split
into smaller checkpoints instead of one risky proxy cutover: native HTTP/1.1
upstream connector/pooling parity, upstream TLS/mTLS and discovery parity,
native HTTP/2 upstream safety, simple native proxy/static/PHP cutover,
full official-profile cutover, HTTP/2 downstream parity proof, explicit
compatibility-blocker evidence, route/policy parity, rich proxy integration
parity, a release checkpoint for the native runtime/load-balancer/PHP/H2 work,
a focused proxy-cache parity release, final Pingora dependency removal, a
security-only stabilization release, and then nginx/Ketama-compatible
load-balancer hash polish. The
1.6.25 slice begins route/policy parity with a native exact/prefix/fallback
route-proxy primitive, and 1.6.26 adds native route redirects, route body
limits, and route response-header overlays while keeping richer policy
integrations in the following checkpoints.
The line
should keep behavior stable while moving code into focused crates where that
reduces review surface. Shared Wasm
extensibility moves to 1.7; it should cover the operational jobs normally
solved with F5 iRules, nginx Lua/OpenResty, HAProxy Lua/SPOE, and VCL-style
cache logic, but only after the Pingora-free runtime boundary is stable. HTTP/3
and QUIC move behind a new 1.8 cross-platform production line.
1.8.x should make macOS and Windows as close to Linux parity as practical
before Fluxheim adds another protocol surface: same public build profiles where
the platform semantics allow them, regular CI, live smoke tests, platform-safe
runtime paths, service/install integration, release assets, and security
reviews for filesystem, ACL, symlink, certificate/key, and process-supervision
behavior. macOS production support should target Apple Developer ID signed and
notarized artifacts, with a signed/notarized .pkg, a Homebrew formula/cask
path, or both. Windows production support should target Authenticode-signed
artifacts and a real installer path: prefer MSIX/App Installer or Microsoft
Store publication only if the Store model fits Fluxheim's server/service
behavior; otherwise use a signed MSI or signed zip plus documented Windows
service installation. HTTP/3 and QUIC become the following 1.9 line after
cross-platform release evidence is stable.
After Pingora is removed from normal builds, add a native
nginx/Ketama-compatible consistent-hash selection mode implemented by
Fluxheim, not by depending on pingora-ketama. The current Fluxheim-owned
rendezvous consistent-hash modes should remain available because they are
valid and per-boot-secret hardened, but operators migrating from nginx should
also have an explicit compatibility mode whose request-to-backend mapping
matches nginx-style consistent hashing.
Future "edge firewall" and "TLS VPN gateway" modes are realistic only as
separate product modes, not as accidental load-balancer options. They would
need dedicated compile profiles, threat models, packet/routing ownership,
kernel capability policy, audit logging, key management, and platform-specific
test matrices. Track them as research until the proxy/load-balancer/Wasm
surfaces are stable.
In-process Linux seccomp/Landlock sandboxing is also post-1.0 work: the
stable 1.0 boundary is hardened systemd/container deployment, while
kernel-enforced in-process sandboxing should remain an optional compile-time
module until path and syscall policies are proven across native and container
deployments.
Operational and admin tooling follows once the public TLS and certificate lifecycle surface is configurable and tested.
Before the next feature lines grow further, Fluxheim needs a focused
feature-graph cleanup: shared ingress, TLS, ACME, admin/config validation, and
observability should be independent building blocks, while web, cache,
proxy, and load-balancer should compile only their own behavior. Today,
some profile aliases still pull in convenience modules such as web for cache
or load-balancer images. The target is focused images and feature aliases:
full, web, cache, proxy, and load-balancer, all TLS-capable where
that makes sense, with CI checks proving unrelated modules are absent unless an
operator explicitly compiles them in.
Future differentiating features should lean into infrastructure problems that
are hard to solve safely with external glue: cluster-wide state, identity-aware
routing, AI-aware request controls, traffic mirroring, and encrypted
inter-node transport. These are not 1.0 items. Each one needs an explicit
compile-time feature, a documented threat model, redaction/privacy rules, and
failure-mode tests before it can move from research to beta.
Fluxheim should also grow a small Rust application-side companion crate after
the proxy and load-balancer control surfaces are stable. The working name is
fluxheim-sdk, not fluxheim-app, so its purpose is clear: typed integration
helpers for applications running behind Fluxheim. The first stable surface
should stay boring and low-risk: health/drain response schemas, Tower/Axum
extractors for Fluxheim-trusted request context, request-id/tracing helpers,
cache-control helpers, and an authenticated cache-purge/admin client. Do not
start with app self-registration, dynamic weight changes, UDP heartbeats, or
persistent control streams; those belong only after the 1.5 runtime backend
management model has authentication, audit logs, replay protection, and failure
semantics.
Crate naming matters. The main project should keep control of the canonical
fluxheim package name if Fluxheim is ever published as a crate, while the
application integration crate should be fluxheim-sdk. Avoid publishing empty
placeholder crates; if names are claimed on crates.io, they should contain real
project-owned packages with clear README text pointing to the correct binary
and SDK roles.
Keep the SDK code in a clearly split directory from the proxy implementation,
for example crates/fluxheim-sdk/, with its own Cargo.toml, README, tests,
and public API boundary. The initial workspace setup may live in this
repository for shared CI and review, but the layout should make it possible to
move fluxheim-sdk into its own GitHub project later without untangling proxy
internals.
Farther down the line, Fluxheim should also grow a dependency-reduction track:
once the major web, cache, PHP, proxy, load-balancer, and extension surfaces are
stable, move bounded Fluxheim-specific logic in-tree and keep large external
engines behind Fluxheim-owned interfaces. This must not compromise feature
parity or security. In the 1.4 and 1.5 work, prefer small local
implementations for queue policy, load-balancer algorithms, persistence state,
rewrite helpers, and typed variable evaluation when they are easy to review;
standardize Fluxheim-owned modules on Rust http crate types and a
Fluxheim-owned error taxonomy where Pingora wrappers are only adapter glue; add
Fluxheim-owned interfaces around subsystems that are already mostly Fluxheim
code, such as cache storage, before trying to replace mature external protocol
engines;
keep mature crates for TLS, cryptography, complex protocol state machines,
async runtime behavior, compression, and parsers until a later milestone can
prove a replacement safer.
The 1.5.5 HTTP/error boundary work intentionally stops before runtime-heavy
cleanup. Remaining plain io::Result / Pingora adapter paths in PHP-FPM
process supervision and body spooling, stream connect/copy/shutdown helpers,
upstream TLS material loading, and load-balancer factory/background wiring are
tracked in the future native stream, load-balancer core, server/listener/TLS,
and HTTP proxy runtime milestones instead of being treated as forgotten
leftovers.
After the smaller 1.5 dependency-reduction work, 1.6 owns the larger
architecture cleanup: a Fluxheim-owned server bootstrap/listener/TLS runtime to
replace Pingora Server, service registration, signal handling, hot-restart fd
passing, and TLS listener configuration where that control is worth the
complexity; plus a Fluxheim-owned HTTP proxy runtime to replace Pingora
ProxyHttp/Session with a linear request/response pipeline. The work is split
across the 1.6.x line with baseline and parity gates instead of being treated
as incidental cleanup.
Active load-balancer health checks should grow in focused slices before the
larger protocol/runtime work: first close the HTTP request-header gap, add the
standard gRPC Health Checking Protocol, add simple JSON field validation for
structured health bodies, and support bounded health-derived degraded weights
such as X-Health-Weight; later add opt-in local exec/agent checks with strict
no-shell/no-ambient-env rules; then add database/service protocol probes such
as Redis PING, PostgreSQL readiness, MySQL handshake/readiness, and carefully
bounded SMTP/LDAP/custom send-expect monitors for stream/database proxy use
cases.
PHP execution is the next application-server milestone after the 1.3.0
ingress/TLS split. It must stay disabled by default and compile only through
opt-in feature flags because PHP support changes Fluxheim's threat model from
static/proxy serving to dynamic code execution. The 1.3.1 path is
php-fpm/FastCGI first. 1.3.2 is an operational detour for the
fluxheim-acme companion-agent model, smooth zero-downtime first issuance, and
release-page config tester binaries for host/container diagnostics.
Embedded or pure-Rust PHP runtimes are not planned for the 1.3.x line.
Revisit only if an interpreter or embedded runtime has mature compatibility,
security, and maintenance evidence.
Legacy Perl CGI execution is also post-MVP application-server work. It should be modeled as a separate opt-in compile feature from PHP, disabled per vhost by default, and implemented with strict process isolation before it is exposed to operators.
Legacy HTTP/1.0 and HTTP/0.9 support is future experimental compatibility work for isolated industrial or research devices only. It must never be compiled into the default binary and must never run on Fluxheim's normal proxy, cache, admin, PHP, or CGI paths. The modern protocol direction remains HTTP/1.1, HTTP/2, and future HTTP/3/QUIC support with strict request parsing.
These are realistic additions to implement across the stable core and early
1.x releases:
-
Pingora Process Settings
- Map Fluxheim config into Pingora process settings: worker threads,
daemon mode, PID file, error log, upgrade socket, graceful shutdown
timeout, upstream keepalive pool size, and max retries.
Initial safe numeric mapping is implemented through
[server.process]fordaemon,error_log,pid_file,upgrade_sock,threads,listener_tasks_per_fd,work_stealing,upstream_keepalive_pool_size,max_retries,grace_period_seconds, andgraceful_shutdown_timeout_seconds. - Validate rootless/container-friendly paths and defaults. Implemented for PID file, upgrade socket, and optional error log by reusing Fluxheim's symlink/traversal runtime-path validation.
- Extend reload impact classification so process-owned settings require a
Pingora process upgrade. Implemented for
[server.process].
- Map Fluxheim config into Pingora process settings: worker threads,
daemon mode, PID file, error log, upgrade socket, graceful shutdown
timeout, upstream keepalive pool size, and max retries.
Initial safe numeric mapping is implemented through
-
Access And Error Logging
- Add typed access-log config with secure defaults. Initial
logging.access.enabledsupport is implemented. - Apply
logging.levelandlogging.formatduring startup throughenv_logger, while still lettingRUST_LOGoverride the configured default filter. Runtime log level/format changes require a process upgrade. - Add typed stream sink selection for OS/container logs. Implemented as
logging.target = "stderr" | "stdout"; changes require a process upgrade. - Add an optional local file sink with explicit append/truncate behavior,
safe path validation, no final symlink following on Linux, and
privacy-moderejection. Implemented as[logging.file]. - Emit structured request logs from the Pingora
logginghook with method, optional host, vhost, optional query-free path, status, request ID, request body bytes seen, response body bytes seen, low-cardinality status class, error flag, and latency. Initial stdout/stderr-compatible JSON event emission is implemented through the existinglogstack and is compiled out inprivacy-mode. - Allow operators to suppress raw request hosts and paths while keeping
access logs enabled. Implemented as
logging.access.include_hostandlogging.access.include_path. - Broaden response byte accounting if later response paths bypass Pingora's response body filter or static file accounting.
- Keep log sinks simple at first: stderr/stdout and optional file path.
Implemented for stderr/stdout plus
[logging.file]; async/remote sinks remain future work. - Implement the staged structured logging plan in Logging Architecture.
- Use
tracingas the core event system, with JSON output for production andlogcompatibility while legacy modules still uselog. - Split log classes into access, error, security, and audit events.
- Add a bounded async dispatcher so request workers do not perform slow disk or network writes directly.
- Make queue overflow behavior explicit:
drop_new,block, or durablespool. Do not claim both zero latency and zero data loss without durable spooling. - Add optional remote TCP/TLS sink with a circuit breaker and stdout/spool fallback.
- Redact secrets by default: authorization headers, cookies, admin tokens, ACME/EAB secrets, and configured sensitive fields.
- Add optional OpenTelemetry tracing as a separate observability module. Architecture and security plan documented in OpenTelemetry Tracing.
- Tracing must be compile-time gated and disabled by default. Planned
features:
otel-tracing: W3C Trace Context propagation, trace-log correlation, and internal request spans.otel-otlp: optional OTLP exporter to a local collector.
- Start with propagation-only support: extract valid
traceparent, generate a trace ID when absent, inject context into upstream requests, and include trace IDs in structured logs when logging is enabled. - Add spans after propagation is stable: vhost routing, request filtering, auth request, cache lookup/store, upstream selection/connect/response, static file reads, and future body filters.
- Add sampling before export is marked beta: probabilistic sampling for
normal traffic, optional all-
5xxsampling, and latency-aware sampling for slow requests. - OTLP export must run through bounded background queues, expose exporter health, redact attributes, and never block request workers when the collector is down.
- Tracing attributes must be low-cardinality and redacted: use vhost, route, status class, cache tier, upstream pool, and policy names; avoid raw queries, cookies, authorization values, bodies, and arbitrary path labels.
privacy-modeshould reject tracing/export features unless a future strictly propagation-only privacy design is written and tested.
- Add typed access-log config with secure defaults. Initial
-
Header Policy
- Add configurable upstream forwarding headers:
X-Forwarded-For,X-Forwarded-Host,X-Forwarded-Proto, and standardizedForwarded. Implemented globally for proxied requests through[headers.request]; spoofable inbound client-IP headers are stripped by default, Fluxheim replacesX-Forwarded-Forfrom the observed peer address, and RFCForwardedremains opt-in. - Add configurable response hardening headers for static/proxied responses:
HSTS, CSP,
X-Content-Type-Options, frame policy, and referrer policy. Implemented globally for proxied and static responses through[headers.response]; HSTS and CSP are opt-in, whilenosniff, frame denial, andno-referrerare defaulted. - Add generic header mutation blocks for both request and response stages:
unset,set, andappend. Implemented globally under[headers.request]and[headers.response]so operators can hide version headers such asServer/X-Powered-By, add CORS/cache headers, appendVary/Set-Cookie, or set proxy marker headers. - Add per-vhost header overlays. Implemented under
[vhosts.headers.request]and[vhosts.headers.response]; vhosts inherit global headers and can override booleans/modes or add moreunset/set/appendmutations. - Make trusted-proxy handling explicit before accepting client IP headers.
Implemented as
server.trusted_proxies; append mode preserves inboundX-Forwarded-Foronly when the direct peer matches a configured IP/CIDR. - Grow trusted-proxy handling into a typed client identity layer after the
1.0route core is stable. Fluxheim should keep separate values for the direct socket peer, verified proxy hop, restored client IP, and original forwarding chain instead of destructively overwriting one address field. - Future real-client identity features should include recursive
X-Forwarded-Fortraversal withmax_hops, provider-managed trusted range sets, Proxy Protocol v2 support, and optional IP context enrichment such as Geo/ASN/threat metadata loaded from local databases. All of this must be fail-closed around trust boundaries and incompatible withprivacy-modeunless a non-retaining design is written and tested.
- Add configurable upstream forwarding headers:
-
Modern Protocol Focus
- Keep normal Fluxheim ingress focused on modern, strictly parsed HTTP: HTTP/1.1 and HTTP/2 now, HTTP/3/QUIC as a future security/performance milestone.
- Treat HTTP/3 as separate from legacy support. HTTP/3 needs its own TLS, UDP, QUIC, ALPN, certificate, and deployment plan.
- Do not weaken the normal parser, proxy, cache, admin, PHP, or CGI paths to support legacy clients.
-
Request Body Streaming Limits
- Keep current
Content-Lengthenforcement. - Add streaming byte accounting for chunked/unknown-length bodies so request
body limits cannot be bypassed. Implemented in Pingora's
request_body_filter; every proxied body chunk is counted againstserver.limits.max_request_body_bytesand over-limit streams fail with413. - Add focused tests for chunked uploads, oversized streaming bodies, and normal uploads. Initial pure limit-counter tests cover exact-limit, over-limit, and saturating counter behavior; end-to-end upload tests remain future work.
- Keep current
5a. Proxy Response Buffering
- Add proxy response buffering and backpressure controls for migrations that currently rely on gateway buffer knobs for WordPress and app backends. The design should expose bounded per-connection response buffer count/size equivalents, clear defaults, streaming behavior when disabled, and tests proving slow clients cannot exhaust worker memory.
5b. Traffic Quotas And Rate Limits
- Add a typed traffic-control policy that can be applied globally, per
vhost, and per route. The first stable scope should cover common
production controls such as requests per second/minute, page views, visits
per day/month, total transferred bytes per day/month, and route-specific
caps such as
/chat/request or bandwidth budgets. - Policies must define the identity key explicitly: whole server, vhost, route, verified client IP, authenticated user, API key, or a future identity claim. Fail closed when a policy references an identity source that is unavailable.
- Use bounded local counters first for single-node installs, then design a distributed counter backend for clustered deployments. Global hard quotas that need exact consistency must not pretend to work correctly across multiple nodes without shared state.
- Expose clear actions for quota/rate failures:
429withRetry-After, static error page, JSON response for API clients, or redirect only where explicitly configured. Log and metric labels must stay low-cardinality. - Add observability from the start: current usage, remaining budget, reset time, dropped/rejected request counters, and per-policy decision logs with privacy-safe labels.
- Integrate with cache carefully: cache hits still consume page-view or bandwidth quotas when the operator asks for user-visible traffic limits, but backend-protection rate limits may count only cache misses or upstream attempts.
-
Load-Balancing Policy Options
- Keep round-robin as the stable default.
- Add explicit config for additional Pingora-supported policies where they are available and stable, starting with hash-based selection.
- Keep smart telemetry and WireGuard routing in Sentinel Mesh as a future design until the base load-balancer surface is stronger.
-
Operator Documentation
- Add a concise GitHub-facing project goals document.
- Add one “production checklist” that states what is MVP-ready and what is still experimental. Implemented in Production Readiness.
- Keep example configs in sync with every new global section.
- Improve config diagnostics for real multi-file deployments:
conf.dparse errors should include the source file path, validation errors should include vhost and route context where possible, and common TOML table-shape mistakes should get actionable hints. - Add production container migration docs from the
1.1gateway cutover: directpodman run --rmconfig validation and ACME commands, an HTTP-only first-issuance sequence for HTTP-01, explicit notes that Fluxheim must serve public port 80 during validation, container secret mount examples for EAB files, and safer optional error-page mount paths such as/var/lib/fluxheim/errorsinstead of nested paths below a read-only image directory. - Improve ACME command output for production runs: report per-target
skipped,renewed, andfailedstatus, include domain/order context on issuer failures, and print the HTTP-01 challenge path/URL when an authorization fails. Implemented for target statuses, per-target success/failure lines, due-only status messaging, and HTTP-01 URL context after challenge files are published. Planned: richer issuer authorization/order context when the client library exposes it cleanly. - Add native systemd deployment support before
1.0.0: a hardenedfluxheim.service, optional environment file, tmpfiles/sysusers guidance, documented install paths, config validation before start, and gracefulSIGTERM/reload behavior for manually compiled binaries. - Treat the packaged systemd unit as the stable
1.0host sandbox: non-root runtime user, no ambient capabilities, no-new-privileges, strict filesystem protection, private temporary/device namespaces, limited address families, namespace restrictions, and a conservative syscall filter.
-
Zero-Retention Privacy Build Profile
- Add a compile-time optional privacy profile for static web serving and
reverse proxying with no application-level request retention. Initial
privacy-modefeature is implemented and covered by the release check script. - Architecture and security plan documented in Zero-Retention Privacy Mode.
- Intended build shape:
cargo build --no-default-features --features proxy,web,tls-rustls,privacy-mode. - Privacy mode must disable access logs, remote logs, file logs, per-client metrics, disk cache, WAF audit logging, Cloudflare real-IP restoration, and any feature that stores or forwards client IPs by default.
- Fluxheim may still use peer IPs transiently in memory because TCP/TLS requires them. The guarantee is no Fluxheim application persistence of request logs, IP addresses, cookies, user agents, request IDs, or paths.
- Privacy mode must not add
X-Forwarded-For,Forwarded, or similar client-IP forwarding headers to upstreams. Implemented for the proxy request header policy: incoming forwarding headers are stripped even if config asks to synthesize forwarding headers. - Add release checks proving privacy builds do not compile metrics/logging
exporters and add tests that request handling does not emit or persist
client-identifying fields. Initial compile/test coverage exists for
proxy,web,tls-rustls,privacy-mode; exporter absence checks remain future work once logging exporters exist. - Plan a separate
privacy-cachedesign after the Fluxheim-owned cache interface work: public assets only, no client-IP cache keys, noCookie/Authorizationadmission, no per-user variants, noprivate/no-store/Set-Cookiestorage, strict query defaults, and memory or encrypted short-TTL disk storage as the preferred shape.
- Add a compile-time optional privacy profile for static web serving and
reverse proxying with no application-level request retention. Initial
Fluxheim should support a modern virtual-host configuration model inspired by Caddy's site blocks and global options, while keeping a strongly typed TOML format as the first implementation target.
Goals:
- A global server section for process-wide and listener-wide defaults.
- Multiple virtual hosts in one config file.
- Optional config-directory loading, similar to
conf.d, for local operations. Implemented for visible top-level*.tomlfiles loaded in sorted order. - Host/SNI based routing for proxy, static web, cache, TLS, and ACME behavior.
- Clear validation errors before startup.
- No implicit insecure inheritance across vhosts.
Initial TOML shape:
[server]
listen = ["0.0.0.0:80"]
tls_listen = ["0.0.0.0:443"]
worker_threads = "auto"
graceful_shutdown = "30s"
trusted_proxies = ["10.0.0.0/8", "192.168.0.0/16"]
[server.limits]
max_request_header_bytes = "64KiB"
max_uri_bytes = "8KiB"
max_request_headers = 100
max_request_body_bytes = "16MiB"
[headers.request]
enabled = true
strip_inbound_client_ip_headers = true
x_forwarded_for = "replace"
x_forwarded_host = true
x_forwarded_proto = true
forwarded = false
unset = ["x-powered-by"]
[headers.request.set]
x-proxy-by = "Fluxheim"
[headers.request.append]
via = "fluxheim"
[headers.response]
enabled = true
strict_transport_security = "max-age=31536000; includeSubDomains"
content_security_policy = "default-src 'self'"
x_content_type_options = "nosniff"
x_frame_options = "DENY"
referrer_policy = "no-referrer"
unset = ["server", "x-powered-by"]
[headers.response.set]
cache-control = "public, max-age=60"
[headers.response.append]
vary = ["Accept-Encoding"]
[tls]
enabled = true
backend = "rustls"
[tls.acme]
enabled = true
storage = "/var/lib/fluxheim/acme"
contact_email = "admin@example.com"
default_issuer = "letsencrypt"
challenge = "tls-alpn-01"
[[vhosts]]
name = "example.com"
hosts = ["example.com", "www.example.com"]
[vhosts.tls]
enabled = true
[vhosts.tls.acme]
enabled = true
[vhosts.web]
root = "/srv/sites/example"
index_files = ["index.html"]
deny_dotfiles = true
[vhosts.proxy]
upstreams = ["127.0.0.1:3000", "127.0.0.1:3001"]
[vhosts.proxy.load_balance]
max_iterations = 256
[vhosts.proxy.load_balance.health_check]
enabled = true
interval_secs = 1
consecutive_success = 1
consecutive_failure = 1
parallel = false
[vhosts.cache]
enabled = true
image_extensions = ["avif", "gif", "jpeg", "jpg", "png", "svg", "webp"]
methods = ["GET", "HEAD"]
max_object_bytes = "32MiB"
[vhosts.cache.memory]
enabled = true
max_size_bytes = "1GiB"
[vhosts.cache.disk]
enabled = false
path = "/var/cache/fluxheim/example.com"
max_size_bytes = "10GiB"Longer-term optional syntax:
{
listen 0.0.0.0:80 0.0.0.0:443
acme letsencrypt
}
example.com, www.example.com {
root /srv/sites/example
file_server
reverse_proxy http://127.0.0.1:3000
cache images
}
The Caddyfile-like syntax is a later adapter target. The internal source of truth should stay a typed Rust config model so tests can validate behavior without parsing text fixtures for every module.
-
Proxy Foundation
- Typed config loading and validation.
- Pingora
ProxyHttpruntime. - Plain HTTP upstream support.
- Optional TLS upstream support.
- Compile-time Pingora load-balancer module. Implemented with static round-robin pools.
- Pingora TCP health-check config. Implemented in the load-balancer module.
- Pingora background service registration for periodic load-balancer health checks. Implemented.
- Smart telemetry load balancer over WireGuard. Future design documented in Sentinel Mesh.
-
Static Web
- Secure static file resolution.
- Index files.
- MIME detection.
GETandHEADsupport.- Static
ETag,If-None-Match,If-Modified-Since, and singleRange/Content-Rangeresponse planning. Implemented. - Traversal, dotfile, and symlink escape tests.
- Pingora does not currently provide a ready-made static file server module. Continue using Fluxheim's checked file resolver on top of Pingora sessions.
- Evaluate Pingora
cache,connection_filter, response compression, and body filters as web-serving hardening/performance modules.
-
Virtual Hosts
- Add
[[vhosts]]config. Implemented. - Route by
Hostheader. Implemented. - Route by TLS SNI once downstream TLS lands.
- Keep backwards-compatible single-site config during migration.
- Add duplicate host detection. Implemented.
- Add fallback/default vhost behavior. Implemented with first-vhost fallback.
- Add explicit configurable default vhost. Implemented.
- Add wildcard host matching. Implemented for one-label
*.example.comhosts.
- Add
-
Global Server Settings
- Listener defaults. Implemented for TCP listener addresses.
- Worker/runtime settings.
- Timeouts.
- Request header limits. Implemented for URI length, header count, and approximate header bytes.
- Request body limits. Implemented for declared
Content-Length; streaming byte accounting remains. - Trusted proxy handling.
- Access log defaults.
-
TLS And ACME
- Compile-time TLS backend feature selection:
tls-rustlsortls-openssl, withtls-rustls-fipsandtls-openssl-fipscompliance variants.tls-boringsslandtls-s2nwere removed from the supported matrix in1.5.4. - Default to
tls-rustlsfor local/rootless portability. - Typed global TLS/ACME config. Implemented.
- Static certificate file config. Implemented.
- Let's Encrypt issuer config. Implemented.
- Actalis issuer config with External Account Binding env/file secret references. Implemented.
- Per-vhost certificate policy config. Implemented.
- ACME renewal queue policy config. Implemented.
- ACME renewal target discovery and queue scheduling. Implemented for config-derived targets and observed certificate expiration times.
- Reject ambiguous local
renew_afterdatetimes. Implemented; use full offset datetimes such as2026-06-01T00:00:00Z. - Safe certificate/key storage permission checks. Implemented for static certificates and ACME storage paths.
- Downstream TLS listener wiring. Implemented for explicit
server.tls_listenaddresses with the first global static certificate as the default certificate. - Config validation for downstream TLS listener prerequisites. Implemented:
TLS listener addresses require
tls.enabled = trueand a global static certificate or a default-vhost static/ACME certificate source. - Per-vhost/SNI downstream certificate selection. Implemented for the default rustls backend and callback-capable TLS backends.
- Future FIPS-capable TLS builds should be backend-specific and evidence
driven, not a generic marketing flag. Planned direction:
tls-rustls-fipsuses rustls' AWS-LC FIPS provider path and runtime FIPS checks;tls-openssl-fipsrelies on OpenSSL 3.x with a validated FIPS provider plus provider/default-property verification. BoringSSL and s2n are not supported Fluxheim compliance paths. FIPS profiles must stay separate from default builds and fail closed when the configured backend/provider cannot prove FIPS-required operation. The tracked compliance references are FIPS PUB 140-3, the current FIPS 140-3 Implementation Guidance, NIST SP 800-52 Rev. 2 for TLS policy, and the selected module's CMVP Security Policy. Fluxheim's job is to enforce FIPS-only TLS configuration, trigger and verify the selected provider's FIPS mode, and keep internal crypto operations on validated backends; operators remain responsible for the validated module installation, OS/container boundary, and Security Policy operating procedure. Seedocs/fips.mdfor the detailed post-1.3.4FIPS implementation ladder and operator evidence model. - Future Common Criteria evidence alignment should turn
docs/common-criteria-roadmap.mdinto actionable release artifacts: define a candidate TOE boundary, record security-relevant interfaces, maintain a Security Target-style draft, map Fluxheim controls to Common Criteria-style functional areas, and attach validation scripts to release evidence. This is product-evaluation evidence planning only; do not claim Common Criteria certification, Protection Profile conformance, or EAL compliance without an accredited evaluation. - Future Rust supply-chain hardening should add human dependency review on
top of the existing lockfile,
cargo-deny,cargo-audit, SBOM, and reproducible-build gates. Planned direction: adoptcargo-vetwith an explicitsupply-chain/policy, require review for new build scripts, procedural macros,*-syscrates, and native dependencies, and evaluatecargo-auditableor native embedded SBOM metadata for release binaries. Seedocs/supply-chain-security.mdfor the staged adoption plan.
- Compile-time TLS backend feature selection:
- ACME account/order/challenge runtime. Implemented as one-shot and
background
acme-clientpaths for HTTP-01. - Background renewal queue service. Implemented for due-only checks on the configured renewal interval.
- Runtime certificate adoption after renewal. Implemented for reloadable downstream SNI resolvers/callbacks.
- Production ACME companion mode. Scheduled for
1.3.2: keep the integrated background worker for simple installs, but add afluxheim-acmecommand/binary plusfluxheim-acme.serviceandfluxheim-acme.timerfor production renewals. The companion should run as the Fluxheim runtime user, reuse the same ACME engine, share only the ACME storage directory, and ask the running webserver over a local-only control channel to reload certificate handles after issuance. - Atomic certificate install and rollback on invalid renewed certificates. Implemented for the managed ACME install helper.
- Runtime certificate/config reload with snapshot swapping for no downtime.
- Reload impact classification. Implemented for snapshot-safe versus process-upgrade changes.
- CLI reload impact check. Implemented with
--reload-from OLD_CONFIGand--config NEW_CONFIG. - Durable config snapshot store. Implemented as a versioned on-disk config history under an operator-chosen state directory.
- Snapshot rollback command. Implemented for validated rollback to a chosen or previous config snapshot and durable current-pointer update.
- Admin live rollback. Implemented with
/_fluxheim/rollback?live=truefor snapshot-safe targets; process-upgrade targets return a conflict before the durable pointer is changed. - Self-healing rollback guard. Implemented known-good and pending-validation state for snapshot-safe reloads, protected confirm/fail endpoints, and fail-closed rollback when the validation window expires.
- Automatic self-healing watchdog. Implemented as a Pingora background service that enforces validation-window expiry without operator traffic.
- Health-signal self-healing. Implemented protected report endpoint for
external watchdog success/error signals, with
min_successful_checksandmax_error_rate_per_milleenforcement. - Proxy-integrated self-healing signals. Implemented: during pending validation, Fluxheim samples proxy outcomes directly. 2xx/3xx responses count as successful checks, while 5xx responses and fatal proxy errors count as failed checks and can trigger rollback through the existing self-healing guard.
- Admin/control API for reload, snapshot, rollback, and health state. Planned on a localhost-only listener by default, with auth required before remote exposure.
- Admin/control API typed config. Implemented with secure defaults: disabled by default, loopback listener, token env/file auth source, snapshot store path, and self-healing validation window settings.
- Admin/control API service. Implemented as a Pingora HTTP service on the configured admin listener with unauthenticated local health, bearer-token-protected status, snapshot listing, snapshot creation, and durable rollback-pointer updates.
- Admin/control API live reload endpoint. Implemented for the durable current
snapshot when the reload classifier returns
nooporsnapshot; returns a conflict for process-upgrade-only changes.
- Cache
- Typed global and per-vhost cache config. Implemented.
- Configurable memory and disk cache tier budgets. Implemented in config.
- Validation that enabled caches declare at least one storage tier. Implemented.
- Cache storage planning for memory object slots and disk paths. Implemented.
- Image/static eligibility and deterministic cache keys. Implemented.
- Vhost-aware Pingora cache-key callback. Implemented.
- Pingora memory backend evaluation. Implemented:
pingora-memory-cache 0.8.0is current and license-compatible, but it is a generic count-based cache and needs an HTTPStorageadapter. - Byte-bounded in-process memory cache tier. Implemented with
moka 0.12.15, verified as latest on 2026-05-05. - Runtime vhost memory-cache construction. Implemented.
- Pingora memory
Storageadapter. Implemented for complete-object memory admission. - Pingora
HttpCachestorage admission. Implemented for eligible image requests with origin-provided freshness metadata. - Full cache-header semantics. Planned as a required cache-pack hardening
track before cache is called complete:
- response headers:
Cache-Control,Expires,ETag,Last-Modified,Vary,Age, andAccept-Ranges; - request headers:
If-Match,If-Unmodified-Since,If-None-Match,If-Modified-Since,Cache-Control,Pragma,Range, andIf-Range; - static responses should honor conditional requests, forced
revalidation, range validation, explicit no-store/no-cache policy, and
operator-configured browser/CDN headers. Implemented for static
If-Match,If-Unmodified-Since,If-None-Match,If-Modified-Since, requestCache-Control,Pragma, singleRange, andIf-Range; - proxied cache responses should preserve origin validators and freshness
metadata, emit correct
Agebehavior on hits, respect request revalidation controls, and avoid caching when origin/client directives forbid it. Implemented conservatively for requestCache-Control: no-cache,Cache-Control: max-age=0, andPragma: no-cacheby forcing cache revalidation of an existing object, and for requestCache-Control: no-storeby bypassing shared-cache admission. Implemented for origin responseCache-Control: no-store,private,no-cache,max-age=0, ands-maxage=0by refusing shared image-cache admission until zero-freshness proxy revalidation is complete. Pingora's cache pipeline already injectsAgefor stored-response hits and applies downstream conditional/range handling when cache is enabled. Implemented end-to-end release smoke coverage now asserts cached-hitAge, cachedLast-Modifiedpreservation, conditional304, byte-range206,Varyvariant isolation, validator-based 304 revalidation metadata, changedLast-Modifiedpreservation from origin304 Not Modified, safe refusal of changedVaryrevalidation metadata, and disk HIT behavior after process restart; Varymust be part of the cache-key strategy before content negotiation, compression, image filtering, or media variants are marked stable. Implemented for Pingora cache variance: repeatedVaryheaders are normalized, request variant headers are hashed into the variance key, andVary: *, malformed, oversized, or excessiveVaryheaders are rejected from cache admission. SensitiveVaryfields such asCookie,Authorization, andProxy-Authorizationare also rejected to avoid per-user cache variants;Set-Cookieresponses must not be stored in the shared image cache. Implemented: cache admission rejects responses carryingSet-Cookie;- proxied image-cache admission should validate the origin response, not
only the request path. Implemented: shared image-cache admission is
limited to
200 OKresponses with animage/*Content-Type, and rejects missing/non-image content types, redirects, and errors; - CDN-facing headers should be user-configurable through header policy and documented examples, not hardcoded globally.
- response headers:
- Request collapsing. Implemented for memory, disk, and tiered cache
policies with Pingora
CacheLock; cache-lock coverage is exposed in metrics/admin status so stampede-protection gaps are visible. - Oversized memory admission refusal. Implemented: objects above
cache.max_object_bytesare not stored. - Disk storage. Implemented as a complete-object Pingora
Storageadapter with SHA-256 shard paths, atomic same-directory renames, per-object limits, purge, runtime LRU eviction, and on-write total-size enforcement. - Disk eviction policy. Runtime-maintained least-recently-used disk-object
index implemented for stats and eviction after startup. A root-local
.fluxheim-disk-index-v1checkpoint is implemented so clean restarts can seed the disk-object index without a full shard scan. Planned: add a compact append-only journal or periodic checkpoint throttling if very high-churn cache workloads make full checkpoint rewrites too expensive. - Pingora cache surface review. Implemented foundations already cover
Storage,HandleHit,HandleMiss,CacheLock,Varyvariance keys, stale serving metadata, and boundedNoCacheReasonstatus reporting. Planned operator-facing additions from Pingora's cache internals: cacheable-predictor integration for historically uncacheable keys, bounded force-miss/force-fresh controls for admin/debug workflows, and directCachePut-style preload so deploys can fill selected objects without loopback HTTP warmups. Implemented: low-cardinality lock-duration and lookup-duration histograms fromHttpCacheDigest, exported through Prometheus and OTLP metrics, plus cache phase/timing attributes on OTLP request traces. Implemented: client refresh requests now use PingoraForcedFreshness::ForceExpiredto revalidate cached objects instead of bypassing cache entirely. Reader-visible partial streaming writes remain deliberately post-1.2 and should be implemented through Pingora'slookup_streaming_write/ streaming-tag model, not by exposing incomplete disk files directly. - Multi-tier cache promotion/fallback. Implemented with a tiered Pingora storage adapter: memory is L1, disk is L2, misses write to both tiers, disk hits promote to memory when they fit, and purge invalidates both.
- Pingora
Storageadapter partial streaming admission. Implemented for disk-only cache admission with bounded same-root temporary files and an atomic final object write. Memory and tiered production adapters still keep Pingora partial-write support disabled until their in-progress object accounting is proven. - Route-scoped reverse-proxy cache policy for production gateway migrations.
Needed for Forgejo-style static path caching such as
/avatars,/repo-avatars,/assets, and/img, with explicit path matchers, operator-controlled cache keys, status-specific TTLs, stale-on-error behavior, cache-lock request collapsing, optionalX-Cache-Statusstyle response headers, and carefully gated controls for ignoring upstream freshness headers or hidingSet-Cookieon cacheable static routes. This must remain opt-in per route and must not weaken the default refusal to store personalized responses. - Full reverse-proxy cache policy parity. Planned:
- cache-key templates are implemented as constrained
key_partsusing safe request fields rather than arbitrary string interpolation; min_usesstyle delayed admission before storing a response. Implemented with a bounded short-lived admission counter per cache key;- status-specific TTL rules, including
anyfallback TTL. Implemented through typedstatus_ttlsanddefault_status_ttl_secspolicy; - explicit request-side bypass rules and response-side no-store rules based on bounded header, cookie, and query predicates. Implemented for header-presence and exact header-value request bypass, raw query-parameter and exact query-value request bypass, cookie-name and exact cookie-value request bypass, plus response header-presence and exact header-value no-store controls;
- stale serving controls for origin error and updating are implemented
through explicit
stale_if_error_secsandstale_while_revalidate_secswindows, withstale_if_error_onfor connect, timeout, read, write, connection-closed, HTTP status, protocol, TLS, and other upstream error classes, plusstale_if_error_statusesfor selected 5xx origin statuses; - optional cache-status response headers for production debugging;
- route-local controls for ignoring upstream freshness headers and hiding
Set-Cookie, allowed only when the route is explicitly marked static or otherwise personalized-content safe; - bounded cache-key indexing for memory and disk tiers is implemented as
the foundation for broader invalidation. Indexed vhost/route scope
purge, path-prefix purge, tag purge, wildcard path-pattern purge, and
stale purge are implemented through the admin API. A background stale
disk purger is implemented through
[cache_purger]; - startup cache-index loading rebuilds the bounded purge index and runtime disk-object index from stored v5 disk object metadata or, when present and valid, from the root-local disk-index checkpoint. Planned: add a compact append-only journal or checkpoint throttling for very high-churn cache workloads;
- byte-range/slice caching for large immutable files, with explicit warnings that the source object must not change during slice fill.
- cache-key templates are implemented as constrained
- Dedicated cache-server feature track inspired by Varnish/Vinyl-style
accelerators. Planned:
- richer cache policy phases for receive, hash, hit, miss, backend response, deliver, and synthetic responses without exposing unsafe arbitrary code by default;
- object metadata fields for TTL, grace, keep, hit-for-pass/pass, tags, surrogate keys, and variant identities;
- health-aware stale/grace behavior where stale objects can be served differently for healthy versus unhealthy origins;
- ban/tag invalidation with asynchronous evaluation and bounded memory use;
- first-class cache observability: per-route hit/miss/pass/bypass/stale counters, storage pressure, eviction reasons, origin fetch outcomes, and structured cache decision logs;
- live administration for cache policy reload, purge/ban operations, storage inspection, and safe config activation through the existing admin/snapshot model;
- extension points for optional policy modules or WASM filters after the stable typed policy language is complete. These WASM hooks should also cover cache phases such as lookup, admission, hit delivery, purge tagging, and synthetic responses so Fluxheim can eventually offer a safer typed equivalent to custom cache policy languages without making arbitrary code part of the default cache path.
- HTTP cache semantics.
- Stale-while-revalidate.
- Purge/admin API. Implemented for protected single-key invalidation through
POST /_fluxheim/cache/purge, same-host bulk invalidation throughPOST /_fluxheim/cache/purge-bulk, indexed scope purge, path-prefix purge, tag purge, wildcard path-pattern purge, and stale purge. Purge removes all storedVaryvariants for the selected primary cache identity in memory and disk tiers. Indexed purge endpoints support vhost and route scopes, bounded batch limits, hard purge, and soft purge where applicable. - Cache admin status. Implemented through protected
GET /_fluxheim/cache/statuswith aggregate and per-vhost memory/disk counters plus hit, miss, store, refused-store, and purge activity. - Cache activity reset. Implemented through protected
POST /_fluxheim/cache/activity/resetwithout clearing cached objects.
6a. 1.4 Optional Compression
- Architecture and security plan documented in Compression.
- Compression is pulled into the
1.4production proxy parity line because NGINX, HAProxy, Envoy, and Caddy operators expect it from a reverse proxy. - Compression must be optional, compile-time gated, and disabled by default until body-filter resource limits and cache-variant behavior are proven.
- Planned features:
compression: shared config, negotiation, eligibility checks, and response body filter integration.compression-zstd: Zstandard response encoding for modern dynamic or streaming responses.compression-brotli: Brotli response encoding for eligible static web assets.compression-gzip: gzip compatibility fallback for older clients.
- Prefer Zstandard and Brotli where clients support them. Gzip should be a fallback, not the default preferred encoding.
- Do not compress already-compressed formats,
no-transformresponses, unsafe personalized responses, or range responses until a range-aware design exists. - Compression variants must integrate with cache keys and
Vary: Accept-Encoding, including policy-version isolation. - Expensive compression must use bounded worker pools or blocking-task offload so request workers do not stall.
- Add tests for negotiation, excluded MIME types, cache isolation, disconnect cancellation, resource limits, side-channel-sensitive response exclusions, and default/privacy builds proving compression is absent.
-
Future Optional Image Filter
- Architecture and security plan documented in Image Filter.
- Image filtering must be optional, compile-time gated, and disabled by
default. Planned features:
image-filter: shared config, eligibility checks, metadata reporting, transform pipeline, and cache-key integration.image-filter-webp: WebP output/input support after codec review.image-filter-avif: AVIF output/input support as beta after codec performance and maintenance review.
- Initial transformations:
validate image type, report metadata, resize, crop, rotate by
90/180/270, strip metadata by default, and set bounded JPEG/WebP quality. - Supported input formats should start with JPEG, PNG, GIF, and WebP. GIF animation handling must be explicit: reject, first frame only, or preserve only when the selected codec safely supports animation.
- The module must enforce hard resource limits before and during decode: input bytes, decoded pixels, output bytes, width/height, timeout, and per-vhost/global transform concurrency.
- Transform policies must be explicit per vhost or route. Do not process admin, metrics, ACME, PHP, CGI, legacy HTTP, or arbitrary binary responses.
- Transformed variants need cache isolation by vhost, source identity,
policy version, dimensions, crop/rotate settings, output format, quality,
and normalized
Acceptbucket. - Prefer WebP only when the client advertises support and the vhost policy allows it. AVIF remains beta until resource use and codec maintenance are proven.
- Security baseline: strip EXIF/GPS/comment metadata by default, reject malformed/oversized files safely, do not log image bytes or sensitive source URLs, keep FFI codecs behind separate feature flags, and require license/advisory review for codec dependencies.
- Exit criteria before beta: unsupported-format tests, decode-bomb tests, output-dimension tests, metadata stripping tests, WebP negotiation tests, cache-key isolation tests, timeout/concurrency tests, and default/privacy build absence checks.
-
Metrics
- Compile-time
metricsmodule. Implemented. - Typed metrics listener config. Implemented with secure defaults: disabled by default, loopback listener, and loopback enforcement before remote exposure.
- Pingora Prometheus HTTP service wiring. Implemented.
- Proxy request outcome counter. Implemented as
fluxheim_proxy_requests_totallabeled by vhost, fixed method bucket, outcome class, and fixed status class. - Reload impact classification. Implemented: metrics listener changes require a process upgrade because the service is startup-owned.
- Additional counters planned: cache operation totals, upstream selection totals, load-balancer health transitions, ACME renewal results, and self-healing rollback actions.
- Advanced metrics architecture documented in Metrics Architecture.
- Keep Prometheus pull as the safe baseline. Advanced per-vhost buckets, remote push, and OTLP export must remain optional add-ons.
- Planned features:
metrics: current baseline Prometheus endpoint.metrics-advanced: cardinality-safe per-vhost counters and latency histograms.metrics-push: optional remote exporter.metrics-otlp: optional OpenTelemetry/OTLP exporter.
- Cardinality safety is mandatory: never create metric labels directly from
arbitrary
Host, path, query, user-agent, client IP, or request ID values. Use configured vhost names and fixed buckets such asunknown,invalid_host,legacy_unidentified, andoverflow. - Prefer prebuilt vhost-indexed buckets and atomic counters on the request
hot path. Evaluate fixed atomic latency buckets first; use
hdrhistogramonly with sharded or background aggregation. - Remote push exporters must run in background services and must never block request workers. Failed pushes keep metrics available locally and expose exporter health through Prometheus/admin status.
- Compile-time
-
Future Optional WAF Support
- Architecture and security plan documented in WAF Architecture.
- WAF support must be optional, compile-time gated, and disabled by default.
- Long-term target: cover the web-application security jobs operators
associate with F5 BIG-IP ASM/Advanced WAF, but as Fluxheim optional
modules rather than as part of the
1.5load balancer. That means signature/anomaly scoring, OWASP CRS compatibility where practical, positive-security policy over time, bot/reputation inputs, per-vhost blocking/dry-run modes, and audit evidence. Planned features:waf: shared WAF config, decision model, audit logging, and native lightweight rule engine.waf-native: Rust-native signature/anomaly engine using reviewed pattern matching crates such asaho-corasick.waf-hyperscan: optional high-performance regex engine usinghyperscan; Linux-focused and FFI-backed, so not part of defaults.waf-proxy-wasm: experimental Proxy-Wasm host path for Coraza/OWASP CRS compatibility after a runtime/security audit.
- Prefer a native MVP first: header/URI checks, body scanning for bounded content types, anomaly scoring, per-vhost enablement, dry-run mode, and audit events. Coraza/Proxy-Wasm is a future compatibility engine, not the initial default.
- WAF hooks should run early in Pingora request handling: inspect method, URI, normalized headers, cookies, and client metadata before upstream selection; inspect request bodies only under explicit size and content-type limits.
- Body scanning must be conditional and bounded: do not scan arbitrary large
uploads, binary content, or streaming bodies beyond
max_scan_bytes. Default action for oversized bodies should be configurable per vhost:skip,deny, orscore. - Enforce cardinality and privacy rules: WAF metrics/logs must not store raw secrets, complete cookies, authorization headers, full request bodies, or attacker-controlled metric labels. Audit logs should include rule IDs, phase, action, score, vhost, and request ID only after redaction.
- Fail mode must be explicit per vhost:
fail_closedfor high-security deployments,fail_openonly when availability is more important and the risk is documented in config validation warnings. - Add tests for header blocks, body blocks, anomaly thresholds, dry-run behavior, redaction, max body scan limits, malformed input, reload of WAF rules through snapshots, and default builds proving WAF is absent unless explicitly compiled.
-
Future Edge Firewall And TLS VPN Gateway Modes
- These are realistic future edge functions, but only as separate product
modes with dedicated compile profiles and release gates. They must not
creep into
1.5.0load-balancer work. - A future
profile-edge-firewallwould need its own threat model and OS integration plan: packet/routing ownership, stateful firewall tables, NAT/SNAT/DNAT policy, kernel capability policy, nftables/eBPF or equivalent integration, rootless/container limits, audit logs, and platform-specific tests. - A future
profile-tls-vpn-gatewaywould need its own identity and tunnel model: TLS or WireGuard-style protocol choice, key lifecycle, replay protection, route push policy, client onboarding/revocation, logging and privacy rules, and separate security evidence. - Treat both as research until the proxy, load-balancer, WAF, and Wasm boundaries are stable enough that Fluxheim can add them without weakening the existing edge server threat model.
- Future Optional Cloudflare Origin Support
- Architecture and security plan documented in Cloudflare Origin Support.
- Cloudflare support must be optional, compile-time gated, and disabled by
default. Planned features:
cloudflare: shared config, trusted IP ranges, header restoration, and Cloudflare-aware logging context.cloudflare-api: Cloudflare API client, IP range refresh, and Origin CA certificate automation.cloudflare-origin-ca: CSR generation and Cloudflare Origin CA certificate lifecycle.cloudflare-aop: Authenticated Origin Pulls client certificate verification configuration and reload support.
- Implement trust-boundary support first: accept
CF-Connecting-IP,CF-Ray,CF-IPCountry, and related headers only when the direct peer IP matches validated Cloudflare IP ranges or mTLS AOP succeeds. Never trust Cloudflare headers from arbitrary clients. - Cloudflare IP ranges should be loaded from pinned config at startup and optionally refreshed by a background service from Cloudflare's official IP API. Refresh failures must keep the last valid range set and expose health through admin/metrics.
- Cloudflare Origin CA automation is feasible but must be separate from Let's Encrypt/ACME: generate a local private key and CSR, call the Cloudflare Origin CA API, persist the cert/key atomically with strict file permissions, and reload TLS without downtime only through the existing certificate reload/snapshot model.
- Authenticated Origin Pulls must distinguish global AOP from stricter zone-level/per-hostname AOP. Global AOP proves traffic came from the Cloudflare network, not from the user's specific account; prefer zone-level or per-hostname AOP for high-security deployments.
- API tokens must be least-privilege, never logged, loaded from secrets/env paths rather than config snapshots by default, and redacted in all admin, log, and error output.
- Add tests for spoofed Cloudflare headers from non-Cloudflare peers, IP range refresh failure, stale range fallback, Ray ID logging, real-IP restoration, token redaction, Origin CA CSR validation, and default builds proving Cloudflare support is absent unless explicitly compiled.
10a. Future Trusted Client Identity Layer
- Generalize provider-specific real-IP restoration into a reusable trust layer that can support local load balancers, private platform gateways, Cloudflare, and future provider packs without duplicating header parsing.
- Planned config shape:
trusted_client_ipprofiles with explicitfromCIDRs, selected header names,recursive,max_hops, and optional provider references. - Keep identity non-destructive: request context should expose direct peer IP, trusted proxy chain, restored client IP, and provider metadata separately.
- Provider-managed ranges may refresh in background with last-known-good fallback, bounded file/API sizes, signature/checksum support where available, and clear health reporting.
- Proxy Protocol v2 support should be an explicit listener option because it changes connection framing. TLV metadata must be allow-listed and bounded.
- Optional Geo/ASN/threat enrichment should load local databases at startup or snapshot reload, use bounded lookups, and never add raw client IP labels to high-cardinality metrics.
- Zero-Retention Privacy Mode Compatibility
- Architecture and security plan documented in Zero-Retention Privacy Mode.
- Privacy mode is not a normal runtime toggle. It should be a compile-time profile so logging/metrics/exporter code paths can be excluded from the binary.
- Planned feature:
privacy-mode: static web plus reverse proxy operation with no application-level request retention.
- Planned incompatible features:
metrics,metrics-advanced,metrics-push,metrics-otlp,logging-remote,logging-spool,waf,waf-native,waf-hyperscan,waf-proxy-wasm,cloudflare,cloudflare-api,cloudflare-origin-ca,cloudflare-aop,php-*,perl-cgi-*,legacy-http-*, and disk cache features. - Privacy builds must not persist client IPs, request paths, user agents, cookies, request IDs, or per-client counters. Startup/config errors may still be emitted without request metadata.
- Reverse proxy behavior must strip inbound
X-Forwarded-For,Forwarded,X-Real-IP, and similar headers, and must not synthesize new real-IP headers for upstreams. - Document the boundary clearly: Fluxheim can avoid storing client data, but the OS, container runtime, firewall, Cloudflare/CDN, and upstream applications can still log traffic unless configured separately.
- Future PHP Runtime Support
- Architecture and security plan documented in PHP Runtime Support.
- PHP must be optional and compile-time gated. Production PHP uses
php-fpm: the backwards-compatible FastCGI bridge to php-fpm over Unix or TCP sockets. 1.3.7managed php-fpm keeps the samephp-fpmCargo feature and adds a runtime config mode where Fluxheim starts and supervises a private php-fpm pool. External php-fpm remains the default.- Pure-Rust PHP/phprs is intentionally out of scope for the 1.3 line. Revisit only if an upstream interpreter has mature compatibility, maintenance, and security evidence.
- Add typed PHP config per vhost: enabled runtime, document root, index file, allowed extensions, socket/upstream, request timeout, body limit override, environment allow-list, and path-info policy.
- Security baseline before any PHP implementation:
canonicalize
SCRIPT_FILENAME, reject traversal/symlink escapes, never serve.phpsource as static fallback, deny dotfiles by default, enforce strict CGI param allow-list, scrub inherited environment, enforce request body limits, add execution timeouts, and log STDERR safely without leaking secrets. php-fpmbridge plan: usefastcgi-client 0.11.1or a reviewed equivalent, map Pingora requests to FastCGI params, support Unix sockets first, parse CGI response headers strictly, and include integration tests against a rootless php-fpm container.- Turbine-style PHP app servers are not Fluxheim runtime targets. Treat them as HTTP upstreams that Fluxheim can reverse-proxy to unless a future project exposes a small, auditable library API with a clearly safer boundary than reverse proxying.
- PHP runtime changes should be process-upgrade changes, not snapshot-only reloads, until each runtime proves safe reload semantics.
- Future Perl CGI Support
- Architecture and security plan documented in Perl CGI Support.
- Perl CGI must be optional and compile-time gated. Planned features:
perl-cgifor the module,perl-cgi-ceglafor thecegla/Tokio CGI implementation, and optional Linux-only sandbox hardening features such asperl-cgi-landlock. - Use current
cegla-cgi 0.2.3/tokio-cegla 0.2.3only after a normal license/security review. Both are MIT.rlimit 0.11.0is the planned Unix resource-limit helper, andlandlock 0.4.4is the optional Linux path sandbox helper. - Add typed per-vhost CGI config: enabled flag, script root, allowed extensions, interpreter path, index names, request timeout, max body override, max stdout/header bytes, uid/gid policy, working directory, environment allow-list, and sandbox profile.
- Security baseline before any CGI implementation: canonicalize script paths, reject traversal/symlink escapes, deny dotfiles, never execute writable-by-group/world scripts, never serve CGI source as static fallback, scrub inherited environment, pass only strict RFC 3875 CGI variables, enforce body limits for streaming requests, set execution timeouts, cap stdout/stderr, parse CGI headers strictly, and kill process groups on timeout or client cancellation.
- Process isolation plan:
prefer an external low-privilege
perlinterpreter; useuid/gidwhere available,rlimitfor CPU/memory/file/process limits, optional Landlock for Linux path restrictions, and rootless container boundaries for deployment. Do not rely on chroot unless the process has the privileges and operational model to support it safely. - CGI runtime changes should be process-upgrade changes until process pool, sandbox, and per-vhost policy reload semantics are proven safe.
- Future Legacy Static HTTP Support
- Architecture and security plan documented in Legacy Static HTTP Support.
- Legacy protocol support must be compile-time gated, disabled by default,
and separate from normal listeners. Planned features:
legacy-http-static,legacy-http10-static, andlegacy-http09-static. - No legacy feature may be included in the default feature set. Release
checks should include a guard that fails if any legacy HTTP feature is
accidentally pulled in by
default. - HTTP/1.0 compatibility is allowed only for static file serving on an
explicitly configured legacy listener and default legacy vhost. It must
reject
Transfer-Encoding,Upgrade, ambiguousContent-Length, request bodies unless explicitly allowed for static-safe methods, and persistent connections. It must forceConnection: close. - HTTP/0.9 compatibility is allowed only on a dedicated raw TCP listener,
separate from Pingora's normal HTTP service. It may only support one-line
GET /pathstatic file reads. No headers, no status-sensitive behavior, no TLS, no proxy, no cache, no admin, no PHP, no CGI, and no directory listings. - Legacy requests must use the existing static resolver's canonical path security model and must never fall through to proxy/cache/admin/dynamic handlers.
- Add explicit request-smuggling tests for HTTP/1.0 framing, upgrade headers, transfer-encoding misuse, multiple content-length values, malformed HTTP/0.9 lines, traversal, and attempts to reach non-static routes.
- Future HTTP/3 And QUIC
- HTTP/3 is the modern protocol direction, not a legacy-compatibility feature.
- Track it as Fluxheim-owned
1.9work, after server bootstrap/listener/TLS ownership and the HTTP proxy runtime are stable. The intended ecosystem path is Rustquinnfor QUIC transport plus theh3stack for HTTP/3 framing, behind Fluxheim-owned listener, TLS, routing, and policy boundaries. - HTTP/3 changes Fluxheim's listener model from TCP/TLS-only ingress to a
dual TCP plus UDP service. It should land first as an opt-in
http3orhttp3-experimentalcompile feature. The milestone must cover TLS/ALPN handling, UDP listener ownership, rootless Podman networking constraints, certificate reload interaction, metrics, graceful shutdown, and zero-downtime process upgrade semantics where still supported. - Do not treat
Alt-Svcas the implementation. Advertising HTTP/3 is easy; Fluxheim must only emitAlt-Svcfrom listeners/vhosts where the UDP QUIC service is actually configured and healthy, with the advertised port matching the deployed UDP mapping. - Start with a conservative config surface:
enabled,listen,advertise_alt_svc,max_concurrent_streams,idle_timeout, andenable_0rtt = false. 0-RTT must remain disabled until Fluxheim has explicit replay-safe route policy for idempotent traffic. - First implementation target should be minimal GET/HEAD traffic through the existing vhost and route policy model. Full parity needs request body streaming, upload limits, static serving, proxying, cache behavior, access/error logs, dynamic headers, and certificate selection to behave consistently with HTTP/1.1 and HTTP/2.
- The core engineering risk is not memory pinning or one buffer choice; it is correctly integrating QUIC connection state, UDP socket batching, connection IDs, anti-amplification limits, congestion behavior, stream timeouts, and request/response mapping into Fluxheim's existing policy pipeline without creating a second independent server path.
- Release validation must include HTTP/3 interop and resilience checks:
client tests with HTTP/3-capable tooling, browser discovery through
Alt-Svc, UDP firewall/container mapping tests, packet loss/reordering tests, malformed frame handling, load tests, and request-smuggling-style boundary tests for mixed HTTP/1.1, HTTP/2, and HTTP/3 deployments. - HTTP/3 must preserve the same security posture as HTTP/1.1/HTTP/2: strict parsing, no downgrade shortcuts, no legacy protocol fallback on modern listeners, and the same vhost/cache/admin isolation rules.
- Future Advanced TLS Privacy And Post-Quantum Work
- Track post-quantum hybrid key exchange as a dedicated TLS backend
milestone, not as a string-only config promise. The first target is
X25519MLKEM768once the default downstream TLS backend can enforce it through a stable crypto provider. - Evaluate ML-DSA/PQC certificate chain handling as part of certificate parsing, storage, scan, and handshake-size testing. Larger certificate chains must be tested against initial congestion window behavior and mobile networks before being advertised as production-ready.
- Add Encrypted Client Hello only when the TLS backend, DNS publishing flow, key rotation model, and operational docs are all in place. ECH changes certificate/SNI visibility and needs explicit failure-mode tests.
- Track RFC 8879 TLS certificate compression separately from response compression. Zstandard certificate compression is interesting for PQC chain sizes, but it must be supported by the chosen TLS stack and tested with real browsers before release.
- Do not build OCSP stapling unless a concrete modern deployment need appears; ACME automation, short-lived certificates, and browser revocation mechanisms are higher-priority.
- Future Optional Host Sandbox
- Plan as an optional compile-time module after the
1.0native systemd and container deployment boundaries are stable. - Planned feature flags:
host-sandbox: shared config, lifecycle hook, and operator docs.host-sandbox-seccomp: Linux syscall filtering after initialization.host-sandbox-landlock: Linux filesystem path restrictions after config, certificates, listeners, state, cache, and log paths are opened or validated.
- Scope: bind listeners, load config/certificates, prepare runtime directories, then install irreversible restrictions that deny process creation, executable loading, and access to paths outside the configured roots.
- Do not compile this into default builds until it is proven across native systemd, rootless Podman, and normal static/proxy workloads. Operators with unusual logging, certificate reload, cache, or content paths must have explicit allow-list config.
- WASM is a separate future plugin sandbox. Do not require Fluxheim itself
to run inside Wasmtime; use systemd/container policy for
1.0and optional seccomp/Landlock for later host hardening. - Exit criteria before beta:
tests for denied
execve/process creation, denied unapproved path access, normal static/proxy traffic after sandbox installation, reload behavior, report-only diagnostics, and release checks proving sandbox code is absent from default and privacy builds.
- Future Cluster-Native State
- Plan as an optional compile-time module after the load-balancer, metrics, admin, and security profiles are stable.
- Goal: let multiple Fluxheim nodes coordinate selected security and routing state without requiring an external database for the first useful cases.
- Planned features:
cluster-state: shared config, node identity, peer discovery, local persistence, admin/metrics visibility, and compatibility checks.cluster-gossip: lightweight eventually consistent distribution for blocklists, allowlists, health summaries, and coarse counters.cluster-consensus: stronger Raft-style coordination for state that must not diverge, such as global rate-limit leases or active leader ownership.
- Start with safe eventually consistent data: blocklists, drain state, backend health hints, and low-risk counters. Do not start with billing, authentication decisions, or hard quotas that require exact consistency.
- Global rate limiting should be designed as a separate capability on top of
cluster state. It needs explicit consistency semantics:
local_only,eventual, orstrict. - Security baseline: every node must have a stable identity, authenticated peer transport, replay protection, bounded message sizes, version negotiation, and fail-closed behavior for strict policies.
- Privacy baseline: replicated state must never contain raw paths, queries, authorization headers, cookies, user agents, or client IPs unless an operator explicitly enables a non-privacy profile and the field is documented.
- Exit criteria before beta: split-brain tests, clock-skew tests, peer restart tests, message fuzzing, downgrade/version mismatch tests, and release checks proving cluster code is absent from default and privacy builds.
- Future External Authorization And Identity-Aware Routing
- Architecture and security plan for external authorization requests is documented in External Authorization Request.
- Architecture and security plan for signed URL grants is documented in Secure Links.
- Plan as optional
auth-requestandidentitymodule families after stable admin, logging redaction, TLS, and header policy are mature. - Goal: let Fluxheim ask a trusted authorization service for an access decision, and later verify user or service identity at the edge and route or annotate requests based on explicit policy rather than blindly trusting inbound headers.
- Planned features:
auth-request: per-vhost/per-route external authorization probe before static serving or proxying.auth-zone: global deny-by-default authorization coverage with explicit route/path exclusions, so protected deployments do not depend on every route remembering to opt in.auth-hook-udsandauth-hook-grpc: low-latency persistent authorization hooks over Unix domain sockets or gRPC for deployments that do not want per-request HTTP overhead.identity-oidc: OIDC discovery, JWKS fetch/cache, JWT verification, issuer/audience validation, and key rotation.identity-oauth2: OAuth2 token introspection for providers that require online validation.identity-policy: per-vhost route decisions based on verified claims, groups, roles, tenant IDs, or subscription tier.secure-links: signed URL grants for static, proxy, download, and media routes, using modern HMAC or Ed25519 verification instead of weak digest-only schemes.secure-links-replay: optional token replay/usage accounting when an explicit state backend is available.
- Authorization decision contract:
2xxfrom the auth service allows the original request,401and403deny with controlled response handling, and every other status is an auth service error. - External auth must be fail-closed by default.
fail_openshould require explicit per-vhost config and emit a security event. - Auth probes should be header-only by default. Body forwarding requires explicit opt-in, small body caps, content-type allow-lists, redaction, and independent timeout budgets.
- Headers copied to the auth service, copied from the auth service to the upstream, or copied to the client must be allow-listed. Fluxheim must strip spoofable identity and forwarding headers before making decisions.
- Optional auth-decision caching must be isolated by vhost, route, method, identity/session fingerprint, and policy version. Positive and negative TTLs must be separate and bounded.
- Header injection must be deny-by-default and namespaced. Fluxheim should strip inbound identity headers before adding verified replacement headers.
- Local JWT verification should be preferred when possible. External authorization is for session/policy decisions that cannot be verified locally or need live revocation.
- Secure links should validate signed claims such as expiry, path, method, audience, entitlement tier, and optional token ID before cache lookup, static serving, proxying, or media transformation.
- Identity state should be stored in the request context after verification so later phases can map verified claims to upstream headers, route decisions, logs, and metrics without reparsing tokens.
- Denial handling should support browser and API clients separately:
configured login redirects with a safe return destination for browser
requests, and JSON
401/403responses for AJAX/API clients when configured. - Security baseline: auth backend TLS verification by default, optional mTLS, strict auth backend response-size limits, loop prevention, strict issuer/audience/expiry checks, algorithm allow-lists, bounded token sizes, JWKS cache pinning rules, stale-key behavior, clock-skew limits, no raw token logging, and explicit failure modes.
- Routing examples: route verified admin users to an admin upstream pool, route paid tiers to stronger backend pools, or deny requests before proxying when claims do not match per-vhost policy.
- Exit criteria before beta: auth allow/deny/error tests, timeout tests, response-size tests, challenge-header allow-list tests, JWT confusion tests, expired/revoked token tests, key rotation tests, spoofed identity-header tests, signed-link expiry/path/method/audience tests, token redaction tests, recursive-auth rejection, and privacy-mode incompatibility guards.
- Future Declarative Redirect And Rewrite Engine
- Goal: provide a safe match-action pipeline for redirects and internal request rewrites without procedural phase ordering.
- Global HTTPS redirect is part of the stable core. The future engine should expand this into per-vhost and per-route policies.
- Planned matcher model: named matchers for host, path, method, header, query, source network, protocol, and verified identity claims when identity modules are enabled.
- Planned actions: external redirect, internal path rewrite, query merge/strip, route stop, route continue, and controlled synthetic responses.
- Safety baseline: redirect destinations must be parsed and validated, host-derived redirects must reject unsafe Host headers, rewrite targets must stay origin-form unless explicitly configured as redirects, and internal rewrite cycles must be rejected during config validation.
- Performance baseline: compile path matchers into tries where practical, compile multiple regex rules into grouped matchers, bound pattern count and pattern size, and reject catastrophic or unsupported patterns at config load.
- WASM integration: complex rewrite decisions may later call a sandboxed WASM policy hook, but only after the WASM host has fuel, wall-time, memory, host-call, and failure-mode limits.
- Future AI Gateway
- Plan as an optional compile-time module family after metrics, WAF, cache, and identity foundations exist.
- Goal: make Fluxheim understand AI API traffic enough to control cost, protect backends, and safely reuse responses where operators opt in.
- Planned features:
ai-gateway: shared request classification, provider/upstream config, model routing, and safety hooks.ai-rate-limit: token-aware rate limits such as tokens per minute, output-token budget, and per-tenant quotas.ai-semantic-cache: opt-in semantic cache for deterministic or cache-approved prompts using vector similarity with strict privacy boundaries.ai-prompt-guard: prompt-injection and data-exfiltration scoring, preferably integrated with the future WAF decision model.
- Start realistic: implement provider-agnostic request size limits, model allow-lists, API key redaction, per-vhost model routing, and token accounting for responses where providers return usage metadata. Token estimation is useful as a fallback but must be labeled approximate.
- Semantic caching is high risk and must be opt-in per vhost and per route. It must never cache prompts or responses containing secrets, personal data, authorization material, cookies, file uploads, tool outputs, or tenant-private context unless an operator provides an explicit safe policy.
- Security baseline: redact prompts by default in logs, cap body sizes before inspection, isolate cache entries by vhost/tenant/model/policy version, and expose clear cache-hit explanations for audit without storing sensitive payloads in normal logs.
- Exit criteria before beta: token-budget tests, provider metadata parsing tests, redaction tests, semantic-cache isolation tests, jailbreak/prompt-guard dry-run tests, and default/privacy build absence checks.
- 1.4 Traffic Mirroring
- Implemented first slice as an optional compile-time
traffic-mirrormodule in1.4.1. - Goal: safely shadow a bounded portion of production traffic to a test or analysis upstream while the live client receives only the primary response.
- Planned features:
- per-vhost and per-route mirror rules are supported through inherited proxy blocks;
- percentage and method-based sampling are supported; header and identity-claim sampling remain future work;
- request body size caps and body redaction/transformation policies;
- mirror timeout budgets that cannot affect the primary request are supported;
- mirror result metrics reuse low-cardinality edge-policy labels without storing sensitive request data.
- Never mirror by default. The operator must explicitly opt in and choose
what fields may be copied. Unsafe methods such as
POST,PUT,PATCH, andDELETErequire a stronger explicit config than idempotent requests. - Security baseline:
strip credentials by default, remove cookies unless allow-listed, cap body
copies, block mirrored admin paths, and forbid mirroring in
privacy-mode. - Exit criteria before beta: primary-response isolation tests, cancellation tests, timeout tests, redaction tests, sampling distribution tests, and proof that mirror failures never change the client response.
- Future Sentinel Mesh Graduation
- Keep the current Sentinel Mesh design as a research track until the load-balancer, TLS reload, admin, metrics, and cluster-state foundations are mature.
- Goal: encrypted node-to-node and edge-to-backend transport with smart routing based on verified telemetry.
- Planned features:
sentinel-mesh: high-level mesh config, node identity, route policy, admin/metrics visibility, and health state.sentinel-wireguard-userspace: optional userspace WireGuard transport evaluation for rootless deployments.sentinel-telemetry: signed backend load/health reports over the encrypted channel.
- The first implementation should not try to be a full service mesh. Start with gateway-to-backend tunnels and smart load balancing for small clusters.
- Security baseline: authenticated peers, key rotation, replay protection, route allow-lists, no plaintext fallback unless explicitly configured, and clear behavior when tunnel health diverges from backend HTTP health.
- Exit criteria before beta: tunnel restart tests, wrong-peer tests, stale telemetry tests, failover tests, rootless Podman smoke coverage, and default/privacy build absence checks.
- Future Programmable Media Edge
- Architecture and security plan documented in Programmable Media Edge.
- Video-aware delivery must be optional, compile-time gated, and disabled by
default. Planned features:
media-edge: shared media config, policy model, parser limits, route integration, and metrics hooks.media-hls: HLS manifest parser/rewrite support.media-dash: DASH manifest parser/rewrite support after XML parser review.media-ssai: dynamic manifest stitching with a trusted decision service.media-watermark: forensic watermarking research track.media-transmux: edge transmuxing/packaging research track.
- Start with manifest intelligence, not video decoding: parse HLS/DASH manifests, validate segment URLs, rewrite safe segment routes, enforce manifest limits, and expose media metrics.
- Add segment-aware cache/routing only after cache indexing and range behavior are strong enough. Cache keys must isolate vhost, asset ID, representation, byte range, sequence, encryption key ID, tenant/entitlement policy, and media policy version.
- Dynamic stitching should operate at manifest level first. Any ad or personalization decision service needs strict timeouts, fail behavior, redaction, and no raw user-profile logging.
- WASM media policy plugins are future-only and require a sandbox with CPU, memory, wall-time, outbound-network, and host-call limits.
- Forensic watermarking should begin with safer manifest or timed-metadata markers. Segment-level or bitstream-level watermarking requires reviewed TS/fMP4 parsers, codec/container compatibility tests, fuzzing, and a legal/privacy policy for user-identifying marks.
- Edge transmuxing is research. The first scope should be container packaging/remuxing only, not arbitrary video transcoding, GPU scheduling, or frame processing.
- Security baseline:
reject oversized/recursive/escaping manifests, never cache media keys or
authorization tokens, never mix personalized segments across users or
tenants, redact personalized URLs, keep DRM license flows out of scope
until separately modeled, and forbid media-edge in
privacy-modeby default. - Exit criteria before beta: manifest parser tests, manifest fuzzing, segment URL normalization tests, media cache-key isolation tests, ad-stitch timeout/fallback tests, redaction tests, metrics cardinality tests, and default/privacy build absence checks.
- Future WASM Extensibility
- Architecture and security plan documented in WASM Extensibility.
- Target release:
1.7as one shared extension runtime, not a partial cache-only1.2.ximplementation. - WASM support must be optional, compile-time gated, and disabled by
default. Planned features:
wasm: shared runtime config, plugin loading, limits, host-call policy, and lifecycle integration.wasm-proxy-abi: proxy-oriented ABI compatibility path.wasm-wasi: explicit WASI capability support for narrowly scoped policy plugins.
- Current crate candidates checked on 2026-05-05:
wasmtime 44.0.1,wasmtime-wasi 44.0.1, andproxy-wasm 0.2.4. - Start with request/response header hooks and access-control decisions. Do not expose body mutation, filesystem, outbound network, process spawning, cache internals, or admin APIs in the first stage.
- Use a reviewed proxy-oriented ABI where practical, but expose only the subset Fluxheim can implement safely. Unsupported host calls must fail deterministically.
- Every plugin needs strict resource limits: module size, compiled artifact size, linear memory, fuel/instruction budget, wall-time, log bytes, header mutations, synthetic response size, and per-vhost concurrency.
- WASI capabilities must be disabled by default. Filesystem, network, clocks, randomness, environment variables, and process state require explicit grants and should remain unavailable for normal header/access plugins.
- Security baseline:
reject symlinked plugin files/parents, hash loaded modules, version the
host ABI, redact secrets from host calls, prevent plugins from directly
controlling cache keys/routing/TLS verification, isolate traps/timeouts,
and reject WASM in
privacy-modeby default. - Exit criteria before beta: ABI compatibility tests, header mutation tests, deny/synthetic response tests, unsupported host-call tests, fuel/timeout/trap tests, capability denial tests, redaction tests, plugin path hardening tests, and default/privacy build absence checks.
- Operational Packaging
- Rootless Podman image. Implemented with a pinned Rust 1.95.0 builder and non-root runtime user.
- Rootless Podman smoke script. Implemented for image build, packaged config validation, and runtime UID verification.
- Proper manual pages for the operator CLI and packaged service:
fluxheim(8),fluxheim.toml(5), and focused subcommand pages for ACME, cache, snapshot, reload/rollback, and validation workflows. The RPM should install these under the distro manpath and include them in package validation, so native deployments have offline command/config documentation. - Release/security checklist. Implemented in Release Checklist, with a wrapper script for local release gates.
- Hardware-specific local build documentation. Implemented with
target-cpu=nativeguidance. - Example configs for local, reverse-proxy, static-site, and mixed modes.
- Release/security checklist.
- Rootless userspace WireGuard evaluation for Sentinel Mesh.