authn

package
v2.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package authn provides inbound HTTP authentication for the ADK REST API.

It defines a small Authenticator seam that different providers implement and a Middleware that gates authenticated endpoints and answers 401 when a request carries no valid credentials

A server wires an Authenticator through adkrest.ServerConfig. Endpoints are authenticated by default and only those explicitly marked public (for example /health and /version) are reachable without credentials.

Index

Constants

View Source
const (
	// UserEMailHeader is header name which contains user email (see https://docs.cloud.google.com/iap/docs/identity-howto).
	// Example value: accounts.google.com:example@gmail.com
	UserEMailHeader = "X-Goog-Authenticated-User-Email"

	// UserIDHeader is header name which contains user id (see https://docs.cloud.google.com/iap/docs/identity-howto).
	// Example value: accounts.google.com:userIDvalue
	UserIDHeader = "X-Goog-Authenticated-User-Id"
)

Variables

View Source
var ErrForbidden = errors.New("authn: forbidden")

ErrForbidden reports that a request carried valid credentials but the authenticated principal is not permitted. An Authenticator returns it, or an error wrapping it, to make Middleware answer 403 Forbidden. It is distinct from ErrUnauthenticated: the caller proved who it is, and that identity is the thing being refused, so folding it into a 401 would tell the caller to present a different credential when the credential was never the problem.

View Source
var ErrUnauthenticated = errors.New("authn: unauthenticated")

ErrUnauthenticated reports that a request carried no valid credentials. An Authenticator returns it, or an error wrapping it, to make Middleware answer 401 Unauthorized. Any error that is neither this nor ErrForbidden is treated as an internal provider failure and answered 500.

Functions

func Middleware

func Middleware(a Authenticator) func(http.Handler) http.Handler

Middleware returns HTTP middleware that authenticates every request before passing it to the next handler, and answers 401 (403 when the principal is authenticated but not permitted, or 500 on an internal provider failure) when authentication fails. On success it stores the resolved identity on the request context, where downstream handlers read it with CallerFromContext.

A nil a yields pass-through middleware, so a caller can wire Middleware unconditionally.

func WithCaller

func WithCaller(ctx context.Context, id *Caller) context.Context

WithCaller returns a copy of ctx carrying id. A nil id is ignored and ctx is returned unchanged.

Types

type Authenticator

type Authenticator interface {
	// Authenticate verifies the request's credentials and returns the
	// authenticated identity. It returns an error wrapping [ErrUnauthenticated]
	// when the request has no valid credentials for this provider.
	Authenticate(r *http.Request) (*Caller, error)
}

Authenticator authenticates an inbound HTTP request. Implementations back different providers/schemes. Use NewCustom to adapt a plain function.

func NewCustom

func NewCustom(authFunc AuthenticatorFunc) Authenticator

NewCustom returns a custom Authenticator, using the provided function as a part of middleware

func NewGoogleOIDC added in v2.5.0

func NewGoogleOIDC(cfg GoogleOIDCConfig) (Authenticator, error)

NewGoogleOIDC returns an Authenticator requiring a Google-signed OIDC bearer token issued for cfg.Audience, verified with idtoken.Validate.

Both fields are required. An empty GoogleOIDCConfig.Audience is rejected rather than passed through to idtoken.Validate, which skips the audience check when it is given an empty one and would leave an authenticator that takes a token minted for any audience at all (leave the Authenticator unset, or use NewNoop, to run without authentication). An empty GoogleOIDCConfig.AllowedServiceAccounts is rejected too. Because the allow-list is mandatory, an Authenticator this returns can never be configured to accept an unlisted principal, including when it is handed directly to adkrest.ServerConfig.Authenticator rather than reached through a trigger flag.

This mirrors GoogleOidcVerifier(audience, allowed_emails) in adk-python, with deliberate differences. adk-python's allow-list is optional (allowed_emails defaults to None), whereas here it is mandatory. adk-python also tests email_verified for Python truthiness, so every non-empty string passes it, "false" included, whereas here the claim must be an actual boolean. And adk-python names the failed check in its response detail, where Middleware answers with the same body for every rejection carrying a given status.

adk-python already answers 403 for a verified-but-unlisted principal, so the ErrForbidden/403 this returns for that case is not itself a difference, and a missing, malformed or unverifiable credential is a 401 either way.

func NewHeader

func NewHeader(name string) Authenticator

NewHeader returns an Authenticator that reads the UserID from the named request header. It rejects a request whose header is absent or carries more than one value.

func NewIdentityAwareProxy

func NewIdentityAwareProxy() Authenticator

NewIdentityAwareProxy returns an Authenticator to be used behind an Identity Aware-Proxy for Google Cloud (https://cloud.google.com/security/products/iap) - for instance for Cloud Run-based deployment. The proxy puts into the headers values for email and user-id (UserEMailHeader and UserIDHeader accordingly) IMPORTANT: Do not rely on those headers if IAP can be bypassed!

func NewNoop

func NewNoop() Authenticator

NewNoop returns a noop Authenticator (always returns an empty Caller)

type AuthenticatorFunc

type AuthenticatorFunc func(r *http.Request) (*Caller, error)

AuthenticatorFunc is the function which can be used by NewCustom to create a custom Authenticator

type Caller

type Caller struct {
	// UserID is the stable identifier of the caller. Middleware puts it on the
	// request context, where it can be read with [CallerFromContext].
	UserID string
	// Claims carries optional provider-specific attributes (email, roles, token
	// scopes, ...). It may be nil.
	Claims map[string]any
}

Caller is the authenticated principal resolved from a request.

func CallerFromContext

func CallerFromContext(ctx context.Context) (*Caller, bool)

CallerFromContext returns the Caller carried by ctx, reporting false when the request was not authenticated.

type GoogleOIDCConfig added in v2.5.0

type GoogleOIDCConfig struct {
	// Audience is the OIDC audience a token must carry to be accepted. Required.
	//
	// It does not identify the caller, because it is chosen freely by whoever
	// mints the token: any principal that can call
	// iam.serviceAccounts.getOpenIdToken on a service account of its own can
	// obtain a Google-signed token for a given audience.
	Audience string

	// AllowedServiceAccounts is the set of service account emails permitted to
	// call. Required and non-empty: since the audience does not identify the
	// caller, an authenticator with no allow-list would admit any principal
	// holding a Google-signed token for the audience. Each entry is matched
	// against a token's verified email claim, the identity the subscription or
	// trigger actually delivers as.
	AllowedServiceAccounts []string
}

GoogleOIDCConfig configures NewGoogleOIDC.

A struct rather than positional parameters: both fields are required today and the verifier is likely to grow more later (an HTTP client for the certificate fetch, possibly several accepted audiences), and a struct absorbs those as compatible additions where a new positional parameter would be a breaking change. This is the house style for a new constructor; see AGENTS.md.