Skip to main content

Snakeway v0.9.0

Breaking Changes

TLS configuration now requires a mode

The tls block inside bind and bind_admin now requires an explicit mode field.

Before (v0.8.0):

bind = {
tls = {
cert = "/path/to/certs/server.pem"
key = "/path/to/certs/server.key"
}
}

After (v0.9.0):

bind = {
tls = {
mode = "manual"
cert = "/path/to/certs/server.pem"
key = "/path/to/certs/server.key"
}
}

Set mode = "manual" to preserve the existing behavior. The new "acme" mode enables automatic certificate issuance and renewal.

Routes now require a hosts field

Service routes and static file routes now require a hosts list. This enables virtual hosting — multiple domains can be served from a single Snakeway instance.

Before (v0.8.0):

routes = [
{ path = "/api" }
]

After (v0.9.0):

routes = [
{
hosts = ["example.com"]
path = "/api"
}
]

Use ["*"] to match all hostnames and preserve previous behavior when upgrading:

routes = [
{
hosts = ["*"]
path = "/api"
}
]

New Features

Automatic TLS Certificate Renewal (ACME)

Snakeway now supports automatic TLS certificate issuance and renewal via the ACME protocol (Let's Encrypt).

Configure tls_automation in snakeway.hcl:

server {
tls_automation = {
renew_within_days = 30
acme = {
directory_url = "https://acme-v02.api.letsencrypt.org/directory"
data_dir = "/var/lib/snakeway/acme"
contact_email = ["admin@example.com"]
}
cert_store = {
type = "filesystem"
cert_dir = "/var/lib/snakeway/acme/certs"
}
}
}

Then set mode = "acme" on any bind block you want managed automatically:

bind = {
tls = {
mode = "acme"
domains = ["example.com", "api.example.com"]
challenge = "http01"
}
}

Certificates are renewed automatically in the background. No restart or reload is required.

See the TLS Cert Management guide for full details.

Virtual Hosting (SNI / host-based routing)

Routes now accept a hosts list, allowing a single Snakeway instance to serve multiple domains. Incoming requests are matched against the Host header before path matching is applied.

See the Routes reference for full details.

Upstream TLS

Upstream connections can now be made over TLS. Configure this per endpoint:

endpoint = {
host = "backend.internal"
port = 8443
tls = {
sni = "backend.internal"
verify = true
// ca_file = "/path/to/ca.pem" // optional; falls back to server.ca_file
}
}

See the Upstream TLS reference for the full field reference.

route solve CLI Command

Debug routing decisions without starting the proxy. The command runs the same config loading, lowering, and routing logic used by the live proxy:

snakeway route solve http://example.com/api/v1/users --config /etc/snakeway

Supports --trace, --verbose, --format=json, and deterministic upstream selection via --lb-index / --lb-key.

See route solve for full documentation.

Snakeway v0.7.0

Highlights

1. New config init Templates

You can now generate a fully structured configuration directory using built-in templates:

snakeway config init ./my-proxy --template=httpbin

Available templates:

  • minimal -- Barebones starting point
  • httpbin -- Working reverse proxy example
  • dev -- Full-featured development setup

Generated structure:

my-proxy/ ├── device.d/ ├── ingress.d/ └── snakeway.hcl

This makes onboarding easier and removes guesswork when starting a new deployment.

2. Standardized config dump and config check

Both commands now support consistent output formats using --format:

snakeway config check /etc/snakeway --format=json
snakeway config dump /etc/snakeway --format=hcl --repr=runtime

Supported formats:

  • hcl
  • json
  • yaml

You can inspect either:

  • --repr=spec (your configuration files)
  • --repr=runtime (internal resolved state)

This improves automation, CI validation, and debugging workflows.

3. Directory Naming Cleanup (Breaking Change)

The include section has been standardized.

Old:

include {
devices = "devices.d/*.hcl"
ingress = "ingress.d/*.hcl"
}

New:

include {
devices = "device.d/*.hcl"
ingresses = "ingress.d/*.hcl"
}

Changes:

  • devices.d/device.d/
  • ingressingresses

If upgrading, update both your snakeway.hcl and directory names.

4. Identity Device Hardening

The Identity device now exposes two configurable limits:

identity_device = {
max_x_forwarded_for_length = 1024
max_user_agent_length = 2048
}

These were previously hard-coded. Both are range validated and applied during parsing, improving safety against oversized or malicious headers.

5. Logging Simplified and Clarified

Runtime logging is now controlled via environment variables:

  • RUST_LOG
  • SNAKEWAY_LOG_DIR
  • TOKIO_CONSOLE

Structured observability remains available via the structured_logging_device.

Everything Else

Config System Refactor

  • Clear separation between specification types and runtime types
  • Health check and circuit breaker moved to explicit Spec and Config types
  • Reduced internal unwrap/expect usage

CLI Namespace Cleanup

Internal CLI modules moved from cli::conf to cli::config.
User-facing commands remain unchanged.

HCL Serialization Improvements

Snakeway now uses an internal HCL serializer that:

  • Preserves identifier keys
  • Produces clean HCL output
  • Supports dumping runtime structures

Optional Field Serialization Cleanup

Many configuration fields now use:

#[serde(skip_serializing_if = "Option::is_none")]

This keeps generated configurations clean and avoids emitting default values unnecessarily.

WASM Feature Gate Cleanup

Header mutation APIs are now gated behind the wasm feature.
They are only available when WASM support is enabled.

Removal of rust-embed

Embedded config templates have been removed.
Templates are now generated programmatically at runtime, reducing binary size and improving clarity.

Validation Improvements

  • Identity header limits are now range validated
  • Validation error output improved
  • Fixture failures now clearly display violations

Documentation Updates

  • CLI docs updated for new flags and behavior
  • Logging docs clarified
  • Getting started guide updated for template-based initialization
  • Roadmap reorganized for clearer phase separation

Upgrade Notes

If upgrading:

In snakeway.hcl:

  1. Rename devices.d/device.d/
  2. Update the include block to use ingresses

In your Identity device config file:

  1. Consider explicitly setting:
    • max_x_forwarded_for_length
    • max_user_agent_length

Snakeway v0.6.0

Highlights

  • New built-in Network Policy device (L7 allow/deny by client identity)

    • Add a network_policy_device to enforce CIDR-based allow/deny decisions at the HTTP layer.
    • Includes forwarded-request handling controls (e.g., whether to allow forwarded requests and what to do when forwarded headers are invalid).
  • New built-in Request Rate Limiting device (L7)

    • Add a request_rate_limiting_device to cap request volume per client over a rolling time window.
  • Listener-level connection controls

    • Connection filtering (CIDR allow/deny + IP family controls + behavior when peer address is missing).
    • Connection rate limiting to cap new connections per client per window.
    • These are configured under your listener bind block, so you can enforce them before requests even reach routing/devices.
  • WASM tooling renamed and clarified

    • The CLI command previously surfaced as “plugin” tooling is now presented as WASM device tooling to match Snakeway’s “device” model.
  • Docs overhaul focused on “how to operate Snakeway”

    • Device configuration docs were reorganized under /configuration/devices/*.
    • New/updated guides for CLI usage, WASM device authoring, and runtime logging.

Everything Else

  • Config scaffolding and templates

    • The repo now includes config templates for common devices (identity, network policy, request filtering, request rate limiting, structured logging) and ingress examples.
    • snakeway config init uses embedded templates to generate a starter config directory (useful for first-run setup and repeatable environments).
  • Config dump improvements

    • snakeway config dump supports emitting both “spec” (as-written config) and “runtime” (lowered internal representation) to help debug what Snakeway actually loaded.
  • Routing and service spec ergonomics

    • Service route settings were refined (for example, websocket connection limits can be expressed as an optional field where applicable).
  • Dependency upgrades that matter to operators

    • Upgraded the underlying Pingora dependency line and related runtime components, which is groundwork for newer networking features and future performance work.
    • WASM toolchain dependencies were updated to newer versions, aligning with current WASI/WIT tooling.
  • Tests and fixtures refreshed

    • Expanded integration coverage for newly added devices and network-level controls to reduce regressions in “real proxy” scenarios.

If you are upgrading from v0.5.4:

  • Review any configs that previously relied on “plugin” CLI naming—use the WASM device command naming going forward.
  • If you want connection-level admission control, move those policies into the listener bind configuration (connection filter / connection rate limiting).
  • If you want request-level admission control, enable the new L7 devices (Network Policy / Request Rate Limiting) in devices.d/.