package authn import ( "net/http" "strings" ) // bearerScheme is the Authorization scheme agents present the token under. // Matched case-insensitively, as RFC 7235 requires. const bearerScheme = "bearer" // HeaderAgent and HeaderAgentSession carry the mandatory provenance an agent // must send alongside its token. They are named after the git trailers they end // up in, so that what an agent sends and what a reviewer reads in `git log` are // spelled the same way. // // There is deliberately no X-Agent-Base header: the base revision is the // `If-Match` value the write plane already defines, and giving it a second // spelling is exactly how REST and MCP end up disagreeing about what it means. const ( HeaderAgent = "X-Agent" HeaderAgentSession = "X-Agent-Session" ) // BearerFromRequest returns the token from an "Authorization: Bearer " // header, or "" when the header is absent or uses another scheme. Anything // after the scheme is returned verbatim apart from surrounding whitespace: the // token is opaque to this function, and validating its grammar is // BearerValidator's job and not the header parser's. func BearerFromRequest(r *http.Request) string { h := r.Header.Get("Authorization") if h == "" { return "" } scheme, rest, ok := strings.Cut(h, " ") if !ok || !strings.EqualFold(scheme, bearerScheme) { return "" } return strings.TrimSpace(rest) }