7.8 KiB
Verification report - RustProxy 0.24.10
Scope
RustProxy 0.24.10 implements the Secret Store + password-encrypted full backup/restore and optional ERROR-only file logging specifications. Secret Store adds schema version 7, encrypts ACME DNS-provider credentials with a local master key, migrates legacy provider .ini files, and recreates plaintext credential files only around the external Certbot operation. Full backup/restore uses Argon2id plus authenticated AES-256-GCM encryption, an explicit manifest, Secret Store key wrapping, staged validation and atomic data-directory activation. Error-file logging is a separate, disabled-by-default asynchronous bounded sink with JSON/RAW formats, central secret redaction and external logrotate rotation.
The release also retains the 0.24.8 overview cache diagnostics, 0.24.7 transform resource controls and 0.24.6 cache/background-worker memory hardening described by the earlier audit material below.
Source contracts reviewed
- SQLite schema version 7 includes the generic encrypted
secret_storetable; stored secret values are AES-256-GCM ciphertext with per-record nonces and the application master key lives outside SQLite in a private file. - Cloudflare, OVH and RFC2136 ACME credentials are validated, imported into Secret Store, decrypted only when required, and legacy provider
.inifiles are removed after successful migration. Certbot credential files are temporary and removed infinallypaths. rust-proxy backup createwrites a new.rpbfile outside the data directory, derives an independent backup key with Argon2id, encrypts authenticated chunks with AES-256-GCM, excludes cache/log/runtime data and wraps the Secret Store master key inside the encrypted backup.rust-proxy backup restorerequires an interactive password, decrypts into private staging, validates manifest/checksums/schema/configuration/Secret Store decryptability before activation, then switches the data directory by rename with rollback on activation failure.error_logis independent from normal access logging, defaults disabled, accepts onlyERROR, supports JSON/RAW, uses a bounded queue and a single asynchronous writer, handles filesystem failures without terminating RustProxy, and relies on systemlogrotaterather than application rollover.- Error File stays in the existing revisioned
loggingsection: its separate dashboard form and the access-log form both save a composite{ logging, error_log }value through/api/config/logging. A database-reopen regression verifies thatenabled, path and format survive restart, the standalone/api/config/error_logroute is intentionally absent, and historical access-only/api/config/loggingpayloads remain accepted for compatibility. The redundant Error Log help sentence is absent from the panel. - The stderr/journald path, access-log sinks and the optional error-file sink share secret-redaction helpers for authorization/provider/password/private-key material.
- The KV secret-redaction expression uses a hash-delimited Rust raw string, avoiding the
E0762unterminated-character-literal parser failure while preserving the same redaction character class. - The release checker preserves the existing dashboard contract while using bundled roots plus common system CA bundles (
SSL_CERT_FILE,CURL_CA_BUNDLE, FreeBSD/OPNsense and Linux paths), follows at most five credential-free HTTP(S) redirects without HTTPS-to-HTTP downgrade, and reports network/TLS/HTTP/parser failures atERRORlevel so the optional error-file sink receives them. - The overview Cache RAM block keeps separate histories for HOT allocated bytes, transient RAM, fill bytes, COLD queue bytes, COLD I/O bytes and COLD disk bytes; the disk series is never included in process RAM accounting.
- HOT and transient histories are rendered against their runtime limits, while COLD storage is rendered against the configured COLD byte budget.
- The long
memoryAccountingHintremains translated and available on demand through the Process information control instead of consuming permanent dashboard height. Response time history is no longer collapsible and has the same compact information control explaining that it charts successive samples of the cumulative mean duration of completed HTTP exchanges. - Transform
preset,memory_budget_bytesandmax_inflightare part of the normal revisioned Settings document and therefore persist in SQLite; the reopen test covers them. - Existing configurations default to 128 MiB transform temporary memory and 32 concurrent attempts.
- New transform attempts use atomic runtime byte/concurrency reservations and fail open with fixed
memory_pressure/concurrency_pressurereasons rather than queueing full-body work. - Presets modify only resource limits; transform type switches and extension allow-lists remain independent.
- Global transform representation/eligibility settings participate in cache compatibility identity. Resource-only preset/budget/concurrency fields do not.
- OpenAPI and both language packs expose the new controls and preset states.
GET /api/statusexposestransform_resourcesandmemory_accounting; the latter keeps process RSS separate from HOT/transient cache accounting and treats transform bytes as an overlapping conservative reservation.- Cache runtime telemetry exposes COLD byte/object limits so the overview can show disk occupancy against configured capacity without mixing disk and RAM.
GET /api/transformexposes current process-wide reserved transform bytes and active slots alongside the existing counters.- 0.24.6 aggregate/decode bounds, allocation reductions and bounded cache/background workers remain in place.
- The bounded transform-body collection path maps its boxed body error explicitly into
anyhow::Error; source/release regressions reject the incompatible.context(...)form that was reported by an external compiler run. - A subsequent external Rust compile reached warning-only status and reported four lint warnings. The source now keeps the COLD transient read lease explicitly alive via
_read_lease, names the RAII-onlyTransientLeasefield_inner, and removes the two dead CSSlast_charassignments without lint suppression. Offline source/release regressions pin those shapes; a compiler-enabled rerun is still required to confirm a warning-clean build.
Verification status in this workspace
| Check | Status |
|---|---|
python3 scripts/preflight.py |
PASS |
python3 scripts/langs_check.py |
PASS |
python3 scripts/memory_contracts.py |
PASS |
Browser JavaScript node --check |
PASS for all administration JS bundles |
| OpenAPI/language JSON parse | PASS |
Shell bash -n |
PASS |
| Python syntax / bytecode compile, including ACME provider worker | PASS |
| Secret Store / encrypted backup / error-log / portable update-check source-contract regression checks | PASS |
SQLite schema 7 migration smoke (secret_store) |
PASS |
Docker agent go test ./... / go vet ./... / go build ./... |
PASS |
python3 scripts/check_source.py |
PASS |
python3 scripts/release_smoke.py |
PASS |
| FreeBSD/OPNsense live release-check execution | NOT RUN in this workspace; source contract and platform CA paths are covered, target runtime confirmation is still required |
./dev.sh fmt / cargo fmt --all |
BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
./dev.sh check / cargo check --locked --all-targets |
BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
./dev.sh test Rust phase |
BLOCKED: Rust/Cargo toolchain unavailable in this workspace |
| Sustained per-preset transform RSS/heap profiling | release-host acceptance gate |
See V0.24.8_AUDIT.md for the dashboard change and V0.24.7_AUDIT.md for the retained transform resource-control design and runtime acceptance gate.