Documentation
¶
Overview ¶
Package requestprincipal is the protocol-neutral view of who made an HTTP request. A resource server (a product API) protects its routes with one middleware that tries several Authenticators in order — a human's BFF cookie or bearer token, an API key, an AI agent's AAuth-signed request — and finds a RequestPrincipal in the request context, whichever protocol authenticated it.
The package has no protocol dependencies. Adapters live with their protocols: relyingparty.NewRequestAuthenticator wraps SystemAuth bearer tokens, API keys and BFF sessions, and the aauthrs subpackage verifies AAuth (agent auth) requests.
Index ¶
- Constants
- Variables
- func Middleware(opts Options, authenticators ...Authenticator) func(http.Handler) http.Handler
- func PrincipalUUID(ctx context.Context) (uuid.UUID, error)
- func WithPrincipal(ctx context.Context, p *RequestPrincipal) context.Context
- type Authenticator
- type AuthenticatorFunc
- type Chain
- type Challenger
- type Error
- type Options
- type Proof
- type RequestPrincipal
- type Type
Constants ¶
const ( // ProtocolSession is a browser (BFF) cookie session. ProtocolSession = "session" // ProtocolOIDC is an OAuth 2.0 / OpenID Connect bearer access token. ProtocolOIDC = "oidc" // ProtocolAPIKey is an API key. ProtocolAPIKey = "apikey" // ProtocolAAuth is an AAuth HTTP message signature with an agent, // person or auth token. ProtocolAAuth = "aauth" )
Protocol values for RequestPrincipal.Protocol.
Variables ¶
var ErrNoCredentials = errors.New("requestprincipal: no credentials")
ErrNoCredentials is returned by an Authenticator when the request carries no credentials of its kind, so the next authenticator may try.
var ErrNoPrincipal = errors.New("requestprincipal: no SystemForge principal")
ErrNoPrincipal is returned by PrincipalUUID when the request carries no principal that is a SystemForge principal.
Functions ¶
func Middleware ¶
Middleware authenticates each request with the authenticators in order (see Chain.Authenticate), puts the RequestPrincipal in the request context, and otherwise writes the protocol's response: the rejecting authenticator's *Error, a 401 with every authenticator's challenge when none recognized the request, or a 500 for an internal error.
func PrincipalUUID ¶
PrincipalUUID returns the SystemForge principal ID of the request's principal. It returns ErrNoPrincipal when the request is unauthenticated or its principal ID is not a SystemForge principal ID, such as an issuer-qualified subject of a credential issued elsewhere.
func WithPrincipal ¶
func WithPrincipal(ctx context.Context, p *RequestPrincipal) context.Context
WithPrincipal returns ctx carrying p.
Types ¶
type Authenticator ¶
type Authenticator interface {
Authenticate(r *http.Request) (*RequestPrincipal, error)
}
Authenticator authenticates requests of one protocol.
Authenticate returns the principal, or:
- an error wrapping ErrNoCredentials when the request carries none of its credentials;
- an *Error when it carries them but they are invalid or insufficient (the response the protocol prescribes: a challenge, 401 or 403);
- any other error for an internal failure (a 500).
type AuthenticatorFunc ¶
type AuthenticatorFunc func(r *http.Request) (*RequestPrincipal, error)
AuthenticatorFunc adapts a function to Authenticator.
func (AuthenticatorFunc) Authenticate ¶
func (f AuthenticatorFunc) Authenticate(r *http.Request) (*RequestPrincipal, error)
Authenticate calls f.
type Chain ¶
type Chain []Authenticator
Chain tries authenticators in order. It is itself an Authenticator.
func (Chain) Authenticate ¶
func (c Chain) Authenticate(r *http.Request) (*RequestPrincipal, error)
Authenticate returns the principal from the first authenticator that recognizes the request's credentials. An authenticator that recognizes them but rejects them ends the chain with its error: credentials of one protocol never fall through to another. When none recognizes the request, the result is a 401 *Error carrying every Challenger's headers, and wraps ErrNoCredentials.
type Challenger ¶
Challenger is implemented by authenticators that advertise themselves on a 401 response to a request that no authenticator recognized: a bearer authenticator adds WWW-Authenticate, an AAuth authenticator adds AAuth-Requirement. Challenge adds its headers to h.
type Error ¶
type Error struct {
// Status is the HTTP status (401 when zero).
Status int
// Header holds response headers, such as a challenge.
Header http.Header
// Code and Message form the default JSON body
// {"code": ..., "message": ...}.
Code string
Message string
// Respond, when set, writes the whole response instead (after Header
// is applied), for protocols with their own error bodies.
Respond func(w http.ResponseWriter)
// Err is the underlying cause, for logs.
Err error
}
Error is an authentication failure with the response its protocol prescribes.
type Options ¶
type Options struct {
// Optional lets requests without credentials through without a
// principal (handlers check FromContext). Invalid credentials are
// still rejected.
Optional bool
// Logger receives internal errors. Default: slog.Default().
Logger *slog.Logger
}
Options configures Middleware.
type Proof ¶
type Proof struct {
// Method names the credential form (e.g. "access_token", "api_key",
// "session", "aa-auth+jwt").
Method string
// Issuer is the party that issued the credential.
Issuer string
// Audience is the audience the credential was verified for.
Audience string
// TokenID is the credential's identifier (a JWT jti or an API key ID).
TokenID string
// KeyThumbprint is the RFC 7638 thumbprint of the key the request was
// signed with, for proof-of-possession credentials.
KeyThumbprint string
// IssuedAt and ExpiresAt bound the credential, when it states them.
IssuedAt time.Time
ExpiresAt time.Time
// Params are further protocol-specific evidence (e.g. the signature's
// covered components), by name.
Params map[string]string
}
Proof is the verified evidence an authenticator accepted.
type RequestPrincipal ¶
type RequestPrincipal struct {
// PrincipalID is the stable identifier the application keys
// authorization and records on: the app-local principal ID for
// SystemAuth credentials, or an issuer-qualified subject for
// credentials issued elsewhere (see the adapter's documentation).
PrincipalID string
// Type is the kind of party that made the request.
Type Type
// Subject is the credential's subject as its issuer states it. It is
// unique within Proof.Issuer only.
Subject string
// Organization is the organization (tenant) the credential is scoped
// to, when it is scoped to one.
Organization string
// Actor identifies the party that made the request when it is not
// the subject: for an agent acting for a person, the agent.
Actor string
// Delegator identifies the party the actor acts for, when there is
// one: for an agent acting for a person, the person.
Delegator string
// Mission identifies the task the credential was issued for, when
// the protocol has one (AAuth: the mission's s256 digest).
Mission string
// Session identifies the authenticated session or grant: a BFF
// session or an issued token's ID.
Session string
// Protocol is how the request authenticated (Protocol*).
Protocol string
// Proof is the verified evidence behind the principal.
Proof Proof
// Scopes are the scopes or grants the credential carries. Empty for
// a session, which carries the principal's full access.
Scopes []string
// Claims are additional verified attributes, by name.
Claims map[string]any
// Native is the adapter's own, protocol-specific result (for example
// *relyingparty.AuthenticatedPrincipal), for callers that need more
// than the neutral view.
Native any
}
RequestPrincipal is the authenticated principal of one request.
func FromContext ¶
func FromContext(ctx context.Context) (*RequestPrincipal, bool)
FromContext returns the request principal in ctx, if any.
func (*RequestPrincipal) HasScope ¶
func (p *RequestPrincipal) HasScope(scope string) bool
HasScope reports whether the principal's credential carries scope.
func (*RequestPrincipal) IsAgent ¶
func (p *RequestPrincipal) IsAgent() bool
IsAgent reports whether the request was made by an AI agent.
type Type ¶
type Type string
Type is the kind of party a request principal is.
const ( // TypeHuman is an interactive person. TypeHuman Type = "human" // TypeAgent is an AI agent, possibly acting for a person. TypeAgent Type = "agent" // TypeService is a backend service or system account. TypeService Type = "service" // TypeApplication is an OAuth client acting as itself. TypeApplication Type = "application" )
Directories
¶
| Path | Synopsis |
|---|---|
|
Package aauthrs authenticates AI agents at a resource server with AAuth (draft-hardt-oauth-aauth-protocol), producing a requestprincipal.RequestPrincipal.
|
Package aauthrs authenticates AI agents at a resource server with AAuth (draft-hardt-oauth-aauth-protocol), producing a requestprincipal.RequestPrincipal. |