1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! Credential resolver + secure `KeyStore` — the storage and naming half of
//! the credential authority (issue #2401; promoted to a top-level module by
//! #4564, DOC-45).
//!
//! Why: every consumer needs the same answer to "where is the secret for
//! provider X" — checked in the same order, with the same
//! never-print-the-value discipline. Before this module, each crate either
//! read `std::env::var` directly (no `.env.local` fallback, no secure-store
//! fallback) or embedded its own ad hoc dotenv call. It lived under
//! `inference::` while its only consumers were LLM providers; by #4564 four of
//! its ten registry entries were Slack/Telegram/`claude-code` tokens and the
//! path had become actively misleading, which is why consumers kept adding a
//! raw `std::env::var` read instead of finding it.
//!
//! What: two layers.
//!
//! **Storage and naming.** [`KeyStore`] is the storage trait
//! ([`memory_store::MemoryKeyStore`], [`file_store::FileKeyStore`], and —
//! behind the `keyring-store` feature — `keyring_store::KeyringStore`).
//! [`registry`] is the provider→environment-variable table.
//! [`resolver::resolve_key`] applies the 3-tier precedence (process env var via
//! [`registry::env_var_for`] > `.env.local` via `dotenv` >
//! [`resolver::default_store`]). `redact` holds the credential-masking
//! implementations: [`redact::redact_secret`] (mask a value you are naming;
//! also reused by `memory_core::filter`) and [`redact::scrub_secrets`] (remove
//! values you hold from text you don't control), with
//! [`redact::resolved_secret_values`] supplying the latter's needle set.
//!
//! **Reference and use-time resolution** (#4565). [`CredentialRef`] is the
//! opaque, non-secret handle a config row holds *instead of* a credential;
//! [`Secret`] is what a resolved credential comes back in, and it cannot be
//! serialised, cloned, or printed; [`authority::resolve`] is the single entry
//! point, taking a [`Principal`] and a [`Scope`] so resolution happens where
//! the credential is consumed rather than at config load;
//! [`CredentialError`] is the five-variant denial taxonomy.
//!
//! This module holds **no** authorization. Which principal may resolve which
//! credential is DOC-45 §5 and lands with #4566; the storage tiers here
//! determine *where a value lives*, never *who may read it* (`C-9.8`). The
//! [`Principal`] argument exists so no consumer is migrated twice when that
//! check lands — see [`authority`]'s honesty clause.
//!
//! Test: `cargo test -p trusty-common --features credentials -- credentials::`
//! and (KeyringStore compile/probe-failure-path only, never a real keychain)
//! `cargo test -p trusty-common --features keyring-store -- credentials::`.
//!
//! [`memory_store::MemoryKeyStore`]: crate::credentials::MemoryKeyStore
//! [`file_store::FileKeyStore`]: crate::credentials::FileKeyStore
//! [`registry`]: crate::credentials::registry
//! [`resolver::resolve_key`]: crate::credentials::resolve_key
//! [`registry::env_var_for`]: crate::credentials::registry::env_var_for
//! [`resolver::default_store`]: crate::credentials::default_store
//! [`redact::redact_secret`]: crate::credentials::redact_secret
//! [`redact::scrub_secrets`]: crate::credentials::scrub_secrets
//! [`redact::resolved_secret_values`]: crate::credentials::resolved_secret_values
//! [`CredentialRef`]: crate::credentials::CredentialRef
//! [`Secret`]: crate::credentials::Secret
//! [`authority::resolve`]: crate::credentials::authority::resolve
//! [`Principal`]: crate::credentials::Principal
//! [`Scope`]: crate::credentials::Scope
//! [`CredentialError`]: crate::credentials::CredentialError
//! [`authority`]: crate::credentials::authority
// #3451: the single shared test-only `EnvVarGuard`, consolidated from three
// prior copies (this module's `resolver::tests`, `memory_core::dream::tests`,
// and `memory_core::semantic_consolidation::tests`).
pub
pub use ;
pub use ;
pub use CredentialError;
pub use FileKeyStore;
pub use ;
pub use KeyringStore;
pub use MemoryKeyStore;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Secret;
use PathBuf;
/// Errors raised by a [`KeyStore`] backend.
///
/// Why: callers (the future `config` clap module, the resolver's store tier)
/// need to distinguish "no home directory" from a genuine I/O or parse
/// failure so they can log or degrade appropriately rather than panicking.
/// What: one variant per failure class the file-backed and keyring-backed
/// stores can hit. `MemoryKeyStore` never constructs any of these — its
/// operations are infallible.
/// Test: `file_store_tests::*`, `keyring_store_tests::*` (probe-failure path
/// only).
/// Storage backend for provider API keys.
///
/// Why: the resolver's store tier (and the future `config` clap `set` /
/// `list` / `unset` verbs) must work identically against an in-memory test
/// double, a `0600` TOML file, or the OS keychain — one trait, three
/// interchangeable implementations, selected at runtime by
/// [`resolver::default_store`].
/// What: `get` returns `None` on any failure (absent key, unreadable store,
/// locked keychain) — callers cannot distinguish "not set" from "backend
/// error" by design, since the resolver only ever needs a fallthrough
/// signal. `set`/`unset` surface [`KeyStoreError`] because a failed *write*
/// is actionable. `list` returns provider **names only** — a `KeyStore`
/// implementation must never return a value from `list`.
/// Test: `memory_store_tests::*`, `file_store_tests::*`.