Skip to content

List your tool's credentials

Implement CredentialBearing on your config

You do not implement CredentialProvider. Implement CredentialBearing from rtb-credentials on the type that holds the credential references — normally your config struct — and a blanket impl in rtb-app turns it into a provider:

use rtb_credentials::{CredentialBearing, CredentialRef};

#[derive(Default)]
struct MyConfig {
    anthropic: CredentialRef,
    github: CredentialRef,
}

impl CredentialBearing for MyConfig {
    fn credentials(&self) -> Vec<(&'static str, &CredentialRef)> {
        vec![("anthropic", &self.anthropic), ("github", &self.github)]
    }
}

CredentialRef is re-exported from rtb_app::prelude, so you do not need rtb-credentials as a direct dependency just for this.

The names are &'static str and become the identifiers users type — credentials test anthropic. Pick them once and treat them as public API.

Wire it into the App

In production, hand the provider to the builder:

Application::builder().credentials_from(Arc::new(my_config))

In a test, assign the field directly — it is public:

let mut app = TestAppBuilder::new(TestWitness::new()).tool("t", "1.0.0").build();
app.credentials_provider = Some(Arc::new(MyConfig::default()));

Read the listing

for (name, cred) in app.credentials() {
    println!("{name}");
}

App::credentials() returns owned (String, CredentialRef) pairs, in whatever order your CredentialBearing implementation returned them.

Understand what an empty listing means

App::credentials() returns an empty Vec when no provider is wired. It does not error, and there is no way to tell "no provider" apart from "a provider that lists nothing" — NoCredentials produces the same result.

That is the right behaviour for credentials list on a tool that has not declared any credentials yet. It does mean you cannot read an empty listing as "this tool has no credentials configured" — only as "nothing was declared".

Do not also implement CredentialProvider

Because of the blanket impl, writing your own impl CredentialProvider for MyConfig alongside impl CredentialBearing for MyConfig is a coherence conflict and will not compile. Implement CredentialProvider directly only for a type that is not CredentialBearing — for instance a wrapper that assembles a listing from several sources.

What this does not do

Listing is not resolving. Nothing here reads a keychain, reads an environment variable, validates a token or redacts a secret — that is rtb-credentials' job. rtb-app stores the provider and enumerates what it reports.