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
//! `SecretProvider` trait — the seam between dodot's secret machinery
//! and the per-provider subprocess work.
//!
//! Concrete providers (pass, op, sops, etc.) implement this trait.
//! The `secret()` MiniJinja function dispatches by scheme; the
//! preflight error UX (secrets.lex §5.4) calls [`SecretProvider::probe`]
//! before anything else; resolution is [`SecretProvider::resolve`].
//!
//! See `docs/proposals/secrets.lex` §5.1 for the design rationale and
//! `docs/proposals/secrets-testing.lex` §2 for the testing-seam role.
use crateSecretString;
use crateResult;
/// Outcome of [`SecretProvider::probe`] — describes whether the
/// provider can be used right now, and if not, why not. Each variant
/// maps to a specific user-facing error message in `secrets.lex` §5.4.
///
/// `Ok` is the "go ahead and call `resolve`" signal; everything else
/// is a fail-fast opportunity that lets us produce an actionable
/// error before subprocess machinery would have produced an opaque
/// one.
/// A provider knows how to turn a reference like
/// `op://Personal/GitHub/token` into a [`SecretString`].
///
/// Implementations should:
///
/// - Be cheap to construct (no IO in the constructor; defer to
/// [`SecretProvider::probe`]).
/// - Make `probe` cheap and side-effect-free where possible. It runs
/// on every dodot invocation that touches a templated file with
/// `secret()` calls, so it can't be slow.
/// - Resolve via the provider's *non-interactive* path. Any provider
/// that can only be unlocked interactively (e.g. requires a
/// biometric prompt at resolve time) MUST surface that as
/// `ProbeResult::NotAuthenticated` first, so the user sees the
/// actionable hint rather than a hung subprocess.
/// - Never log the resolved value. The `tracing` macros expose the
/// message through the global subscriber, which may go to stdout,
/// stderr, journald, or a CI log — none of which are appropriate
/// destinations for a secret. `SecretString`'s `Debug` impl already
/// redacts on accidental capture; provider code should not unwrap
/// the bytes for logging at all.