Documentation
¶
Index ¶
- Constants
- Variables
- func MatchesExplicitFrameCredential(ctx context.Context, scheme, token string) bool
- func NewExtension(opts ...ConfigOption) forge.Extension
- func NewExtensionWithConfig(config Config) forge.Extension
- func ParseExplicitFrameCredential(presentation string) (scheme, token string, err error)
- func WithContext(ctx context.Context, authCtx *AuthContext) context.Context
- func WithExplicitFrameCredential(ctx context.Context, scheme, token string) (context.Context, error)
- type AuthContext
- func FromContext(ctx context.Context) (*AuthContext, bool)
- func GetAuthContext(ctx forge.Context) (*AuthContext, bool)
- func GetAuthContextFromStdContext(ctx context.Context) (*AuthContext, bool)
- func MustFromContext(ctx context.Context) *AuthContext
- func MustGetAuthContext(ctx forge.Context) *AuthContext
- func (a *AuthContext) GetClaim(key string) (any, bool)
- func (a *AuthContext) GetClaimString(key string) (string, bool)
- func (a *AuthContext) HasAllPermissions(permissions ...string) bool
- func (a *AuthContext) HasAnyRole(roles ...string) bool
- func (a *AuthContext) HasPermission(permission string) bool
- func (a *AuthContext) HasRole(role string) bool
- func (a *AuthContext) HasScope(scope string) bool
- func (a *AuthContext) HasScopes(scopes ...string) bool
- type AuthProvider
- type Authorizer
- type Config
- type ConfigOption
- type Extension
- type OAuthFlow
- type OAuthFlows
- type ProviderConfig
- type ProviderFunc
- type Registry
- type Requirement
- type SecurityScheme
- type SecuritySchemeType
Constants ¶
const ( // RegistryKey is the DI key for the auth registry. RegistryKey = "auth:registry" // RegistryKeyLegacy is the legacy DI key for the auth registry. RegistryKeyLegacy = "auth.Registry" )
DI container keys for auth extension services.
Variables ¶
var ( // ErrProviderNotFound is returned when a provider is not found. ErrProviderNotFound = errors.New("auth provider not found") // ErrProviderExists is returned when a provider already exists. ErrProviderExists = errors.New("auth provider already exists") // ErrInvalidConfiguration is returned when configuration is invalid. ErrInvalidConfiguration = errors.New("invalid auth configuration") // ErrMissingCredentials is returned when credentials are missing. ErrMissingCredentials = errors.New("missing authentication credentials") // ErrInvalidCredentials is returned when credentials are invalid. ErrInvalidCredentials = errors.New("invalid credentials") // ErrInsufficientScopes is returned when required scopes are missing. ErrInsufficientScopes = errors.New("insufficient scopes") // ErrAuthenticationFailed is returned when authentication fails. ErrAuthenticationFailed = errors.New("authentication failed") // ErrAuthorizationFailed is returned when authorization fails. ErrAuthorizationFailed = errors.New("authorization failed") // ErrTokenExpired is returned when a token has expired. ErrTokenExpired = errors.New("token expired") // ErrTokenInvalid is returned when a token is invalid. ErrTokenInvalid = errors.New("invalid token") )
Functions ¶
func MatchesExplicitFrameCredential ¶ added in v1.12.5
MatchesExplicitFrameCredential reports whether trusted transport code marked this exact scheme and token as an explicit frame presentation. Only check credentials extracted from a valid Authorization presentation. A match does not authenticate the token or promote credentials read from cookie fallback.
func NewExtension ¶
func NewExtension(opts ...ConfigOption) forge.Extension
NewExtension creates a new auth extension with functional options.
Example:
auth.NewExtension(
auth.WithEnabled(true),
auth.WithDefaultProvider("jwt"),
)
func NewExtensionWithConfig ¶
NewExtensionWithConfig creates a new auth extension with a complete config. This is for backward compatibility or when config is fully known at initialization.
func ParseExplicitFrameCredential ¶ added in v1.12.5
ParseExplicitFrameCredential parses a protocol frame's selected credential. You can supply a bare token, Bearer <token>, or DPoP <token>. The returned scheme is canonical, and token bytes are preserved after splitting fields. Proofs must use the transport's existing proof channel.
func WithContext ¶
func WithContext(ctx context.Context, authCtx *AuthContext) context.Context
WithContext adds the AuthContext to a context.
func WithExplicitFrameCredential ¶ added in v1.12.5
func WithExplicitFrameCredential(ctx context.Context, scheme, token string) (context.Context, error)
WithExplicitFrameCredential records a credential received in a protocol frame after request middleware. Call it only from trusted transport code, using the same parsed scheme and token you put in the Authorization header. Never create this marker from request headers, cookies, or claims.
The marker stores a digest, preserves the parent context, and grants no identity. Providers must still validate the credential and any required proof.
Types ¶
type AuthContext ¶
type AuthContext struct {
// Subject is the authenticated entity (user ID, service ID, etc.)
Subject string
// Claims holds additional authentication claims (roles, permissions, etc.)
Claims map[string]any
// Scopes holds OAuth2 scopes or permission strings
Scopes []string
// Roles holds the authenticated subject's roles (e.g. "admin", "editor").
// Route requirements treat roles as any-of.
Roles []string
// Permissions holds fine-grained permission strings
// (e.g. "users:write"). Route requirements treat permissions as all-of.
Permissions []string
// Metadata holds provider-specific metadata
Metadata map[string]any
// Data holds additional data from the authenticated provider
Data any
// ProviderName identifies which auth provider authenticated this request
ProviderName string
}
AuthContext holds authenticated user/service information. This is stored in the request context after successful authentication.
func FromContext ¶
func FromContext(ctx context.Context) (*AuthContext, bool)
FromContext retrieves the AuthContext from the request context. Returns the auth context and true if found, nil and false otherwise.
func GetAuthContext ¶
func GetAuthContext(ctx forge.Context) (*AuthContext, bool)
GetAuthContext retrieves the AuthContext from forge.Context. Returns the auth context and true if found, nil and false otherwise.
func GetAuthContextFromStdContext ¶
func GetAuthContextFromStdContext(ctx context.Context) (*AuthContext, bool)
GetAuthContextFromStdContext retrieves AuthContext from standard context.Context. This is for backward compatibility with code that uses standard context. For new code using forge.Context, use GetAuthContext instead.
func MustFromContext ¶
func MustFromContext(ctx context.Context) *AuthContext
MustFromContext retrieves the AuthContext or panics. Use this only when you're certain the context contains auth information (e.g., after auth middleware has run).
func MustGetAuthContext ¶
func MustGetAuthContext(ctx forge.Context) *AuthContext
MustGetAuthContext retrieves the AuthContext from forge.Context or panics. Use this only when you're certain the context contains auth information (e.g., after auth middleware has run).
func (*AuthContext) GetClaim ¶
func (a *AuthContext) GetClaim(key string) (any, bool)
GetClaim retrieves a claim by key.
func (*AuthContext) GetClaimString ¶
func (a *AuthContext) GetClaimString(key string) (string, bool)
GetClaimString retrieves a string claim.
func (*AuthContext) HasAllPermissions ¶ added in v1.9.8
func (a *AuthContext) HasAllPermissions(permissions ...string) bool
HasAllPermissions reports whether the subject holds every permission.
func (*AuthContext) HasAnyRole ¶ added in v1.9.8
func (a *AuthContext) HasAnyRole(roles ...string) bool
HasAnyRole reports whether the subject holds at least one of the roles.
No roles required means everyone satisfies it. A requirement that demands nothing must not deny, or threading an unguarded route through a generic authorizer would start refusing it.
func (*AuthContext) HasPermission ¶ added in v1.9.8
func (a *AuthContext) HasPermission(permission string) bool
HasPermission reports whether the subject holds a permission.
func (*AuthContext) HasRole ¶ added in v1.9.8
func (a *AuthContext) HasRole(role string) bool
HasRole reports whether the subject holds a role.
func (*AuthContext) HasScope ¶
func (a *AuthContext) HasScope(scope string) bool
HasScope checks if the auth context has a specific scope.
func (*AuthContext) HasScopes ¶
func (a *AuthContext) HasScopes(scopes ...string) bool
HasScopes checks if the auth context has all specified scopes.
type AuthProvider ¶
type AuthProvider interface {
// Name returns the unique name/ID of this auth provider.
// This name is used to reference the provider in route/group options.
Name() string
// Type returns the OpenAPI security scheme type
Type() SecuritySchemeType
// Authenticate validates the request and returns the authenticated subject.
// Returns the auth context (user, claims, etc.) or an error.
// The provider can access services from the DI container via closures.
Authenticate(ctx context.Context, r *http.Request) (*AuthContext, error)
// OpenAPIScheme returns the OpenAPI security scheme definition.
// This is used to automatically generate OpenAPI security documentation.
OpenAPIScheme() SecurityScheme
// Middleware returns HTTP middleware for this provider.
// The middleware is automatically applied when the provider is used.
Middleware() forge.Middleware
}
AuthProvider defines the interface for authentication providers. Implementations can access the DI container through closures or context to retrieve services needed for authentication (database, cache, etc.).
type Authorizer ¶ added in v1.9.8
type Authorizer interface {
Name() string
Authorize(ctx context.Context, authCtx *AuthContext, req Requirement) error
}
Authorizer decides whether an authenticated subject satisfies a route's declared requirement.
Forge ships one implementation doing plain set membership. warden replaces it wholesale through Registry.SetAuthorizer. Forge itself never grows role hierarchies, permission inheritance or wildcard matching: that is policy, and policy belongs to the authorizer.
Authorize returns an error rather than a bool so an implementation can say why it refused. A nil return allows. An error wrapping ErrAuthorizationFailed or ErrInsufficientScopes maps to 403.
func NewDefaultAuthorizer ¶ added in v1.9.8
func NewDefaultAuthorizer() Authorizer
NewDefaultAuthorizer returns the built-in set-membership authorizer.
type Config ¶
type Config struct {
// Enabled determines if auth extension is enabled
Enabled bool `yaml:"enabled"`
// Providers holds provider-specific configurations
Providers []ProviderConfig `yaml:"providers"`
// DefaultProvider is the default provider name to use
DefaultProvider string `yaml:"default_provider"`
// RequireConfig requires config from ConfigManager
RequireConfig bool `yaml:"-"`
// Authorizer, when set, replaces the built-in set-membership authorizer.
// This is the seam a policy engine such as warden plugs into.
Authorizer Authorizer `yaml:"-"`
}
Config holds auth extension configuration.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the default auth configuration.
type ConfigOption ¶
type ConfigOption func(*Config)
ConfigOption configures the auth extension.
func WithAuthorizer ¶ added in v1.9.8
func WithAuthorizer(a Authorizer) ConfigOption
WithAuthorizer sets the authorization decision maker.
Example:
auth.NewExtension(
auth.WithAuthorizer(warden.New(policySource)),
)
func WithDefaultProvider ¶
func WithDefaultProvider(name string) ConfigOption
WithDefaultProvider sets the default provider.
func WithEnabled ¶
func WithEnabled(enabled bool) ConfigOption
WithEnabled sets whether auth is enabled.
func WithProviders ¶
func WithProviders(providers ...ProviderConfig) ConfigOption
WithProviders sets the provider configurations.
func WithRequireConfig ¶
func WithRequireConfig(require bool) ConfigOption
WithRequireConfig requires config from ConfigManager.
type Extension ¶
type Extension struct {
*forge.BaseExtension
// contains filtered or unexported fields
}
Extension implements forge.Extension for authentication and authorization. It provides a registry for managing auth providers and automatically integrates with the router for OpenAPI security scheme generation. The extension is now a lightweight facade that loads config and registers services.
func (*Extension) Register ¶
Register registers the auth extension with the app. This method now only loads configuration and registers service constructors.
type ProviderConfig ¶
type ProviderConfig struct {
Name string `yaml:"name"`
Type string `yaml:"type"`
Enabled bool `yaml:"enabled"`
Description string `yaml:"description"`
Config map[string]any `yaml:"config"`
}
ProviderConfig holds configuration for a single auth provider.
type ProviderFunc ¶
ProviderFunc is a function adapter for simple auth providers.
type Registry ¶
type Registry interface {
// Register registers an auth provider
Register(provider AuthProvider) error
// Unregister removes a provider by name
Unregister(name string) error
// Get retrieves a provider by name
Get(name string) (AuthProvider, error)
// Has checks if a provider exists
Has(name string) bool
// List returns all registered provider names
List() []string
// Middleware creates combined middleware for multiple providers.
// When multiple providers are specified, they are tried in order (OR logic).
// Authentication succeeds if ANY provider succeeds.
Middleware(providerNames ...string) forge.Middleware
// MiddlewareAnd creates middleware requiring ALL providers to succeed (AND logic).
MiddlewareAnd(providerNames ...string) forge.Middleware
// MiddlewareWithScopes creates middleware with required scopes
MiddlewareWithScopes(providerName string, scopes ...string) forge.Middleware
// MiddlewareWithRequirement authenticates through the requirement's
// providers and then hands the result to the authorizer.
MiddlewareWithRequirement(req Requirement) forge.Middleware
// OpenAPISchemes returns all security schemes for OpenAPI generation
OpenAPISchemes() map[string]SecurityScheme
// SetAuthorizer replaces the authorization decision maker. Passing nil is
// ignored, so a misconfigured caller cannot leave the registry without one.
SetAuthorizer(a Authorizer)
// Authorizer returns the current decision maker. Never nil.
Authorizer() Authorizer
}
Registry manages authentication providers. It provides thread-safe registration and retrieval of auth providers, and can create middleware that chains multiple providers.
func GetRegistry ¶
GetRegistry retrieves the auth Registry from the container. Returns error if not found or type assertion fails.
func GetRegistryFromApp ¶
GetRegistryFromApp retrieves the auth Registry from the app. Returns error if not found or type assertion fails.
func MustGetRegistry ¶
MustGetRegistry retrieves the auth Registry from the container. Panics if not found or type assertion fails.
func MustGetRegistryFromApp ¶
MustGetRegistryFromApp retrieves the auth Registry from the app. Panics if not found or type assertion fails.
type Requirement ¶ added in v1.9.8
type Requirement struct {
// Providers are the auth providers that may satisfy authentication.
Providers []string
// Scopes must all be held. Existing WithRequiredAuth behaviour.
Scopes []string
// Roles: holding any one of them satisfies the requirement.
Roles []string
// Permissions must all be held.
Permissions []string
// Mode is "or" or "and", and applies to Providers only.
Mode string
}
Requirement is the static authorization requirement a route declares.
It is a value rather than a closure on purpose: a value can be written into an OpenAPI document and read back into a generated client, and a closure cannot. That is the constraint that keeps v1 free of resource-scoped checks (can this user edit document 42), which stay inside handlers.
func (Requirement) IsEmpty ¶ added in v1.9.8
func (r Requirement) IsEmpty() bool
IsEmpty reports whether this requirement asks anything of the subject beyond being authenticated.
Providers are excluded: naming a provider is an authentication requirement, which the middleware has already enforced by the time an authorizer runs.
type SecurityScheme ¶
type SecurityScheme = shared.SecurityScheme
SecurityScheme represents an OpenAPI security scheme definition We use the shared type to ensure compatibility with OpenAPI generation.
type SecuritySchemeType ¶
type SecuritySchemeType string
SecuritySchemeType represents OpenAPI 3.1 security scheme types.
const ( SecurityTypeAPIKey SecuritySchemeType = "apiKey" SecurityTypeHTTP SecuritySchemeType = "http" SecurityTypeOAuth2 SecuritySchemeType = "oauth2" SecurityTypeOpenIDConnect SecuritySchemeType = "openIdConnect" SecurityTypeMutualTLS SecuritySchemeType = "mutualTLS" )