[package]
name = "estate-front"
# 0.2.0 (2026-10-27, R5G): breaking after crates.io's 0.1.5: `web::serve::admit` is gone and
# `App::set_outer` is crate-only (RA4-22, RA4-23); the RA4-11 accept-loop reasons and connection cap.
# 0.1.4 (2026-10-25, lane acme): ACME checks DNS first (web::dns); a name that does not point
# here is not an ACME failure. web::status: per certificate valid until, next attempt, last
# reason, "try now" and the one-hour ALERT tls.no-certificate. Additive.
# 0.1.1 (2026-10-21, lane G5, A7 row 13): `relay::Relay::take_with_psk` lists each box with the
# pre-shared key the front was fed for it (`wg_psk.<box>`, Gunnar 356e8dd2), and
# `Relay::with_psk`. Additive: `take` is `take_with_psk` with none.
# 0.2.1 (2026-10-28, RA5-22): :443 per-peer cap (64), request-head (15 s) and idle (120 s) timeouts.
version = "0.3.1" # RA5-34 caller_key is the one ClientKey rule; 0.3.0 RA5-1: breaking: Routed::grpc_services; RepoRoute::of and route::start take the product's carried gRPC list
edition = "2021"
description = "What an estate's FRONT (vm1) does that is no product's: its own HTTPS (the certificate fed, kept or from ACME HTTP-01 in-process, the hand-over to its successor, :80/:443 swapped live, callback-only hosts, a payment vendor's callback carried to monetize), a product's repository carried through :443 to the primary, a TCP port forwarded to the primary, and the estate's WireGuard relay. Moved as is from gunnar-front (2026-09-27) when holger's estate grew its own front; no product type in it."
license = "MIT OR Apache-2.0"
repository = "https://git.gunnar.rs/nordisk/edda"
keywords = ["acme", "tls", "front", "estate", "wireguard"]
categories = ["network-programming", "web-programming"]
exclude = ["/.nornir/"]
[features]
default = []
# **ACME in this process** (Let's Encrypt HTTP-01, `web::acme`; A32-11, owner rule 7): OFF by default,
# so the airgap default links no ACME client and dials no directory; without it `acme::issue_as`
# answers `acme::NOT_BUILT` and a fed or kept certificate is served. A product's front that takes
# its certificate from Let's Encrypt names it (holger-estate-front; gunnar-front's `acme`).
acme = ["dep:instant-acme", "dep:hyper-rustls", "dep:webpki-roots"]
# `certs::self_signed` for a product's own tests of the certificate road.
test-support = ["dep:rcgen", "dep:time"]
[dependencies]
# The one client partition rule (RA5-34): `client-key` only, no dependencies of its own.
nornir-auth-webauthn = { path = "../nornir-auth-webauthn", version = "0.2.3", default-features = false, features = ["client-key"] }
# The relay: wg-appliance-core's userspace HubRelay (`hubfixture`, its default).
wg-appliance-core = { path = "../wg-appliance-core", version = "0.1.7" }
# The kept certificate is written with PID 1's durable writer (staged, fsync, rename, fsync of
# the directory; lane G9, A7 row 24). Its default build: libc only.
appliance-pid1 = { path = "../appliance-pid1", version = "0.1.5" }
# rustls over `ring`, named explicitly (`builder_with_provider`): a product's
# graph may also carry aws-lc-rs, and rustls refuses to guess between two. The
# ACME client is `instant-acme` (pure Rust, RFC 8555) with its `ring` + `rcgen`
# halves only — NOT its `hyper-rustls` feature, which brings the platform
# verifier: an OS-less front has no trust store, so the client is hyper-rustls
# with the compiled-in Mozilla roots. (gunnar-front's choices, kept.)
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
tokio-rustls = { version = "0.26", default-features = false, features = ["ring", "tls12"] }
instant-acme = { version = "0.8.5", default-features = false, features = ["ring", "rcgen"], optional = true }
hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "ring", "tls12", "webpki-roots"], optional = true }
webpki-roots = { version = "1", optional = true }
hyper-util = { version = "0.1", features = ["client-legacy", "http1", "http2", "server", "server-auto", "service", "tokio"] }
http = "1"
bytes = "1"
hyper = { version = "1", default-features = false }
axum = { version = "0.8", default-features = false, features = ["tokio", "http1", "http2", "query"] }
tower = { version = "0.5", features = ["util"] }
tokio = { version = "1", features = ["net", "rt", "time", "sync", "macros"] }
tracing = "0.1"
x509-parser = "0.16"
serde_json = "1"
blake3 = "1"
rcgen = { version = "0.13", default-features = false, features = ["crypto", "pem", "ring"], optional = true }
time = { version = "0.3", default-features = false, features = ["std"], optional = true }
[dev-dependencies]
# A box sealing to the wrong front key, for the relay's counters test (lane D12).
boringtun = { version = "0.7.1", default-features = false }
tokio = { version = "1", features = ["macros", "rt-multi-thread", "net", "io-util", "time", "sync"] }
tempfile = "3"
rcgen = { version = "0.13", default-features = false, features = ["crypto", "pem", "ring", "x509-parser"] }
time = { version = "0.3", default-features = false, features = ["std"] }
base64 = "0.23"
sha2 = "0.10"
rand_core = { version = "0.6", features = ["getrandom"] }