Skip to content

Resource

A resource verifies whichever token a request presents and challenges for the next one. With PS authorization (three-party), an agent token is answered with requirement=person-token, a person token with a resource token challenge (requirement=auth-token), and an auth token is served:

const self = "https://files.example" // the resource's server identifier
verify := aauth.TokenVerifyOptions{Resolver: aauth.NewJWKSResolver(nil)} // nil: aauth.DiscoveryClient

handler := func(w http.ResponseWriter, r *http.Request) {
    tok, err := aauth.ParseSignatureKey(r)
    if err != nil {
        aauth.WriteSignatureFailure(w, err) // 401 with Signature-Error
        return
    }
    typ, err := aauth.TokenType(tok)
    if err != nil {
        aauth.WriteSignatureFailure(w, err)
        return
    }
    switch typ {
    case aauth.TypAuth:
        claims, err := aauth.VerifyAndExtractAuth(r.Context(), r, self,
            aauth.AuthTokenVerifyOptions{TokenVerifyOptions: verify})
        if err != nil {
            aauth.WriteSignatureFailure(w, err)
            return
        }
        serve(w, claims.Subject, claims.Scope) // directed sub, granted scope
    case aauth.TypPerson:
        person, err := aauth.VerifyAndExtractPerson(r.Context(), r, self, verify)
        if err != nil {
            aauth.WriteSignatureFailure(w, err)
            return
        }
        rt, err := aauth.IssueResourceToken(
            aauth.ResourceTokenParams{Resource: self, Scope: "files:read"},
            person, resourceKey, resourceKID)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        aauth.ChallengeAuthToken(w, rt) // 401 requirement=auth-token
    default:
        aauth.ChallengePersonToken(w) // 401 requirement=person-token
    }
}

The resource also serves /.well-known/aauth-resource.json (aauth.ResourceMetadata) and the JWKS holding resourceKey. A resource that needs only the agent's identity stops at aauth.VerifyAndExtractAgent. For four-party access, set ResourceTokenParams.Audience to the resource's access server. The compile-checked version is Example_resource.