Credential listing¶
rtb_app::credentials is how a tool tells the framework which credentials it knows
about, so credentials list and friends have something to show.
What this module does not do¶
It enumerates credentials. It does not resolve them, read them from a keychain,
validate them, or redact them. Resolution lives in rtb-credentials; this module
stores a listing so App::credentials() has an answer.
CredentialProvider¶
The object App stores, as Option<Arc<dyn CredentialProvider>>. It returns
owned pairs, which is the whole reason it exists as a separate trait from
rtb_credentials::CredentialBearing.
You implement CredentialBearing, not this¶
There is a blanket implementation:
So the thing to write on your config struct is CredentialBearing:
use rtb_credentials::{CredentialBearing, CredentialRef};
impl CredentialBearing for MyConfig {
fn credentials(&self) -> Vec<(&'static str, &CredentialRef)> {
vec![("anthropic", &self.anthropic), ("github", &self.github)]
}
}
Arc::new(my_config) then coerces to Arc<dyn CredentialProvider> with no further
work.
The consequence of a blanket impl is worth stating plainly: you cannot write your
own impl CredentialProvider for a type that already implements
CredentialBearing. The two would overlap and the compiler rejects it. Implement
CredentialProvider directly only for types that are not CredentialBearing.
Why there are two traits at all¶
CredentialBearing::credentials returns Vec<(&'static str, &CredentialRef)> —
borrows tied to the provider's lifetime. That is the right shape to implement on a
config struct, and the wrong shape to store behind a dyn on App, because there is
no lifetime for those borrows to anchor to. CredentialProvider is the owned dual,
and the blanket impl does the conversion so nobody writes it twice.
NoCredentials¶
A provider that lists nothing. Useful when a type is required but there is nothing to
report. Note that it is not what App::for_testing installs — that leaves
credentials_provider as None. The two are indistinguishable from the outside,
since both produce an empty listing.
list_or_empty¶
pub fn list_or_empty(provider: Option<&Arc<dyn CredentialProvider>>)
-> Vec<(String, CredentialRef)>;
The helper behind App::credentials(): the provider's listing when Some, an empty
Vec when None. Exposed so tests can exercise the same path without an App.
What an empty listing means¶
An empty result is not an error and is not distinguishable from "no provider wired".
A tool that has not implemented CredentialBearing yet reports the empty set, and
credentials list shows nothing rather than failing — which is the right behaviour
for a tool that has not declared any credentials, but does mean an empty listing
cannot be read as "this tool has no credentials configured".