atproto/oauth/flow

Start an authorization flow: resolve the PDS, discover the authorization server, push the request (PAR) with PKCE + DPoP, return the authorization URL and the pending Flow the caller must hold (server-side by state, or in-process for a CLI) until the callback returns with the code.

Confidential clients pass their client-assertion fields via extra_form; public and loopback clients pass an empty list.

Types

pub type Flow {
  Flow(
    identifier: String,
    pds: String,
    issuer: String,
    token_endpoint: String,
    dpop_key: gose.Key(String),
    pkce_verifier: String,
    client_id: String,
    state: String,
  )
}

Constructors

  • Flow(
      identifier: String,
      pds: String,
      issuer: String,
      token_endpoint: String,
      dpop_key: gose.Key(String),
      pkce_verifier: String,
      client_id: String,
      state: String,
    )
pub type FlowError {
  ResolveFailed(String)
  DiscoverFailed(String)
  ParFailed(String)
  DpopFailed(String)
}

Constructors

  • ResolveFailed(String)
  • DiscoverFailed(String)
  • ParFailed(String)
  • DpopFailed(String)

Values

pub fn start(
  client: xrpc.Client,
  resolver resolver: String,
  identifier identifier: String,
  client_id client_id: String,
  redirect_uri redirect_uri: String,
  scope scope: String,
  extra_form extra_form: List(#(String, String)),
) -> Result(#(String, Flow), FlowError)

Returns the authorization-server URL to send the user to, and the pending flow. The caller must verify the callback’s state against flow.state before exchanging the code.

Search Document