Skip to main content

CredentialBroker

Trait CredentialBroker 

Source
pub trait CredentialBroker: Send + Sync {
Show 19 methods // Required methods fn access_token<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait; fn proxy<'life0, 'async_trait>( &'life0 self, request: ProxyRequest, ) -> Pin<Box<dyn Future<Output = Result<ProxyResponse, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait; fn proxy_stream<'life0, 'async_trait>( &'life0 self, request: ProxyRequest, ) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<Bytes, BrokerError>> + Send>>, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait; fn anthropic_usage<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait; fn capabilities<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<ProviderStatus>, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait; // Provided methods fn account_selector(&self, provider: OAuthProviderId) -> AccountSelector { ... } fn access_token_for<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait { ... } fn recover_rejected_token<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, _rejected: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait { ... } fn access_token_pinned<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait { ... } fn access_token_pinned_for<'life0, 'life1, 'async_trait>( &'life0 self, provider: OAuthProviderId, model: Option<&'life1 str>, ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait { ... } fn access_token_pinned_excluding<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, provider: OAuthProviderId, model: Option<&'life1 str>, exclude: &'life2 [CredentialRef], ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait { ... } fn accounts<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<Vec<AccountSummary>, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait { ... } fn usage<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<UsageSnapshot, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait { ... } fn report_cooldown<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, until_ms: Option<u64>, reason: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait { ... } fn active_cooldown(&self, cred: &CredentialRef) -> Option<u64> { ... } fn clear_cooldown(&self, cred: &CredentialRef, sent_at_ms: u64) { ... } fn access_token_for_auto<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait { ... } fn cloud_catalog<'life0, 'life1, 'async_trait>( &'life0 self, provider: CloudProviderId, context_ref: &'life1 str, allow_stale: bool, ) -> Pin<Box<dyn Future<Output = Result<Vec<CloudCatalogEntry>, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait { ... } fn cloud_invoke<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, provider: CloudProviderId, context_ref: &'life1 str, model_id: &'life2 str, request: InvokeRequest, ) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<CloudEvent, BrokerError>> + Send>>, BrokerError>> + Send + 'async_trait>> where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait { ... }
}
Expand description

The typed credential broker protocol. One implementation runs in-process (LocalBroker) so normal local use needs no daemon; the other talks to a remote synaps auth-broker over authenticated HTTP(S) (RemoteBroker).

Required Methods§

Source

fn access_token<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Vend a fresh OAuth access token (token + expiry ONLY) for the policy-selected account of provider.

Source

fn proxy<'life0, 'async_trait>( &'life0 self, request: ProxyRequest, ) -> Pin<Box<dyn Future<Output = Result<ProxyResponse, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Execute a non-streaming provider request with the broker-owned key.

Source

fn proxy_stream<'life0, 'async_trait>( &'life0 self, request: ProxyRequest, ) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<Bytes, BrokerError>> + Send>>, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Execute a streaming (SSE) provider request with the broker-owned key. Returns the byte stream only when the upstream response is successful; error statuses are read (bounded) and surfaced as BrokerError.

Source

fn anthropic_usage<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Value, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Typed operation: fetch the Anthropic account-usage summary.

The destination URL is pinned broker-side and the OAuth access token is resolved and attached behind the boundary — callers receive usage JSON only and never see a token or auth.json. This is deliberately NOT a generic OAuth proxy: one operation, one fixed endpoint.

Source

fn capabilities<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<ProviderStatus>, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Non-secret provider capability/status list.

Provided Methods§

Source

fn account_selector(&self, provider: OAuthProviderId) -> AccountSelector

Effective account selector for provider (env > config > injected policy). No I/O beyond reading configuration; no secrets.

Source

fn access_token_for<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Vend a token for an explicitly addressed credential. The default implementation serves only the default slot (via access_token); a named slot is an error — NEVER a fallback to another account.

Source

fn recover_rejected_token<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, _rejected: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Re-vend the exact credential whose access token was rejected. Local brokers force refresh only if storage still holds that rejected token. Remote/custom brokers keep their ordinary explicit-slot semantics.

Source

fn access_token_pinned<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Policy-resolved pair: the credential the broker selected for provider and its token. Default implementation: the default slot.

Source

fn access_token_pinned_for<'life0, 'life1, 'async_trait>( &'life0 self, provider: OAuthProviderId, model: Option<&'life1 str>, ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Model-aware variant of access_token_pinned: under an auto selector only accounts with proven capacity for model are eligible. Default implementation ignores the model.

Source

fn access_token_pinned_excluding<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, provider: OAuthProviderId, model: Option<&'life1 str>, exclude: &'life2 [CredentialRef], ) -> Pin<Box<dyn Future<Output = Result<PinnedToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

access_token_pinned_for that never answers with an account in exclude (the accounts one logical request already used). Default implementation: the ordinary selection, with an excluded answer refused as “no account available”; a broker that can pass the exclusion into its own selection overrides this.

Source

fn accounts<'life0, 'async_trait>( &'life0 self, provider: OAuthProviderId, ) -> Pin<Box<dyn Future<Output = Result<Vec<AccountSummary>, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, Self: 'async_trait,

Non-secret account listing for provider. Default: unsupported.

Source

fn usage<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<UsageSnapshot, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Typed, read-only usage snapshot for one credential. The token is resolved and used behind the boundary; callers receive normalized, secret-free data only. Default: unsupported.

Source

fn report_cooldown<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, until_ms: Option<u64>, reason: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<(), BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Report that cred hit a provider limit so automatic selection stops advertising it until until_ms (epoch ms; None = a short default). Best effort; default implementation is a no-op.

Source

fn active_cooldown(&self, cred: &CredentialRef) -> Option<u64>

When cred’s active cooldown ends (epoch ms), if this broker knows of one. No network request and no token refresh. Default: none.

Source

fn clear_cooldown(&self, cred: &CredentialRef, sent_at_ms: u64)

A request sent on cred at sent_at_ms (epoch ms) was accepted: drop its cooldown if that was reported no later than the request left (the same millisecond counts: the caller saw the limit first), so a limit that has passed does not keep moving turns off the account. A cooldown reported later than sent_at_ms stays (that request proves nothing about it). Memory only. Default: no-op.

Source

fn access_token_for_auto<'life0, 'life1, 'async_trait>( &'life0 self, cred: &'life1 CredentialRef, ) -> Pin<Box<dyn Future<Output = Result<AccessToken, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Re-vend cred for automatic selection (a turn keeping the account it is on). Unlike access_token_for, which serves an account the user chose, this honours and records a refused refresh’s hold, the same as the automatic choice’s own vend. Default: access_token_for.

Source

fn cloud_catalog<'life0, 'life1, 'async_trait>( &'life0 self, provider: CloudProviderId, context_ref: &'life1 str, allow_stale: bool, ) -> Pin<Box<dyn Future<Output = Result<Vec<CloudCatalogEntry>, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Typed cloud catalog. Credentials and provider authority remain broker-owned.

Source

fn cloud_invoke<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, provider: CloudProviderId, context_ref: &'life1 str, model_id: &'life2 str, request: InvokeRequest, ) -> Pin<Box<dyn Future<Output = Result<Pin<Box<dyn Stream<Item = Result<CloudEvent, BrokerError>> + Send>>, BrokerError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Typed cloud invocation. The canonical model and normalized request are the only caller-controlled inputs; hosts, auth and signing remain broker-owned.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§