feat(container): manifest-declared generated secrets + companion/quadlet hardening

Generated-secrets system: apps declare `generated_secrets` in their manifest
(kinds hex16/hex32/bcrypt); `container::secrets::ensure_generated_secrets`
materialises them 0600/rootless in resolve_dynamic_env — idempotent and
self-healing (recovers wrongly root-owned secrets with no privilege). Replaces
per-app Rust (deletes ensure_fmcd_password). fedimint-clientd/gateway manifests
now declare fmcd-password / fedimint-gateway-hash.

companion.rs: rebuild the auto-built :latest image when its build context changes
(staleness check) so baked-in fixes (e.g. guardian-UI CSS) actually reach nodes.

quadlet.rs: skip PublishPort under Network=host (podman rejects the combo, exit
125) + regression tests.

UI: "Fedimint Guardian" rename, fedimint-clientd/nostr-rs-relay/meshtastic tagged
as Services (headless backends), gateway icon fallback.

Deployed + verified on .228 (generated-secrets fixed fedimint-gateway start;
grafana/strfry orphan crash-loop units removed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-06-21 05:11:07 -04:00
co-authored by Claude Opus 4.8
parent db7d424bff
commit 03a4ee1b30
16 changed files with 521 additions and 52 deletions
+5
View File
@@ -16,6 +16,11 @@ app:
# fmcd and retries on join failure (fmcd needs >=1 federation to boot), so an
# unreachable default never crash-loops. All config comes from FMCD_* env
# below. Nodes can join more federations via wallet.fedimint-join.
# Auto-generated on first install (random hex, 0600, rootless-owned) so the
# app needs no host provisioning. The wallet bridge reads the same file.
generated_secrets:
- name: fmcd-password
kind: hex16
secret_env:
- key: FMCD_PASSWORD
secret_file: fmcd-password