identity

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package identity verifies who a gateway request is from. Cohort assignment must only ever use a Subject produced here: never a header a client could have set itself.

Index

Constants

View Source
const (
	ModeJWT           = "jwt"
	ModeTrustedHeader = "trusted_header"
	ModeNone          = "none" // no verification: every caller is anonymous (default routing)
)

Modes.

Variables

View Source
var AllowedAlgs = []string{"RS256", "ES256", "EdDSA"}

AllowedAlgs is the JWT signature allowlist. "none" and HS* are never accepted: a shared-secret alg would let anyone holding the (public) JWKS key forge tokens (key confusion).

View Source
var ClientCredentialHeaders = []string{"Authorization", "X-Api-Key", "Api-Key", "X-Goog-Api-Key", "Proxy-Authorization"}

ClientCredentialHeaders are the headers a caller can use to present a credential to the gateway. None is ever a gateway-to-provider credential.

View Source
var ErrAmbiguous = errors.New("identity: identity header sent more than once")

ErrAmbiguous is returned when a trusted identity/groups header appears more than once; adapters answer 400 rather than guess which value is real.

View Source
var ErrNoCredentials = errors.New("identity: no credentials")

ErrNoCredentials is returned when the request carries nothing to verify.

Functions

func BearerToken

func BearerToken(h http.Header) string

BearerToken returns the caller's token from "Authorization: Bearer" or, for Anthropic SDKs, "x-api-key".

func SubjectFromClaims

func SubjectFromClaims(claims map[string]any, cfg Options) (policy.Subject, error)

SubjectFromClaims derives the caller from verified token claims using cfg.UserClaim / cfg.GroupsClaim (defaults "email" / "groups"). When the user claim is "email" the token must also carry email_verified=true (bool or "true"): many IdPs let users set an unverified email, which would let them pick someone else's identity. cfg.TrustUnverifiedEmail opts out.

Types

type OIDCJWT

type OIDCJWT struct {
	Issuer, Audience       string
	UserClaim, GroupsClaim string
	// TrustUnverifiedEmail accepts an "email" user claim without
	// email_verified=true. Off by default: see SubjectFromClaims.
	TrustUnverifiedEmail bool
	// contains filtered or unexported fields
}

OIDCJWT verifies a bearer JWT issued by the org's IdP: discovery + JWKS (cached, refetched on unknown kid so key rotation works), then iss / aud / exp / nbf and the alg allowlist.

func NewOIDCJWT

func NewOIDCJWT(issuer, audience, userClaim, groupsClaim string, client *http.Client) (*OIDCJWT, error)

NewOIDCJWT never touches the network; discovery happens on first Verify (and is retried while it fails), so a proxy can start before the IdP is reachable. client may be nil.

func (*OIDCJWT) Verify

func (o *OIDCJWT) Verify(r *http.Request) (policy.Subject, error)

type Options

type Options struct {
	Mode                   string
	Issuer, Audience       string
	UserClaim, GroupsClaim string
	IdentityHeader         string
	GroupsHeader           string
	TrustedProxyCIDRs      []string
	// TrustUnverifiedEmail: accept userClaim "email" without email_verified=true.
	// Default false; only for IdPs that never issue unverified emails.
	TrustUnverifiedEmail bool
}

Options is per-binary identity config. Empty fields fall back to the org's policy (Org.Identity / Org.Gateway.Auth), so most deployments set nothing.

func (Options) Effective

func (o Options) Effective(org *policy.Org) Options

Effective fills gaps from the org and picks the mode: jwt when an issuer is known, otherwise trusted_header (which then demands CIDRs and fails closed).

func (Options) HeaderNames

func (o Options) HeaderNames(org *policy.Org) []string

HeaderNames are the identity/groups headers (effective for org) that must be cleared from every upstream request once the subject is derived.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver caches the Verifier across policy hot-reloads: it is rebuilt only when the effective options change (so the JWKS cache survives reloads).

func (*Resolver) Get

func (r *Resolver) Get(base Options, org *policy.Org) (Verifier, error)

Get returns the verifier for base options + org. A nil Verifier with nil error means ModeNone.

type TrustedHeader

type TrustedHeader struct {
	IdentityHeader string
	GroupsHeader   string
	// contains filtered or unexported fields
}

TrustedHeader reads identity from headers set by an auth gateway. That is only safe when the request provably came from that gateway, so it refuses to exist without a CIDR allowlist for the peer address.

func NewTrustedHeader

func NewTrustedHeader(identityHeader, groupsHeader string, trustedProxyCIDRs []string) (*TrustedHeader, error)

func (*TrustedHeader) Verify

func (t *TrustedHeader) Verify(r *http.Request) (policy.Subject, error)

type Verifier

type Verifier interface {
	Verify(r *http.Request) (policy.Subject, error)
}

Verifier authenticates a request and returns the caller. Any error means the caller is unverified.

func New

func New(o Options) (Verifier, error)

New builds the Verifier for o (already Effective). ModeNone returns nil, nil.

Directories

Path Synopsis
Package identitytest is a tiny OIDC issuer (discovery + JWKS + token minting + an auto-approving authorization-code/PKCE flow) for tests and the compose demo.
Package identitytest is a tiny OIDC issuer (discovery + JWKS + token minting + an auto-approving authorization-code/PKCE flow) for tests and the compose demo.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL