Linux keychain dials a new D-Bus connection per operation, defeating per-entry access confirmation
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 42/100
調査の方向性
store/keychain/keychain_linux.go の operationService と store/keychain/internal/go-keychain/secretservice/secretservice.go の kc.NewService から始め、次に store.Store のライフサイクルと withRelockRetry を調べます。完成した変更では、ストアごとの SecretService セッションを操作間で安全に再利用し、列挙された古い D-Bus エラーから復旧し、短時間しか存続しない ensureAvailable probe を壊すことなく、上限付きのクリーンアップを提供する必要があります。
索引モデルが issue の本文から書いたものです。
説明
Problem
The Linux keychain store dials a private D-Bus connection, opens a Secret
Service session, and closes both on every operation (operationService in
store/keychain/keychain_linux.go, kc.NewService in
store/keychain/internal/go-keychain/secretservice/secretservice.go).
Each connection presents a new unique bus name, so the provider sees a new
client on every call. docker/sbx-releases#579 reports the result: with
per-entry access confirmation enabled, one login produced 61 D-Bus
connections, 119 OpenSession calls, and roughly 300 confirmation popups —
more than a user can confirm before sbx's own timeout expires.
Per-call churn causes three failures:
- "Remember this application" binds to the connection's unique bus name, so
the user's choice never applies to the next operation. - Unlocks die with their connection, so every operation repeats the
IsLocked→Unlock→Promptcycle thatwithRelockRetryexists to
absorb. - Every operation pays connection setup, session negotiation, and teardown.
What the spec says
The Secret Service spec binds a session to the client's bus connection: it
closes on disconnect or explicit Close(), has no timeout, and calls
multiple sessions per client "typically unnecessary"
(https://specifications.freedesktop.org/secret-service/latest/sessions.html).
libsecret, the reference client, keeps one process-global connection and
session. Reuse is the intended model.
Proposal
Cache one (SecretService, Session) pair per store, dial it lazily, and
reuse it for all operations.
- Serialize operations with a mutex:
PromptAndWaitshares one signal
channel per connection and is not thread-safe. (Alternative: route
Completedsignals by prompt path.) - Dial the cached connection under a detached context, so a caller's
cancellation cannot kill the shared connection; keep per-operation
contexts for prompt waits. - Drop the cache and redial once on stale-state errors —
org.freedesktop.Secret.Error.NoSession,NoSuchObject,
ServiceUnknown, or a closed connection — matched on structured D-Bus
error names, asisLockedDBusErrordoes today. - Give the store a teardown path for the cached connection (see Risks).
- Keep
withRelockRetryas a safety net and keepensureAvailable's
short-lived probe connection.
Risks
The store model changes: state and teardown. Today every operation is
self-contained — dial, work, close — so a store holds no resources between
calls and needs no teardown. A cached connection makes the store stateful.
store.Store has no Close; the Linux store would need a teardown function
(for example Close() error behind an optional interface), and callers
would own calling it — including embedders that construct stores freely,
one per request or per test.
Open D-Bus connections can leak. An abandoned store holds one live bus
connection — a unix-socket fd, a unique bus name, an open session — until
process exit. The bus daemon caps connections per user, so in a long-lived
process the leak is real, not cosmetic.
Mitigation. An idle timeout bounds both risks without an API change:
close the cached connection after a short idle period, redial on next use.
A run still collapses to one connection, and an abandoned store self-heals.
Timeout and teardown hook compose; the timeout alone may suffice.
Expected effect
One connection per run. Unlocks and "remember this application" persist
across operations. Prompt count drops from one cycle per operation to one
confirmation per entry — or one total, once remembered.
Refs docker/sbx-releases#579.
- 主要言語
- Go
- スター
- 94
- フォーク
- 17
- 平均マージ
- 7時間 52分
- マージ済み PR(30日)
- 31
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
docker/secrets-engine のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
docker/secrets-engine#682 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
docker/secrets-engine#676 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
docker/secrets-engine#665 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 65/100
docker/secrets-engine#584 · コメント 1 件 · リアクション 2 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
docker/secrets-engine#551 · コメント 3 件 · リアクション 3 件 ·
メンテナーはふだん 1 日以内に返信
docker/secrets-engine の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
open-telemetry/opentelemetry-go-compile-instrumentation#1467 ·
メンテナーはふだん 3 日以内に返信
-
Python 3.15 support対応中かも @amnesiaof が今日担当しました。 オープンL: python L: python:uv
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
dependabot/dependabot-core#16524 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
duplication
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
openvibely/openvibely#1443 ·
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 60/100
canonical/service-mesh#845 ·
メンテナーはふだん 1 日以内に返信