Files
2026-10-27 22:44:06 +02:00

7.1 KiB

Dependency Policy and Approved Choices

Read this document before changing dependencies, features, or build/runtime requirements. The approved choices may be introduced without renewed approval; unapproved direct dependencies require prior user agreement.

Approved dependencies

The user has approved the following choices. They may be introduced when their implementation stage needs them without requesting approval again. Approval does not mean they are already installed. Select compatible maintained versions and minimal features, and record exact resolved versions in Cargo.lock.

Purpose Approved crates Intended use
Terminal UI ratatui, crossterm Widgets, layout, keyboard events, terminal lifecycle
Serialization and settings serde, toml Typed application settings and metadata; TOML backup manifests
Typed errors thiserror Recoverable domain and adapter errors
Address ranges ipnet IPv4/IPv6 subnet validation and allocation support
Dates time UTC metadata, backup timestamps, handshake display
QR encoding qrcode Additional terminal delivery of client configurations
Backup archives tar Archives with manifests; initially without compression
Temporary files tempfile Staged file replacement and isolated test directories
Linux operations rustix User checks, controlled filesystem operations, and bounded Generic Netlink runtime reads
Encrypted vault age Recipient encryption and password protection of the vault secret key
WireGuard key pairs x25519-dalek Key generation and public/private key matching
Secure randomness getrandom Operating-system randomness for key generation
WireGuard key encoding base64 Reading and writing WireGuard key representations
Secret handling secrecy, zeroize Explicit secret exposure and supported memory cleanup
WireGuard runtime wireguard-uapi Direct Linux interface, peer, handshake, and traffic queries
Service management zbus 5.19.0 Async systemd D-Bus requests and job completion tracking
Container integration tests testcontainers Alpine server/client lifecycle; development dependency only
  • Use a separate vault key pair from all WireGuard client/server key pairs. Encrypt each client secret to the vault public key; protect the vault secret key with password-based encryption using the established age format. Do not replace this with password-only encryption of every new client record, which would require a password on creation.
  • wireguard-uapi remains an approved option but is not selected for the bounded runtime reader: its public read API does not expose a receive deadline or a complete-dump guarantee. A systemd D-Bus request being accepted is not proof of job completion or successful VPN application.
  • Runtime observation uses the already approved rustix 1.1.5 safe net and event APIs for a nonblocking Linux Generic Netlink socket, polling and datagram I/O. This keeps one monotonic deadline and exact truncation/sender checks around the checked WireGuard decoder. It does not add a direct dependency or use a subprocess.
  • The systemd adapter pins zbus 5.19.0 with default features disabled and async-io plus p2p enabled. It first uses the system bus, then selects /run/systemd/private peer mode only when the bus connection reports a missing/refused/disconnected endpoint, before submitting any restart request. Permission errors, authentication/protocol failures, and deadline expiry do not trigger fallback. Private mode uses EXTERNAL authentication and checks the peer UID is root. Bus calls use the systemd well-known destination; private calls omit the destination and avoid bus-daemon owner monitoring. zbus's local peer signal matching tracks JobRemoved after systemd Subscribe. Each call uses zbus's asynchronous APIs driven by a small standard-library wake/park loop so operations share the caller's monotonic deadline. zbus's async-io backend owns internal I/O executor thread(s); callers must allow the connection to be dropped after each operation. Signal polling uses zbus 5.19.0's doc-hidden export::futures_core re-export to avoid another direct dependency; keep zbus pinned until that implementation is deliberately migrated. The private systemd socket is an internal systemd interface and may change between releases.
  • Avoid incompatible duplicate versions of secret-handling types where library APIs exchange them. Use supported re-exports where appropriate rather than adding redundant direct dependencies.
  • Additional direct dependencies still require the comparison and prior agreement required by AGENTS.md, including any test/build helpers. Transitive dependencies of approved crates are resolved through Cargo; review their compatibility and runtime requirements. Do not add a direct tokio dependency merely because an approved library uses an async runtime internally.
  • clap, chrono, SQLite, a generic INI writer, a mocking framework, and archive compression libraries are not part of the approved initial set. Use the standard library for the small startup argument surface and background threads/channels where sufficient.

External runtime and build requirements

  • Production requires Linux with WireGuard support and the existing configured systemd service. Restart uses the system D-Bus when available and can use systemd's root-only /run/systemd/private peer socket when the bus endpoint is unavailable. Permission or authentication failures and timeouts stop the operation without trying the private socket. The private socket is not a stable public systemd API. Existing wg-quick service dependencies remain necessary if that is how the service manages the interface.
  • The application uses library APIs rather than invoking wg, systemctl, age, qrencode, tar, or openssl for its own operations. Test fixture setup and the existing WireGuard service may use their required system tools; that does not create an application subprocess fallback.
  • Rust/Cargo and the target toolchain/linker are build requirements, not production application requirements. Verify the release binary's actual dynamic-library requirements rather than promising an automatically static executable.
  • A Docker-API-compatible runtime, test images, and container tools belong to the integration environment only. Production does not need Docker or Testcontainers.