diff --git a/authn/bearer.go b/authn/bearer.go index d73a947f30cb406fa2c9ecff15adfd94587996f1..cd61aabe6cef116ac440fe4f37b9a526dc81d26f 100644 --- a/authn/bearer.go +++ b/authn/bearer.go @@ -172,8 +172,13 @@ // and the holder is who they say they are, so retrying is pointless and what // they need is a wider grant, not another login. Both are asked before the // bearer table, because ErrMissingGrant is raised beside a token that // verified and must not be read as one that did not. -// - ErrNoToken is 401: nothing was presented on a surface that requires a -// credential. +// - Whatever else IsAuthFailure calls permanent is 401 — today that is +// ErrNoToken, nothing having been presented on a surface that requires a +// credential. The predicate is asked rather than the sentinel listed a second +// time, so that a sentinel added to one of them cannot be missing from the +// other: this package's two answers to "is the credential the problem?" have +// to agree, and the cheapest way to guarantee that is for one to be built +// from the other. // - ErrNoAgentPlane, and anything else at all, is 503. An instance with no // [tokens.sr.ht] origin cannot check any credential, and telling the holder // of a good token that it is bad would send them to re-provision it; an @@ -190,7 +195,7 @@ case errors.Is(err, ErrMissingGrant), errors.Is(err, ErrNotInstanceOwner): return http.StatusForbidden case isBearerRefusal(err): return bearer.StatusFor(err) - case errors.Is(err, ErrNoToken): + case IsAuthFailure(err): return http.StatusUnauthorized default: return http.StatusServiceUnavailable