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 <token>"
// 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)
}