Skip to main content

AuthState

Struct AuthState 

Source
pub struct AuthState {
Show 27 fields pub estop: Arc<Estop>, pub operator: Option<Arc<OperatorAuth>>, pub relay: Option<RelayTarget>, pub operator_login_limiter: Arc<RateLimiter>, pub disclosure: Disclosure, pub oauth: OAuthState, pub provision_rate_limiter: Arc<RateLimiter>, pub unauthenticated_creates: bool, pub max_accounts: u64, pub loopback_callers_only: bool, pub strict_transport_security: Option<StrictTransportSecurity>, pub subscriber_limit: Arc<SubscriberLimit>, pub park_rate_limiter: Arc<RateLimiter>, pub sync_rate_limiter: Arc<RateLimiter>, pub write_meter: Arc<WriteMeter>, pub proxy: Arc<ProxyLimits>, pub never_wrote_min_idle: Duration, pub tree: Arc<TreeState>, pub trust_forwarded_headers: bool, pub lifecycle: Arc<ServerLifecycle>, pub nudge: Arc<PollNudge>, pub operator_records: Arc<OperatorRecords>, pub operator_handle: Arc<OperatorHandle>, pub handles: Arc<dyn HandleDid>, pub handle_lookup_limiter: Arc<RateLimiter>, pub did_lookup_limiter: Arc<RateLimiter>, pub declared_lookups: Arc<DeclaredLookups>,
}
Expand description

Session storage, the e-stop latch and the operator credential, bundled so a caller building app_with_auth hands them over together.

Separate from Registry on purpose: neither a session nor an e-stop engagement is provisioning, and bundling them into the same object-safe trait every backend must implement would grow that trait for every deployment whether or not it uses a local stop. The default is what every other builder here gets: fresh, empty, in-memory state and no operator credential configured, so app keeps behaving exactly as before this existed.

Fields§

§estop: Arc<Estop>

The local emergency stop.

§operator: Option<Arc<OperatorAuth>>

Signing in as this deployment’s operator, when it has one. None when no --operator was given: there is no DID a sign-in could match, so the operator routes answer that they are not configured rather than offering a sign-in that can only fail. See crate::operator::OperatorAuth.

§relay: Option<RelayTarget>

The relay an operator may announce this server to. None when no relay was named, and under a .localhost zone regardless; see crate::relay.

§operator_login_limiter: Arc<RateLimiter>

Bounds GET /dashboard/login per caller address.

That route takes no credential — signing in is how a caller gets one — and answering it costs an identity resolution and a pushed authorization request against a host the caller named. That is the same shape as POST /oauth/par, which is already bounded this way, and rather more outbound work.

§disclosure: Disclosure

Which Credential::Disclosure routes this deployment has closed. Defaults to every route open; see auth::Disclosure.

§oauth: OAuthState

PAR, authorize, token and discovery; see crate::oauth::OAuthState. Defaults to in-memory stores and every policy hook refusing — see that type’s own doc.

§provision_rate_limiter: Arc<RateLimiter>

Bounds bot.did.createAccount and bot.did.createSession calls per caller address, the two together; see this module’s PROVISION_RATE_LIMIT and crate::rate_limit’s own doc for where that address comes from and AuthState::trust_forwarded_headers for when a caller-supplied header may stand in for it.

authorize is keyed this way already; createAccount mints an account — a signing key, a hostname, a blob quota, a permanent ledger and firehose entry — and the claim Credential::Attested checks is verified only after this budget, so it needs the same address-keyed budget at least as much as either. Both routes read a proof, which can fetch an issuer’s keys or a DID document before any signature is checked.

§unauthenticated_creates: bool

Whether bot.did.createAccount with no credential creates beneath the deployment’s own account; see tree::prove.

false unless a deployment turns it on: a public deployment creates only for a creator that proved itself. didbot-pds turns it on under .localhost, where nothing holds a credential yet, and nowhere else.

§max_accounts: u64

How many accounts this deployment may hold before bot.did.createAccount refuses to mint another; see this module’s DEFAULT_MAX_ACCOUNTS and create_account.

Checked against didbot_pds::RegistryStats::accounts — the same count crate::health’s periodic line already reports — rather than a second counter kept here, so a cap and a dashboard can never disagree about what “how many accounts” means.

§loopback_callers_only: bool

Whether this deployment answers only callers on this host.

A .localhost zone is a development run: createAccount mints with no attestation claim there, and without a --data directory every blob is held in memory — so a run reachable from the network hands both to anybody sharing it. The listener binds every address because that is the only single bind answering both 127.0.0.1 and ::1 (see didbot-pds’s own comment), so the restriction is here: a request whose peer address is not a loopback address is refused before it reaches a route.

false unless a deployment turns it on, which is the posture a real zone wants: a deployment nobody can reach serves no agents.

§strict_transport_security: Option<StrictTransportSecurity>

The Strict-Transport-Security header every response carries, if any; see StrictTransportSecurity.

None unless a deployment turns it on. didbot-pds turns it on only when it serves a production ACME certificate.

§subscriber_limit: Arc<SubscriberLimit>

Bounds how many never-ending streams — com.atproto.sync.subscribeRepos — this server holds open at once, in total and per caller address; see crate::subscribers::SubscriberLimit.

crate::MAX_CONCURRENT_REQUESTS does not cover these: its permit is released when the response head is sent, which for a stream is before the stream has carried a single frame.

§park_rate_limiter: Arc<RateLimiter>

Bounds bot.did.parkKey and describeParkedKey per caller address; see tree::PARK_RATE_LIMIT.

§sync_rate_limiter: Arc<RateLimiter>

Bounds the com.atproto.sync.* reads per caller address; see routes::SYNC_READ_LIMIT. Those reads are unauthenticated and each can rebuild and sign a repository.

§write_meter: Arc<WriteMeter>

Bounds each account’s record writes and blob uploads, by operation and by request byte; see crate::write_meter.

§proxy: Arc<ProxyLimits>

Bounds each account’s atproto-proxy calls, and caches where their targets live; see crate::ProxyLimits.

§never_wrote_min_idle: Duration

The shortest idleFor a neverWrote account delete takes; see crate::NEVER_WROTE_MIN_IDLE.

§tree: Arc<TreeState>

Parked keys, spent proofs and issuers’ keys; see crate::tree.

§trust_forwarded_headers: bool

Whether X-Forwarded-For/X-Real-IP may be trusted as the caller’s address for every per-address budget this router keeps — AuthState::provision_rate_limiter, crate::oauth::OAuthState::par_rate_limiter and crate::oauth::OAuthState::authorize_rate_limiter — instead of the TCP peer address crate::rate_limit::caller_key gets by default.

false unless a deployment turns it on — see crate::rate_limit’s own doc for why trusting a caller-supplied header by default would make every per-address budget bypassable rather than merely degraded. Turn this on only once a real reverse proxy sits in front of this server and sets whichever header it reads.

§lifecycle: Arc<ServerLifecycle>

Where this deployment is in its own lifecycle; see didbot_pds::ServerLifecycle and this module’s own require_lifecycle, which is the single point every capability question goes through.

Defaults to ServerLifecycle::claimed — a server that exists and works — because that is what every builder in this crate other than didbot-pds’s own path is: a test, or a .localhost run. A real deployment hands in one built by ServerLifecycle::booting and driven by a store read and an operator poll.

§nudge: Arc<PollNudge>

Where bot.did.pollOperatorClaim delivers its “look now” request; see crate::PollNudge and this module’s own poll_operator_claim.

Defaults to a channel with no poll task attached, which absorbs nudges and does nothing — the correct behaviour for a build with no operator repository to read.

§operator_records: Arc<OperatorRecords>

What the operator poll’s last listing of the operator’s repository read, for the dashboard’s provenance panel. Shared with the poll, which is the only thing that writes to it; see crate::OperatorRecords.

§operator_handle: Arc<OperatorHandle>

The operator’s handle as the operator poll last verified it, for the homepage. Shared with the poll, which is the only thing that writes to it; see crate::OperatorHandle.

§handles: Arc<dyn HandleDid>

Where com.atproto.identity.resolveHandle looks up a handle no account here holds; see crate::handles. Defaults to the network, through Cloudflare’s resolver.

§handle_lookup_limiter: Arc<RateLimiter>

Bounds those lookups per caller address; see routes::HANDLE_LOOKUP_LIMIT.

§did_lookup_limiter: Arc<RateLimiter>

Bounds com.atproto.identity.resolveDid’s lookups of DIDs hosted elsewhere per caller address; see routes::DID_LOOKUP_LIMIT.

§declared_lookups: Arc<DeclaredLookups>

The lookups this deployment’s policies declare, shared with the policy poll, which is the only thing that writes to it; see crate::DeclaredLookups.

Trait Implementations§

Source§

impl Clone for AuthState

Source§

fn clone(&self) -> AuthState

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for AuthState

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,