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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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.rsblocks provisioning the gRPC bearer token at startup — the daemon hangs with no error and no log line, the worst possible failure shape.outbox.rsblocks provisioning the webhook signing key on firstCALL WEBHOOKdispatch, parking the outbox worker.Both reads should be bounded the same way the CLI's now is (detached
std::threadbehind atokio::time::timeout— notspawn_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.Fixed in #424 (
90eab25), merged todev. 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.