pub struct OAuthState {Show 18 fields
pub http: Client,
pub client_cache: Arc<dyn ClientMetadataCache>,
pub par_store: Arc<dyn ParStore>,
pub scope_policy: Arc<dyn ScopePolicy>,
pub consent_store: Arc<dyn ConsentStore>,
pub decision_store: Arc<dyn DecisionStore>,
pub browser_sessions: Arc<BrowserSessions>,
pub shutdown: Stopping,
pub grant_gate: Arc<dyn PolicyGate>,
pub evaluation_log: Arc<EvaluationLog>,
pub code_store: Arc<dyn AuthorizationCodeStore>,
pub tokens: Arc<OAuthTokenStore>,
pub dpop: Arc<dyn DpopVerifier>,
pub client_assertions: Arc<ClientAssertionVerifier>,
pub permission_sets: Arc<PermissionSets>,
pub authorize_rate_limiter: Arc<RateLimiter>,
pub par_rate_limiter: Arc<RateLimiter>,
pub token_rate_limiter: Arc<RateLimiter>,
}Expand description
Every collaborator the OAuth authorization server routes need, bundled so
crate::routes::AuthState carries one field instead of a dozen.
OAuthState::default is what every router this crate builds gets
unless a deployment wires its own: in-memory stores, plus the two things
that judge a sign-in — OAuthState::grant_gate and
OAuthState::scope_policy — with no denial loaded. A policy denies and
an empty policy set permits everything (plan/policy.md), so the default
grants every requested scope inside authorize::GrantAnyScope’s
ceiling; consent’s identity check is what stands between a client and
a token once the record says allow. Both are read at
POST /oauth/par, and the gate once more before POST /oauth/token
issues anything. DPoP verification is the one hook this crate
does own end to end (RFC 9449 is not a deployment policy choice the way
a scope ceiling is), so OAuthState::default wires the real
dpop::DpopVerifier rather than dpop_seam::RefusingDpopVerifier —
see DPOP_SKEW (this module, private) for the window it is built with.
Fields§
§http: ClientFetches client metadata documents on a deployment that reaches its
own machine (client_metadata::LoopbackClients::Fetched). Every other
deployment fetches each one through a client pinned to the addresses
it checked; see oauth::client_metadata::resolve_client. Nothing else
in this crate shares it; crate::relay and crate::operator_poll
each build their own. OAuthState::default builds it with
client_metadata_http_client’s bounds, but a deployment may wire
its own, so resolve_client applies the per-request bounds it needs
regardless of what arrives here.
client_cache: Arc<dyn ClientMetadataCache>Where fetched client metadata documents are cached; see
oauth::client_metadata.
par_store: Arc<dyn ParStore>Where pushed authorization requests live between par and
authorize; see oauth::par.
scope_policy: Arc<dyn ScopePolicy>The deployment’s scope ceiling, intersected with what a client asks
for at PAR; see oauth::authorize.
consent_store: Arc<dyn ConsentStore>Where pending consent decisions live; see oauth::consent.
decision_store: Arc<dyn DecisionStore>Where the decision records PAR mints live; see oauth::decision.
browser_sessions: Arc<BrowserSessions>The browsers signed in as an account, and the tickets that sign one
in; see oauth::browser.
shutdown: StoppingThe stop this process serves until, so
bot.did.listPendingAuthorizations’s long poll comes back at once
rather than holding a connection open for the rest of its window.
A poll that begins after the stop does not wait at all.
Only the long poll waits on anything here; every other route answers
and returns. The default never stops; didbot-pds passes the stop
its listener closes on.
grant_gate: Arc<dyn PolicyGate>plan/policy.md’s gate, asked about a Subject::Grant at PAR and a
Subject::Token at POST /oauth/token. A deployment wires the same
gate its writes are judged by. Denies only, and
OAuthState::default wires the gate with nothing loaded. A client
this deployment will not admit is denied here, by a denyClient
policy, rather than by a check of its own.
evaluation_log: Arc<EvaluationLog>Where a narrowed or denied grant is written down, payload-free; see
didbot_pds::evaluation_log.
code_store: Arc<dyn AuthorizationCodeStore>Where issued authorization codes live between consent confirmation
and exchange; see oauth::token.
tokens: Arc<OAuthTokenStore>OAuth access/refresh token issuance and rotation; see
oauth::token.
dpop: Arc<dyn DpopVerifier>The DPoP verification seam; see oauth::dpop_seam.
client_assertions: Arc<ClientAssertionVerifier>Where a confidential client’s assertion is checked at par and
token, and its jti held; see oauth::client_auth.
permission_sets: Arc<PermissionSets>Where the permission set an include: scope names is resolved at
par, and cached for every account; see oauth::permission_set.
Rate limits GET /oauth/authorize; see crate::rate_limit.
par_rate_limiter: Arc<RateLimiter>Rate limits POST /oauth/par per caller address, the same way
OAuthState::authorize_rate_limiter bounds the step after it.
PAR is unauthenticated and does more work than authorize does: it
fetches a document from a host the caller names (see
client_metadata_http_client), then mints a decision record
addressed to an account the caller names. Both are costs an anonymous
client can spend without proving anything, which is the same argument
crate::routes::AuthState::provision_rate_limiter makes for the other
unauthenticated route that does real work.
token_rate_limiter: Arc<RateLimiter>Rate limits POST /oauth/token per caller address.
Also unauthenticated until the credential in the body checks out, and every call costs a DPoP proof verification, an ECDSA check made before that credential is read. Without this a caller with a fresh key can spend those checks with proofs naming no token at all.
Trait Implementations§
Source§impl Clone for OAuthState
impl Clone for OAuthState
Source§fn clone(&self) -> OAuthState
fn clone(&self) -> OAuthState
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for OAuthState
impl !RefUnwindSafe for OAuthState
impl Send for OAuthState
impl Sync for OAuthState
impl Unpin for OAuthState
impl UnsafeUnpin for OAuthState
impl !UnwindSafe for OAuthState
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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