aaif-goose / aaif-goose/goose

Prevent headless ACP from hanging on system keyring reads

Open
#11,799 0 comments 0 reactions 1 assignee Claimed by @Abhijay007 View on GitHub
Dominant language
Rust
Stars
54.2k
Forks
6.2k
Avg merge
3d 4h
Merged PRs (30d)
240

Description

🤖 > **Disclaimer:** This is a potential issue identified during code review. As far as we know, it has not been observed in the wild.

**Describe the bug**

With the default `system-keyring` feature, `goose acp` can hang indefinitely when a headless process triggers a system keyring prompt that cannot be answered over piped stdio. On macOS, this can occur when an unsigned process triggers a Keychain ACL prompt.

Provider construction during `session/new` reads secrets synchronously. `Config::all_secrets()` also holds its cache mutex while loading them, so a blocked keyring read can occupy a Tokio worker and block concurrent secret users.

---

**To reproduce**

1. Run `goose acp` over piped stdio in a headless context that triggers a Keychain authorization prompt.
2. Send `session/new` for a provider that reads a stored secret.
3. The request waits indefinitely because the prompt cannot be answered.

---

**Expected behavior**

Noninteractive ACP requests should not indefinitely block runtime workers or concurrent secret lookups. Interactive CLI and desktop users should still be able to complete system authentication without a short global timeout.

Suggested direction:

- Move ACP keyring reads off Tokio core workers.
- Avoid holding the secrets-cache mutex across the blocking read.
- If a timeout is needed, scope and configure it for noninteractive execution, fail closed with guidance to use environment credentials or `GOOSE_DISABLE_KEYRING=1`, and do not treat a timeout as a missing keyring entry.
- Avoid accumulating blocked threads, since timing out the caller does not cancel the underlying OS keyring request.

---

**Verification**

Using an injectable blocking keyring read, verify that ACP returns within its configured bound, concurrent secret users are not blocked on the cache mutex, and repeated requests do not create unbounded blocked workers. Also verify that interactive keyring prompts can wait longer than three seconds.

---

**Environment**

- **OS:** Primarily macOS; audit Linux and Windows behavior
- **Interface:** ACP
- **Version:** Current `main`

Do not begin implementation until the issue reaches **Ready** on the [Goose Issues board](https://github.com/orgs/aaif-goose/projects/1).

Contributor guide

Open the contributing guide

Research direction

Look at the provider construction in `session/new` and `Config::all_secrets()` to see where secrets are read synchronously and the cache mutex is held. The fix involves moving keyring reads off Tokio workers, avoiding mutex locks during blocking reads, and adding a timeout for noninteractive contexts. Test with an injectable blocking keyring read to verify ACP returns within bounds and concurrent users are not blocked.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
authentication, cli, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.