This document defines the repository's authoritative public API design for all
DefaultCredentialProvider types.
Implementations that do not match this document should be treated as legacy debt. New code, reviews, and refactors must follow this document.
- Make provider participation explicit.
- Remove boolean toggles from the public API.
- Remove
configure_*patch-style APIs from the public API. - Keep the top-level
DefaultCredentialProviderAPI uniform across services. - Keep builder APIs predictable across services while allowing service-specific provider slots.
Every service-level default provider exposes the same product-level API:
DefaultCredentialProvider::new()
DefaultCredentialProvider::builder()
DefaultCredentialProvider::with_chain(chain)
DefaultCredentialProvider::push_front(provider)
impl Default for DefaultCredentialProvidernew()creates the documented default chain for that service.default()is identical tonew().builder()returns a builder pre-populated with the documented default slots.with_chain(chain)bypasses all default-chain assembly logic.push_front(provider)prepends a high-priority provider in front of the documented default chain.
Every DefaultCredentialProviderBuilder exposes:
DefaultCredentialProviderBuilder::new()
DefaultCredentialProviderBuilder::default()
.build()For each supported provider slot, the builder exposes exactly two primary methods:
.env(provider)
.no_env()The same pattern applies to all other slots:
.profile(provider)
.no_profile()
.sso(provider)
.no_sso()
.imds(provider)
.no_imds()- Public builder APIs must not expose
configure_*. - Public builder APIs must not expose
disable_*(bool). - Each slot is controlled by one positive method and one removal method.
- Slot names must match the actual provider concept, not an overloaded alias.
- Builders expose only the slots that a service actually supports.
A service may expose a narrowly scoped convenience method when one logical input applies to multiple provider slots. Such a method must:
- Update only slots that are currently present; it must not re-enable a slot
removed with
no_slot(). - Preserve every unrelated setting on each provider.
- Respect builder call order so that later slot-level replacement or removal still wins.
For AWS V4, with_profile(profile) applies the explicit profile to the
profile, sso, and process slots. On wasm32, it applies only to the
available profile slot.
Each builder slot should be represented as:
Option<T>with this meaning:
Some(T::default()): slot enabled with the default provider configurationSome(custom): slot enabled with a custom provider configurationNone: slot removed from the chain
This implies:
DefaultCredentialProviderBuilder::default()initializes all documented default slots toSome(T::default())..no_env()setsenvtoNone..env(provider)setsenvtoSome(provider).build()pushes onlySome(...)slots and skipsNone.
No separate enabled flag is needed.
Use provider-concept names without the CredentialProvider suffix.
Examples:
envprofilessoprocessecsimdsweb_identityoidcconfig_filevm_metadata
Do not collapse distinct concepts under a vague shared name.
Examples:
- Prefer
web_identity(...)overassume_role(...)when the slot is actuallyAssumeRoleWithWebIdentityCredentialProvider. - Prefer
oidc(...)overassume_role(...)when the slot is specifically OIDC-based.
let provider = DefaultCredentialProvider::builder()
.no_env()
.profile(ProfileCredentialProvider::new().with_profile("prod"))
.no_imds()
.build();Expected slots:
envprofilessoweb_identityprocessecsimds
let provider = DefaultCredentialProvider::builder()
.env(EnvCredentialProvider::new())
.no_oidc()
.build();Expected slots:
envoidc
let provider = DefaultCredentialProvider::builder()
.no_env()
.web_identity(AssumeRoleWithWebIdentityCredentialProvider::new())
.build();Expected slots:
envweb_identity
When changing an existing service:
- Remove all public
configure_*methods. - Remove all public
disable_*(bool)methods. - Initialize builder defaults with
Some(T::default())for documented default slots. - Add
slot(provider)andno_slot()methods for every supported slot. - Update tests to verify that
no_slot()truly removes the provider from the chain. - Update examples and docs to use slot/no-slot APIs only.
- This document does not require a repository-wide refactor in one patch.
- This document does not require every service to expose the same set of provider slots.
- This document does not remove
with_chainorpush_front; those remain the escape hatch for advanced composition.