feat(marmot-interop): let wnd run in sandboxes without kernel keyring

Containers / CI often block the keyutils syscalls wnd uses by default
to store secret keys (add_key returns EACCES, keyctl_search returns
ENOSYS). The integration-tests feature ships a mock keyring store, but
the stock wnd binary doesn't wire it up. Add a tiny opt-in patch.

Changes:
- headless/patches/whitenoise-mock-keyring.patch: if built with the
  integration-tests feature and \$WHITENOISE_MOCK_KEYRING is set, wnd
  calls Whitenoise::initialize_mock_keyring_store() before the normal
  init path. Harmless on production builds.
- headless/setup.sh: apply both harness patches generically from a
  list; build wn/wnd with --features cli,integration-tests; export
  WHITENOISE_MOCK_KEYRING=1 alongside WHITENOISE_DISCOVERY_RELAYS when
  launching each daemon.
- preflight swaps keyctl for patch in required tools — we no longer
  need a real session keyring.

https://claude.ai/code/session_01M6dCKAF5Y1VyHGZPjzwDXq
This commit is contained in:
Claude
2026-04-21 22:20:54 +00:00
parent 6213fb2197
commit 37515ec975
2 changed files with 58 additions and 23 deletions
@@ -0,0 +1,18 @@
--- a/src/bin/wnd.rs
+++ b/src/bin/wnd.rs
@@ -22,6 +22,15 @@
let args = Args::parse();
let config = Config::resolve(args.data_dir.as_ref(), args.logs_dir.as_ref());
+ // marmot-interop-headless patch: allow sandboxes/CI without a real
+ // kernel keyring to fall back to the integration-tests mock keyring
+ // by setting $WHITENOISE_MOCK_KEYRING=1. Requires the daemon to be
+ // built with --features cli,integration-tests. No effect otherwise.
+ #[cfg(feature = "integration-tests")]
+ if std::env::var("WHITENOISE_MOCK_KEYRING").is_ok() {
+ Whitenoise::initialize_mock_keyring_store();
+ }
+
let wn_config = WhitenoiseConfig::new(&config.data_dir, &config.logs_dir, KEYRING_SERVICE_ID);
Whitenoise::initialize_whitenoise(wn_config).await?;