pub struct OidcFederationStrategy<P, S = NoStore> { /* private fields */ }Expand description
An AuthStrategy that federates a third-party OIDC JWT (Clerk, Supabase,
Auth0, …) into a CipherStash CTS service token via POST /api/authorise.
Each call to get_token returns a cached CTS
token until it expires. Because /api/authorise issues no CTS refresh
token, renewal means re-federating: the strategy calls the
OidcProvider again for a current third-party JWT and exchanges it for a
fresh CTS token. Supply an OidcProvider that returns the live provider
token each time (e.g. wrapping clerk.session.getToken()).
The strategy is bound to a workspace CRN at construction. The region is
derived from the CRN — there is no separate region argument — so a
caller can’t accidentally point the strategy at one region while the
CRN says another, matching
AccessKeyStrategy.
Every returned token is checked against the CRN’s workspace — the
same post-auth verification AccessKeyStrategy performs — so a token CTS
minted for a different workspace (or one loaded from a poisoned shared
cache) is never handed back. Verification can fail in two ways:
AuthError::WorkspaceMismatch— the JWT decoded cleanly but itsworkspaceclaim doesn’t match the CRN’s workspace ID.AuthError::InvalidToken— the JWT is malformed or missing theworkspaceclaim entirely, so verification can’t run.
When constructed via OidcFederationStrategyBuilder::with_token_store, the strategy
also persists tokens through an external TokenStore so short-lived
instances (e.g. one per Edge Function request) can share a cache and skip
re-federating on every cold start. The workspace check runs on cached and
store-loaded tokens too, not just freshly federated ones.
§Example
use stack_auth::{AuthError, OidcProviderFn, OidcFederationStrategy, SecretToken};
use cts_common::Crn;
let crn: Crn = "crn:ap-southeast-2.aws:ZVATKW3VHMFG27DY".parse().unwrap();
let provider = OidcProviderFn::new(|| async {
// Real consumers call into a provider SDK / FFI to fetch a live JWT.
Ok::<_, AuthError>(SecretToken::new("header.payload.signature".to_string()))
});
let strategy = OidcFederationStrategy::new(crn, provider).unwrap();Implementations§
Source§impl<P: OidcProvider> OidcFederationStrategy<P>
impl<P: OidcProvider> OidcFederationStrategy<P>
Sourcepub fn new(workspace_crn: Crn, oidc_provider: P) -> Result<Self, AuthError>
pub fn new(workspace_crn: Crn, oidc_provider: P) -> Result<Self, AuthError>
Create a new OidcFederationStrategy for the given workspace CRN and
OIDC provider.
The auth endpoint is resolved automatically via service discovery using the region encoded in the CRN; the workspace ID is used to verify every federated token belongs to the right workspace.
A CRN with a service_name component (e.g.
crn:ap-southeast-2.aws:ZVATKW3VHMFG27DY:zerokms) is accepted; the
service_name is ignored. Only the region and workspace ID are
load-bearing for this strategy.
Sourcepub fn builder(
workspace_crn: Crn,
oidc_provider: P,
) -> OidcFederationStrategyBuilder<P>
pub fn builder( workspace_crn: Crn, oidc_provider: P, ) -> OidcFederationStrategyBuilder<P>
Return a builder for configuring an OidcFederationStrategy before construction.
Trait Implementations§
Source§impl<P: OidcProvider, S: TokenStore> AuthStrategy for &OidcFederationStrategy<P, S>
impl<P: OidcProvider, S: TokenStore> AuthStrategy for &OidcFederationStrategy<P, S>
Auto Trait Implementations§
impl<P, S = NoStore> !Freeze for OidcFederationStrategy<P, S>
impl<P, S = NoStore> !RefUnwindSafe for OidcFederationStrategy<P, S>
impl<P, S = NoStore> !UnwindSafe for OidcFederationStrategy<P, S>
impl<P, S> Send for OidcFederationStrategy<P, S>
impl<P, S> Sync for OidcFederationStrategy<P, S>
impl<P, S> Unpin for OidcFederationStrategy<P, S>
impl<P, S> UnsafeUnpin for OidcFederationStrategy<P, S>where
S: UnsafeUnpin,
P: UnsafeUnpin,
Blanket Implementations§
impl<T> AuthStrategyBounds for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more