pub struct OauthRuntime {
pub codec: Codec,
pub client: ClientConfig,
pub client_id: String,
pub client_key: Option<SigningKey>,
pub auth_method: AuthMethod,
pub locks: RefreshLocks,
pub plc_directory: String,
pub resolver: TokioResolver,
}Expand description
Everything the Rust OAuth client needs that outlives a request.
Fields§
§codec: CodecAt-rest encryption for sessions and the signing key.
client: ClientConfigThe validated client identity.
client_id: Stringclient_id, precomputed — it is derived, and recomputing it per request
invites a divergence between what we send and what we publish.
client_key: Option<SigningKey>The ES256 client key. None for the dev client, which is a public
client and publishes no JWKS — and for a confidential client whose
backend is not selected and which has no key file yet, since creating one
it will never use is key material at rest for nothing.
auth_method: AuthMethodHow this client authenticates to the authorization server.
locks: RefreshLocksPer-subject refresh serialization. One map process-wide, or the locking does nothing.
plc_directory: StringThe PLC directory for did:plc resolution.
resolver: TokioResolverThe system DNS resolver, for handle → DID.
Implementations§
Source§impl OauthRuntime
impl OauthRuntime
Sourcepub fn new(cfg: &Config) -> Result<Self>
pub fn new(cfg: &Config) -> Result<Self>
Build the runtime from configuration.
Dev is inferred from the public URL, exactly as the sidecar infers it, so the two agree on which client identity they present. A localhost public URL means atproto’s localhost development client: a public client with no JWKS.
The signing key is loaded (or created) only for a confidential client that is actually going to use it — i.e. when the Rust backend is the selected one. Two reasons, and the second is the one that bit:
- a dev client is public, so a key there is never used and never published, and later reads as “the key exists, so it must be in play”;
- the runtime is built on EVERY start so configuration errors surface
early, including when the sidecar is serving. Creating the key as part
of that validation meant a sidecar deployment wrote an ES256 private
key it would never use — key material at rest, for nothing. In tests it
also meant any
AppStatebuilt with a production-likepublic_urldropped a private key into the working directory.
Source§impl OauthRuntime
impl OauthRuntime
Sourcepub fn without_creating_key(cfg: &Config) -> Result<Self>
pub fn without_creating_key(cfg: &Config) -> Result<Self>
OauthRuntime::new, refusing instead of CREATING a missing signing
key. For the operator’s --revoke-all-sessions.
new creates the key when a confidential client has none — right for
the app’s first boot, wrong here. Run from the wrong directory (the
default FEATHERREADER_OAUTH_KEY_PATH is relative) or with the wrong
environment, it minted a fresh key under the same kid while the live
app kept publishing the old JWKS. Every client assertion was then
rejected, every row deleted anyway, and the teardown proceeded over
live tokens. Revocation can only work with the key the PDSes know, so a
missing one is an error.
App startup is unchanged: it still calls new.
Auto Trait Implementations§
impl !RefUnwindSafe for OauthRuntime
impl !UnwindSafe for OauthRuntime
impl Freeze for OauthRuntime
impl Send for OauthRuntime
impl Sync for OauthRuntime
impl Unpin for OauthRuntime
impl UnsafeUnpin for OauthRuntime
Blanket Implementations§
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
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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