Crate aliri_tokens[][src]

Expand description

Facilities for efficient background management of access tokens

This library is intended to support some best practices for background management of authentication tokens for clients such that they can make the right trade-offs with regard to reliability of their own application and reliance on the backend authentication system always being available to issue tokens.

In particular, this moves considerations about whether a token needs to be refreshed to the background, provides a grace period where the existing token can continue to be used while attempts are made to obtain a fresher token, and contemplates a mechanism whereby multiple short-lived instances (such as serverless functions) can cooperate in order to reduce the need for an always-up authentication server.

This is done in such a way that consumers of the tokens need be hardly aware that the refreshes are happening in the background at all.

General Flow (Client Credentials)

On application start-up, you will need to set up your source and any intermediate caching layers.

In the example below, we pull some credentials in and set up a token source to perform a token exchange against an OAuth2 token backend. That set up includes some configuration for determining when a token should be considered stale and eligible for renewal.

We next set up a file cache so that we can persist the token locally. This allows us to continue using the same token across application restarts or for multiple instances on the same logical filesystem to share tokens. In the case of serverless functions, you might want to implement a token cache that uses a private cache such as Redis or a private table.

Finally, we construct our final token source from these to elements and spawn a token watcher which will automatically renew the token in the background as it becomes stale. The actual time that it attempts to perform this refresh is controlled by a JitterSource, which helps prevent stampedes of renewal attempts by multiple instances seeing a token go stale at the same time. An error backoff configuration is also provided to introduce a reasonable means of reducing load when the token authority returns an error.

use aliri_clock::DurationSecs;
use aliri_tokens::{backoff, jitter, sources, ClientId, ClientSecret, TokenLifetimeConfig, TokenWatcher};

let credentials = sources::oauth2::dto::ClientCredentialsWithAudience {
    credentials: sources::oauth2::dto::ClientCredentials {
        client_id: opts.client_id,
        client_secret: opts.client_secret,
    }
    .into(),
    audience: opts.audience,
};

let fallback = sources::oauth2::ClientCredentialsTokenSource::new(
    reqwest::Client::new(),
    opts.token_url,
    credentials,
    TokenLifetimeConfig::default(),
);

let file_source = sources::file::FileTokenSource::new(opts.credentials_file);

let token_source =
    sources::cache::CachedTokenSource::new(fallback).with_cache("file", file_source);

let jitter_source = jitter::RandomEarlyJitter::new(DurationSecs(60));

let watcher = TokenWatcher::spawn_from_token_source(
    token_source,
    jitter_source,
    backoff::ErrorBackoffConfig::default(),
)
.await?;

tracing::info!(
    token = format_args!("{:#?}", watcher.token().access_token()),
    "first access token"
);

This crate includes an example of doing a periodic refresh using a file cace in the examples folder. Refer to that example for more details on usage.

Features

The following features are supported by this crate, all of which are enabled by default:

  • oauth2: Provides implementations of token refresh sources corresponding to the client credentials and refresh token flows.
  • file: Provides implementations of a token refresh source and cache using the local filesystem.
  • rand: Provides for an implementation of JitterSource based on the random number generator provided by the rand crate.

Modules

backoff

Error backoff handling

jitter

Utilities for adding a bit of jitter to reduce stampeding

sources

Token sources

Structs

AccessToken

An access token

AccessTokenRef

A reference to a borrowed AccessToken

BorrowedToken

An outstanding borrow of a token

ClientId

A client ID

ClientIdRef

A reference to a borrowed ClientId

ClientSecret

A client secret

ClientSecretRef

A reference to a borrowed ClientSecret

IdToken

An OAuth2 ID token

IdTokenRef

A reference to a borrowed IdToken

RefreshToken

A refresh token

RefreshTokenRef

A reference to a borrowed RefreshToken

TokenLifetimeConfig

Configuration for determining how long a token should be considered fresh

TokenPublisherQuit

An error generated when the token publisher ceases to publish new tokens

TokenWatcher

A token watcher that can be uses to obtain up-to-date tokens

TokenWithLifetime

A token as returned by the authority with some additional lifetime information

Enums

TokenStatus

A token’s lifecycle status