Skip to main content

require_agent_token_or_dpop

Function require_agent_token_or_dpop 

Source
pub fn require_agent_token_or_dpop(
    registry: &dyn Registry,
    oauth: &OAuthState,
    headers: &HeaderMap,
    http_method: &str,
    path: &str,
) -> Result<Writer, ApiError>
Expand description

Resolves either an agent’s own Credential::AccountToken or a DPoP-bound OAuth access token minted by crate::oauth::token, for com.atproto.repo.*’s write routes and uploadBlob — the resource path an app authorized over OAuth actually writes through.

http_method and path are this request’s own method and route path (e.g. "/xrpc/com.atproto.repo.createRecord"); a DPoP proof presented here must bind to this request, not merely to some request the caller once made. The absolute htu a proof is checked against is derived from path the same way crate::oauth::discovery::request_htu builds it for /oauth/token — out of this deployment’s own zone service document, never a header — and, deliberately, only when a DPoP-scheme credential is actually presented: an agent-token route with no zone document seeded yet (a bare FakeRegistry, or a deployment mid-bootstrap) must still be reachable with a plain agent token, which needs no htu at all.

A DPoP <token> credential is checked in two steps, both required: the DPoP header’s proof must verify against this request (crate::oauth::dpop_seam::DpopVerifier::verify), and the resulting thumbprint must match the one access_token was minted bound to (crate::oauth::token::OAuthTokenStore::validate_access). A bare stolen token with no proof, or a well-formed proof signed by the wrong key, fails at one of those two steps — see plan/adversarial.md’s DPoP-binding findings, which this function exists to close.