a173ced9b2
Closes the v3.3 "bridges by hand" honest limitation. Admins now publish a
CA-signed manifest with the current bridge list; clients re-read it from
disk on a timer and merge it with the static [client] bridges. Cuts the
"rotate the bridge list" cycle from "edit every client config" to
"distribute one signed file".
- New aura sign-bridges CLI:
aura sign-bridges --ca /etc/aura/pki \
--bridges "ip1:443,ip2:443" \
--ttl-days 7 \
--out /var/aura/bridges.signed
- Manifest format (single file, text + signature block, same shape as the
in-band CRL):
AURA-BRIDGES-v1
{"version":1,"generated_at":...,"expires_at":...,"bridges":[...]}
--SIGNATURE--
<hex ECDSA-P256/SHA-256 over body>
- aura-pki now exports `sign_ecdsa_p256` / `verify_ecdsa_p256` so CRL and
bridges share ONE signing primitive (no copy-paste). CRL keeps working.
- aura-cli::bridges::BridgeManifest + BridgesDiscoveryWatcher: new
module. encode_signed/load_signed_verified verifies signature + rejects
expired manifests. Watcher spawns a tokio interval that re-reads the
file; on load failure (truncated, expired, bad sig) the previous
snapshot is kept — bridges never collapse to empty.
- New [client.bridges_discovery] {enabled, manifest_path,
refresh_interval_secs}; serde(default) so v3.2 configs keep working.
- Merge strategy: manifest EXTENDS static [client] bridges, dedup by
SocketAddr, static-first ordering. Static remains as fallback.
- 13 new tests (8 lib unit + 4 integration + 1 config). Workspace: 310
tests passed (+13), clippy -D warnings clean, fmt clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>