Documentation
¶
Overview ¶
Package verify verifies AuthKit tokens without a database: access tokens and delegated access tokens of the issuers a Verifier trusts, checked against their keys (a JWKS, static keys or a live key source). It also holds the claims, actor and context helpers and the net/http middleware, which authenticate through a *Verifier or an *authkit.Client (which adds API keys and remote applications from its database).
Index ¶
- Variables
- func ActorFromClaims(c Claims) (iam.Actor, bool)
- func ActorFromContext(ctx context.Context) (iam.Actor, bool)
- func AuthenticateRequest(ctx context.Context, a Authenticator, r *http.Request) (auth.Principal, error)
- func IdentityFromContext(ctx context.Context) (auth.Identity, bool)
- func Optional(a Authenticator) func(http.Handler) http.Handler
- func PrincipalFromClaims(a Authenticator, cl Claims) (auth.Principal, error)
- func RequirePermission(a Authority, perm iam.Perm) func(http.Handler) http.Handler
- func RequirePermissionOn(a Authority, ref iam.GroupRef, perm iam.Perm) func(http.Handler) http.Handler
- func RequireSession(a Authority) func(http.Handler) http.Handler
- func Required(a Authenticator) func(http.Handler) http.Handler
- func Sensitive(a Authority) func(http.Handler) http.Handler
- func SetClaims(ctx context.Context, cl Claims) context.Context
- func WithGroup(ctx context.Context, ref iam.GroupRef) context.Context
- type Authenticator
- type Authority
- type Claims
- type IssuerKeyStatus
- type IssuerOptions
- type PermissionChecker
- type PermissionScope
- type ServiceJWTVerifyOption
- type SessionChecker
- type Verifier
- func (v *Verifier) AddIssuer(issuerID string, audiences []string, opts IssuerOptions) error
- func (v *Verifier) AuthenticateRequest(ctx context.Context, r *http.Request) (auth.Principal, error)
- func (v *Verifier) CheckIssuerKeys(context.Context) error
- func (v *Verifier) IssuerKeyStatuses() []IssuerKeyStatus
- func (v *Verifier) RemoveIssuer(issuerID string)
- func (v *Verifier) Verify(ctx context.Context, token string) (Claims, error)
- func (v *Verifier) VerifyClaims(ctx context.Context, token string) (map[string]any, error)
- func (v *Verifier) VerifyDelegatedAccess(ctx context.Context, token string) (Claims, error)
- func (v *Verifier) VerifyDelegatedAccessRequest(r *http.Request) (Claims, error)
- func (v *Verifier) VerifyRequest(r *http.Request) (Claims, error)
- func (v *Verifier) VerifyServiceJWT(ctx context.Context, token string, opts ...ServiceJWTVerifyOption) (iam.ServiceJWTClaims, error)
- type VerifierOption
Constants ¶
This section is empty.
Variables ¶
var ( // ErrSenderProofRequired refuses a bound token presented without its // proof: no TLS peer or another leaf, no or an invalid DPoP proof, or a // token verified detached from its request. ErrSenderProofRequired iam.Error = errmodel.E(errmodel.CodeSenderProofRequired) // is refused, not proven invalid. ErrSenderProofUnavailable = errors.New("sender proof replay protection unavailable") // ErrInvalidConfirmation refuses a cnf claim that is not exactly one // x5t#S256 or jkt thumbprint. ErrInvalidConfirmation iam.Error = errmodel.E(errmodel.CodeInvalidConfirmation) // ErrConfirmationWrongTokenType refuses cnf on a token type AuthKit does // not bind: an unenforced binding would be a silent downgrade. ErrConfirmationWrongTokenType iam.Error = errmodel.E(errmodel.CodeConfirmationWrongTokenType) )
Sender-proof errors: RFC 8705 certificate-bound and RFC 9449 DPoP-bound delegated tokens.
Functions ¶
func ActorFromClaims ¶ added in v0.147.0
ActorFromClaims derives the actor verified claims act as. It is pure and never yields the system. ok is false for claims that carry no AuthKit authority: another issuer's user, a 2FA-enrollment-only token, or an unrecognized shape. A user or AuthKit-minted delegated actor is bound to the session or device key its token was minted from (iam.Actor.InSession), so every permission check refuses it once that sign-in is revoked.
func ActorFromContext ¶ added in v0.147.0
ActorFromContext is the actor the claims the middleware stored in ctx act as (ActorFromClaims), resolved once when they were stored.
func AuthenticateRequest ¶ added in v0.147.0
func AuthenticateRequest(ctx context.Context, a Authenticator, r *http.Request) (auth.Principal, error)
AuthenticateRequest verifies r through a and returns its helpers/auth principal, for code written against helpers/auth providers. When a is a PermissionChecker (*authkit.Client), the principal's Can checks the credential's permissions live, the session included; otherwise it is identity only.
func IdentityFromContext ¶ added in v0.147.0
IdentityFromContext is the verified caller's provider-neutral identity.
func Optional ¶
func Optional(a Authenticator) func(http.Handler) http.Handler
Optional is Required when the request carries an Authorization header and passes it through anonymously otherwise. A present but invalid credential is refused.
func PrincipalFromClaims ¶ added in v0.147.0
func PrincipalFromClaims(a Authenticator, cl Claims) (auth.Principal, error)
PrincipalFromClaims hands claims a trusted middleware verified for this same request to helpers/auth code without verifying again, which would spend a single-use sender proof twice. Never pass claims from anywhere else. See AuthenticateRequest for Can.
func RequirePermission ¶ added in v0.65.0
RequirePermission authenticates the request (it includes Required) and requires perm, checked live, in the group attached to the request (WithGroup, or an adapter's SetGroup). The check includes the token's session: once it is revoked the request is 401 session_revoked. A request with no group fails closed: 500 internal_error, logged with its route. It panics at construction on a perm a does not register.
func RequirePermissionOn ¶ added in v0.147.0
func RequirePermissionOn(a Authority, ref iam.GroupRef, perm iam.Perm) func(http.Handler) http.Handler
RequirePermissionOn is RequirePermission in one fixed group, such as iam.RootGroup().
func RequireSession ¶ added in v0.147.0
RequireSession is Required plus the session check: the session or device key the token was minted from is still active (not logged out, revoked, banned or deleted), or the request is 401 session_revoked. A user's token passes, and so does a delegated token AuthKit minted from a sign-in, while that sign-in stands; any other credential is 403 forbidden.
func Required ¶
func Required(a Authenticator) func(http.Handler) http.Handler
Required authenticates every request through a, storing its claims and actor in the request context, and answers 401 otherwise. It is stateless: a token outlives its revoked session until it expires. The live gates (RequireSession, RequirePermission, Sensitive) include it.
Stacked gates over the same a verify a request once: the first stores the claims and the later ones reuse them, so a DPoP proof is spent and an API key looked up once. Claims another authenticator verified, or verified for another credential, or stored by SetClaims are verified again.
func Sensitive ¶ added in v0.54.0
Sensitive is RequireSession plus a recent sign-in of the user's own token: within the last 15 minutes, with the second factor when the account has one. A stale sign-in answers 403 step_up_required with the account's step-up methods, which auth-ui handles; a delegated token, which carries no sign-in of its own, is 403 forbidden. Stack it after RequirePermission when a route needs both.
Types ¶
type Authenticator ¶ added in v0.147.0
Authenticator authenticates requests: a *Verifier, or an *authkit.Client, which also accepts its API keys and its remote applications' tokens.
type Authority ¶ added in v0.147.0
type Authority interface {
Authenticator
PermissionChecker
SessionChecker
}
Authority authenticates requests and checks sessions and permissions live: what the live gates need. *authkit.Client is one.
type Claims ¶
type Claims struct {
// Kind is the credential class: iam.ActorUser or iam.ActorDelegated for a
// token, and from *authkit.Client also iam.ActorAPIKey and
// iam.ActorRemoteApplication.
Kind iam.ActorKind
// JOSEType is the token's typ header ("access+jwt",
// "delegated-access+jwt", "remote-application-access+jwt"); empty for an
// API key.
JOSEType string
// Issuer is the validated iss.
Issuer string
// UserID is a local user: set only for an issuer registered IsLocal.
UserID string
// Subject is another issuer's user. It is meaningful only with Issuer and
// never names a local user.
Subject string
// DelegatedSubject is a delegated token's delegated_sub, whose authority
// is Permissions: the user who minted a token of this deployment, else an
// external actor. It never sets UserID.
DelegatedSubject string
// SessionID (sid) or DeviceKeyID names the sign-in a native token, or a
// delegated token AuthKit minted from one, was minted from; the session
// check refuses the token once it is revoked.
SessionID string
DeviceKeyID string
// APIKeyID is the key an API-key credential resolved to.
APIKeyID string
// RemoteApplicationID is the stored application behind a remote
// application token or its delegation, resolved from the validated iss.
RemoteApplicationID string
// Group binds a machine credential's authority to the group it was
// granted in: set for API keys, remote applications and their
// delegations; nil otherwise.
Group *PermissionScope
// Permissions are the credential's permission strings: an API key's or
// application's stored grants, or a delegated token's grant (bounded by
// the application's stored ceiling when an application issued it). Native
// user tokens carry none; their authority is read live (Can).
Permissions []string
// Attributes is the attributes claim, each value raw JSON for the
// consuming service to decode; AuthKit assigns no key a meaning.
Attributes map[string]json.RawMessage
// Entitlements is the issuer's token-time entitlements snapshot.
Entitlements []string
// RootRole is the user's root-group role at mint ("root:admin"), for
// display only: UI and content visibility without a database call. It is
// stale up to the token lifetime and never authorizes anything; every
// permission check reads the role live.
RootRole string
Email string
EmailVerified bool
Username string
// AMR, ACR and AuthTime describe the sign-in the token carries.
AMR []string
ACR string
AuthTime time.Time
// TwoFAEnrollment marks a token that reaches only AuthKit's 2FA
// enrollment routes; every verifier refuses it elsewhere.
TwoFAEnrollment bool
// MFAEnrolled is whether the user had a usable second factor at mint.
MFAEnrolled bool
JTI string
// CertificateThumbprint (cnf x5t#S256) or JWKThumbprint (cnf jkt) is a
// delegated token's sender binding, already matched against this
// request's TLS peer certificate or DPoP proof; empty for a bearer token.
CertificateThumbprint string
JWKThumbprint string
}
Claims is a verified credential: what the middleware stores in the request context. Kind says which fields apply.
func ClaimsFromContext ¶
ClaimsFromContext is the claims the middleware stored in ctx.
func (Claims) HasAMR ¶ added in v0.52.0
HasAMR reports whether the sign-in used authentication method m.
func (Claims) HasEntitlement ¶
HasEntitlement reports whether the claims carry entitlement ent.
func (Claims) HasPermission ¶
HasPermission reports whether the claims carry a permission covering perm.
type IssuerKeyStatus ¶ added in v0.143.0
IssuerKeyStatus is one JWKS issuer's key-refresh state: key count, freshness, the age of the last successful fetch against MaxStale, and the last error.
type IssuerOptions ¶
type IssuerOptions struct {
// JWKSURI is fetched on first use and refreshed in the background when
// its keys expire or an unknown kid arrives. Expired keys keep verifying
// while refreshes fail, up to MaxStale.
JWKSURI string
// Keys are static PEM public keys, each with its kid. Replace them by
// calling AddIssuer again.
Keys []iam.RemoteApplicationKey
// KeySource is read live on every verification: a co-located, rotating
// key source such as AuthKit's own.
KeySource keys.Source
// CacheTTL is how long fetched JWKS keys are fresh (default 10m).
CacheTTL time.Duration
// MaxStale bounds how long after the last successful fetch JWKS keys
// keep verifying while refreshes fail, so a peer's key revocation cannot
// be suppressed by blocking the fetch. Past it the issuer's tokens fail
// with 503 issuer_keys_unavailable. Default 4h; never below CacheTTL.
MaxStale time.Duration
// IsLocal marks the issuer whose users are this host's own: only its
// access tokens set Claims.UserID (others set Subject).
IsLocal bool
}
IssuerOptions is where an issuer's keys come from: exactly one of JWKSURI, Keys and KeySource.
type PermissionChecker ¶ added in v0.65.0
type PermissionChecker interface {
Can(ctx context.Context, a iam.Actor, ref iam.GroupRef, perm iam.Perm) (bool, error)
// KnownPermission reports whether perm is registered.
KnownPermission(perm iam.Perm) bool
}
PermissionChecker checks an actor's authority in a group live; *authkit.Client is one. Can is false for an unknown group or an actor bound to another group, iam.ErrSessionRevoked once the actor's session is revoked, and iam.ErrUnknownPermission for an unregistered perm.
type PermissionScope ¶ added in v0.65.0
PermissionScope is a credential's group binding: the group, the issuer whose group it is, and the group's persona.
type ServiceJWTVerifyOption ¶
type ServiceJWTVerifyOption func(*serviceJWTConfig)
ServiceJWTVerifyOption configures VerifyServiceJWT.
func WithServiceJWTMaxLifetime ¶
func WithServiceJWTMaxLifetime(d time.Duration) ServiceJWTVerifyOption
WithServiceJWTMaxLifetime caps the accepted lifetime (default 15m).
type SessionChecker ¶ added in v0.147.0
type SessionChecker interface {
// CheckSession: the session or device key the token was minted from is
// still active. A user's token carries one, and so does a delegated
// token AuthKit minted from it.
CheckSession(ctx context.Context, cl Claims) error
// CheckRecentSignIn: CheckSession, and the user's own token, signed in
// recently enough for a sensitive action, with the second factor when
// the account has one.
CheckRecentSignIn(ctx context.Context, cl Claims) error
}
SessionChecker checks the sign-in behind verified claims live; *authkit.Client is one. Both return nil or the error to answer: iam.ErrSessionRevoked, forbidden for a credential that carries no sign-in, or (CheckRecentSignIn) step_up_required carrying the step-up methods.
type Verifier ¶
type Verifier struct {
// contains filtered or unexported fields
}
Verifier verifies tokens from the issuers added with AddIssuer.
func NewVerifier ¶
func NewVerifier(opts ...VerifierOption) *Verifier
NewVerifier returns a Verifier that trusts no issuer until AddIssuer.
func (*Verifier) AddIssuer ¶
func (v *Verifier) AddIssuer(issuerID string, audiences []string, opts IssuerOptions) error
AddIssuer trusts issuerID's tokens for any of audiences, replacing an earlier registration of it. A failure leaves the earlier one in place.
func (*Verifier) AuthenticateRequest ¶ added in v0.126.0
func (v *Verifier) AuthenticateRequest(ctx context.Context, r *http.Request) (auth.Principal, error)
AuthenticateRequest verifies r and returns its helpers/auth principal, identity only: a Verifier checks no permissions.
func (*Verifier) CheckIssuerKeys ¶ added in v0.143.0
CheckIssuerKeys is a no-I/O health probe: it fails naming every JWKS issuer whose last key fetch failed, with the age of its keys and whether they are past MaxStale (its tokens then fail closed). Other issuers are unaffected.
func (*Verifier) IssuerKeyStatuses ¶ added in v0.143.0
func (v *Verifier) IssuerKeyStatuses() []IssuerKeyStatus
IssuerKeyStatuses reports every JWKS issuer's key state, sorted by issuer.
func (*Verifier) RemoveIssuer ¶
RemoveIssuer stops trusting issuerID's tokens and drops its cached keys.
func (*Verifier) Verify ¶
Verify verifies an access token or a delegated access token detached from any request, so a sender-bound delegated token fails with ErrSenderProofRequired (use VerifyRequest). ctx bounds the key fetches.
func (*Verifier) VerifyClaims ¶
VerifyClaims verifies a token's signature, issuer, audience and times and returns its raw claims, for host-defined token profiles: it enforces no AuthKit token type, subject, permission or sender binding. Use Verify or VerifyRequest for AuthKit tokens.
func (*Verifier) VerifyDelegatedAccess ¶
VerifyDelegatedAccess is Verify accepting only a delegated access token.
func (*Verifier) VerifyDelegatedAccessRequest ¶ added in v0.98.0
VerifyDelegatedAccessRequest is VerifyRequest accepting only a delegated access token.
func (*Verifier) VerifyRequest ¶ added in v0.65.0
VerifyRequest verifies the request's bearer (or DPoP) token, its sender proof included. It is stateless: a token outlives its revoked session until it expires; RequireSession, RequirePermission and Sensitive check the session live (through *authkit.Client).
func (*Verifier) VerifyServiceJWT ¶
func (v *Verifier) VerifyServiceJWT(ctx context.Context, token string, opts ...ServiceJWTVerifyOption) (iam.ServiceJWTClaims, error)
VerifyServiceJWT verifies a service JWT (token_use=service) of a trusted issuer and returns its claims. It grants nothing: the host intersects the requested permissions with its own grants for the issuer and subject.
type VerifierOption ¶
type VerifierOption func(*verifierConfig)
VerifierOption configures a Verifier.
func WithDPoP ¶ added in v0.101.0
func WithDPoP(replay func(ctx context.Context, key string, ttl time.Duration) (bool, error)) VerifierOption
WithDPoP accepts RFC 9449 DPoP-bound delegated tokens, with WithPublicURL. replay is the proof replay store: it atomically claims key until ttl and returns true only for the first claim; every replica must share it, and its errors fail closed. Client.NewVerifier wires AuthKit's own.
func WithHTTPClient ¶
func WithHTTPClient(client *http.Client) VerifierOption
WithHTTPClient sets the client JWKS are fetched with (default: a timeout-bounded client).
func WithPublicURL ¶ added in v0.149.0
func WithPublicURL(url string) VerifierOption
WithPublicURL is where clients reach the paths this verifier sees: "https://api.example.com", or "https://example.com/api" when a proxy in front strips /api. A DPoP proof must name it plus the request's path, the rule HTTPConfig.PublicURL sets for AuthKit's own routes. No Host or Forwarded header is consulted.
func WithSkew ¶
func WithSkew(d time.Duration) VerifierOption
WithSkew sets the clock skew allowed on exp, nbf and iat (default 60s).