nunciod hangs at startup if its keyring read blocks #421

Closed
opened 2026-08-15 01:03:59 +00:00 by KofTwentyTwo · 1 comment
KofTwentyTwo commented 2026-08-15 01:03:59 +00:00 (Migrated from github.com)

nunciod's own keyring reads are unbounded. #420 bounded the CLI's read after a macOS keychain ACL consent prompt made the call never return in a non-interactive session; the daemon's reads were explicitly left unfixed.

The daemon mostly mints its key material, so it does not normally hit the cross-binary ACL prompt — but "does not normally" is not "cannot". A keychain locked by screen-lock, a migrated or restored keychain whose ACL no longer trusts the binary, a re-signed or rebuilt nunciod, or a Linux Secret Service with no unlocked collection all block the read.

When that happens today:

  • main.rs blocks provisioning the gRPC bearer token at startup — the daemon hangs with no error and no log line, the worst possible failure shape.
  • outbox.rs blocks provisioning the webhook signing key on first CALL WEBHOOK dispatch, parking the outbox worker.

Both reads should be bounded the same way the CLI's now is (detached std::thread behind a tokio::time::timeout — not spawn_blocking, since Tokio joins its blocking pool at shutdown and would merely relocate the hang to process exit), terminating with an honest, actionable error that names which key material could not be read and suggests the likely cause. No environment-variable token override for the daemon: the daemon must never accept its bearer token from the environment.

`nunciod`'s own keyring reads are unbounded. #420 bounded the *CLI's* read after a macOS keychain ACL consent prompt made the call never return in a non-interactive session; the daemon's reads were explicitly left unfixed. The daemon mostly *mints* its key material, so it does not normally hit the cross-binary ACL prompt — but "does not normally" is not "cannot". A keychain locked by screen-lock, a migrated or restored keychain whose ACL no longer trusts the binary, a re-signed or rebuilt `nunciod`, or a Linux Secret Service with no unlocked collection all block the read. When that happens today: - `main.rs` blocks provisioning the gRPC bearer token at startup — the daemon hangs with no error and no log line, the worst possible failure shape. - `outbox.rs` blocks provisioning the webhook signing key on first `CALL WEBHOOK` dispatch, parking the outbox worker. Both reads should be bounded the same way the CLI's now is (detached `std::thread` behind a `tokio::time::timeout` — not `spawn_blocking`, since Tokio joins its blocking pool at shutdown and would merely relocate the hang to process exit), terminating with an honest, actionable error that names which key material could not be read and suggests the likely cause. No environment-variable token override for the daemon: the daemon must never accept its bearer token from the environment.
KofTwentyTwo commented 2026-08-15 01:14:17 +00:00 (Migrated from github.com)

Fixed in #424 (90eab25), merged to dev. The daemon's gRPC bearer-token read at startup and the webhook signing-key read are now bounded by the same shared helper the CLI uses, so a locked keychain or a stale ACL surfaces an honest error instead of hanging with no log line. No environment override was added for the daemon — that stays CLI-only.

Not covered, deliberately: per-account password reads in the request/worker paths remain unbounded. They stall one call rather than the whole daemon, so they are a lower-severity follow-up.

Fixed in #424 (`90eab25`), merged to `dev`. The daemon's gRPC bearer-token read at startup and the webhook signing-key read are now bounded by the same shared helper the CLI uses, so a locked keychain or a stale ACL surfaces an honest error instead of hanging with no log line. No environment override was added for the daemon — that stays CLI-only. Not covered, deliberately: per-account password reads in the request/worker paths remain unbounded. They stall one call rather than the whole daemon, so they are a lower-severity follow-up.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: KofTwentyTwo/nuncio#421