Skip to main content

OAuthSection

Struct OAuthSection 

Source
pub struct OAuthSection {
    pub scope_ceiling: Option<Vec<String>>,
    pub pending_per_account: Option<usize>,
    pub pending_total: Option<usize>,
    pub dns_resolver: Option<String>,
    pub browser_session_ttl_secs: Option<u64>,
}
Expand description

The authorization server’s own bounds: the scope ceiling every grant is narrowed to, how many decisions may sit undecided at once, and the resolver it finds a permission set’s authority through.

scope_ceiling is the one place this file names scopes, and it may only narrow. Whatever it holds is intersected with the compiled-in ceiling (didbot_serve::oauth::authorize::GrantAnyScope) before it is applied, so a configured value can shrink what an agent may hold and can never reach past what the binary already allows — the hard-blocked capabilities stay outside it whatever this section says. See the crate root’s doc for why that direction is the only one permitted.

Reload: needs a restart. The ceiling is built once and handed to the router’s OAuthState.

Fields§

§scope_ceiling: Option<Vec<String>>

The most any agent may be granted, as an enumeration of scope atoms — plan/scope-policy.md’s “a ceiling is an enumeration, not a pattern”. Absent leaves the compiled-in ceiling in place.

A seam, and the first half of that plan’s “from server configuration first, from the operator’s records second”: a ceiling read from policy records in the operator’s repository replaces this one at the same ScopePolicy interface, without either side changing. It is here so the boundary is testable before that source exists, not because a ceiling belongs in a configuration file.

§pending_per_account: Option<usize>

How many decisions one account may have awaiting an answer before a further pushed authorization request is refused. Mirrors didbot_serve::oauth::decision::DEFAULT_PENDING_PER_ACCOUNT, 8.

Reasonable range: 1 to 64. At 1, a second sign-in started before the first is answered displaces it. Above 64, one account can hold many sign-ins nobody will answer, and a caller with no credential can push them.

§pending_total: Option<usize>

How many decisions this server may hold in total, counting an answered one until its pushed request expires.

Left unset, the default is derived rather than fixed: didbot-pds computes [capacity] max_accounts * pending_per_account, floored at didbot_serve::oauth::decision::DEFAULT_PENDING_TOTAL, so a deployment sized above 64 accounts is not left with a total bound tighter than pending_per_account gives each one; with no max_accounts configured either, that same fixed default applies outright. A value written here is never adjusted against max_accounts – only checked, with a startup warning if it comes up short.

Reasonable range: max_accounts * pending_per_account to twice that. Below it, a full deployment refuses a push before every account has used its own bound. An answered decision is held until its pushed request expires, so some room above it keeps a busy deployment from refusing. Each one held is memory that POST /oauth/par, which needs no credential, can fill.

§dns_resolver: Option<String>

The DNS-over-HTTPS resolver an include: scope’s permission set is found through: it is asked for the _lexicon TXT record under the set’s authority. com.atproto.identity.resolveHandle asks it for the _atproto TXT record of a handle no account here holds. Default https://cloudflare-dns.com/dns-query.

Reasonable range: an https:// DNS-over-HTTPS (RFC 8484) endpoint that also answers the JSON form, ?name=&type=TXT answered as application/dns-json: Cloudflare’s, Google’s at https://dns.google/resolve, or one on this deployment’s own network. Anything else refuses startup. The default is Cloudflare’s because it answers that form and is the resolver the operator’s own onboarding checks ask. Whoever runs the resolver sees which permission sets sign-ins here name, and which handles callers ask this server to resolve.

§browser_session_ttl_secs: Option<u64>

How long a browser stays signed in as an account, in seconds, counted from the sign-in. Use does not extend it. Default 43_200, twelve hours, as an operator’s session.

Reasonable range: 300 to 86_400 — five minutes to a day. Below five minutes an agent signs its browser in again for most web sign-ins. Above a day a copied cookie outlives any session an agent has. Nothing enforces the range.

Trait Implementations§

Source§

impl Clone for OAuthSection

Source§

fn clone(&self) -> OAuthSection

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 Debug for OAuthSection

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for OAuthSection

Source§

fn default() -> OAuthSection

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

impl<'de> Deserialize<'de> for OAuthSection

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for OAuthSection

Source§

fn eq(&self, other: &OAuthSection) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for OAuthSection

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for OAuthSection

Source§

impl StructuralPartialEq for OAuthSection

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
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.

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> 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.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,