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
//! Credential resolver + secure `KeyStore` (issue #2401, epic #2400 Wave 1).
//!
//! Why: every inference-adapter consumer needs the same answer to "where is
//! the API key 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. Centralising the trait,
//! the three backends, and the precedence chain here means every future
//! `inference-client` consumer (and, eventually, the migrated
//! trusty-agents / trusty-search dotenvy call sites) gets identical
//! behaviour for free.
//!
//! What: [`KeyStore`] is the storage trait ([`memory_store::MemoryKeyStore`],
//! [`file_store::FileKeyStore`], and — behind the `keyring-store` feature —
//! `keyring_store::KeyringStore`). [`resolver::resolve_key`] applies the
//! 3-tier precedence (process env var via [`resolver::env_var_for`] >
//! `.env.local` via [`dotenv`] > [`resolver::default_store`]).
//! [`redact::redact_secret`] is the one credential-masking implementation,
//! also reused by `memory_core::filter`.
//!
//! Test: `cargo test -p trusty-common --features credentials -- inference::credentials::`
//! and (KeyringStore compile/probe-failure-path only, never a real keychain)
//! `cargo test -p trusty-common --features keyring-store -- inference::credentials::`.
pub use ;
pub use FileKeyStore;
pub use KeyringStore;
pub use MemoryKeyStore;
pub use redact_secret;
pub use ;
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::*`.