security

package
v0.36.0 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AccessTokenExpires  = time.Minute * 30
	RefreshTokenExpires = time.Hour * 24 * 7
)
View Source
const (
	AuthTypePassword = "password"
)
View Source
const (
	AuthTypeRefresh = "refresh"
)
View Source
const AuthTypeSignature = "signature"

AuthTypeSignature is the authentication type for signature-based authentication.

View Source
const (
	AuthTypeToken = "token"
)

Variables

View Source
var (
	// ErrIPWhitelistNameBlank rejects a whitelist declared under a blank name.
	ErrIPWhitelistNameBlank = errors.New("ip whitelist name must not be blank")
	// ErrIPWhitelistEmpty rejects a whitelist with no usable entries, which
	// could never authenticate a request.
	ErrIPWhitelistEmpty = errors.New("ip whitelist must contain at least one IP or CIDR entry")
	// ErrIPWhitelistEntryInvalid rejects an entry that is neither an IP
	// address nor a CIDR range.
	ErrIPWhitelistEntryInvalid = errors.New("ip whitelist entry is neither an IP address nor a CIDR range")
)

Configuration faults raised while building the config-backed IP whitelist loader; they surface as fx start-up errors, never through the API.

View Source
var Module = fx.Module(
	"vef:security",
	fx.Decorate(func(cfg *config.SecurityConfig) *config.SecurityConfig {
		if cfg.TokenExpires <= 0 {
			cfg.TokenExpires = RefreshTokenExpires
		}

		if cfg.RefreshNotBefore <= 0 {
			cfg.RefreshNotBefore = AccessTokenExpires / 2
		}

		if cfg.LoginRateLimit <= 0 {
			cfg.LoginRateLimit = 6
		}

		if cfg.RefreshRateLimit <= 0 {
			cfg.RefreshRateLimit = 1
		}

		return cfg
	}),
	fx.Decorate(
		fx.Annotate(
			func(loader security.RolePermissionsLoader, bus event.Bus) security.RolePermissionsLoader {
				if loader == nil {
					return nil
				}

				return security.NewCachedRolePermissionsLoader(loader, bus)
			},
			fx.ParamTags(`optional:"true"`),
		),
	),
	fx.Provide(
		password.NewBcryptEncoder,
		newJWT,
		fx.Annotate(
			NewJWTAuthenticator,
			fx.ResultTags(`group:"vef:security:authenticators"`),
		),
		fx.Annotate(
			NewJWTRefreshAuthenticator,
			fx.ParamTags(``, `optional:"true"`),
			fx.ResultTags(`group:"vef:security:authenticators"`),
		),
		NewJWTTokenGenerator,
		security.NewJWTChallengeTokenStore,
		fx.Annotate(
			NewSignatureAuthenticator,
			fx.ParamTags(`optional:"true"`, `optional:"true"`),
			fx.ResultTags(`group:"vef:security:authenticators"`),
		),
		fx.Annotate(
			NewPasswordAuthenticator,
			fx.ParamTags(`optional:"true"`, `optional:"true"`),
			fx.ResultTags(`group:"vef:security:authenticators"`),
		),
		fx.Annotate(
			NewAuthManager,
			fx.ParamTags(`group:"vef:security:authenticators"`),
		),
		fx.Annotate(
			NewRBACPermissionChecker,
			fx.ParamTags(`optional:"true"`),
		),
		fx.Annotate(
			NewRBACDataPermissionResolver,
			fx.ParamTags(`optional:"true"`),
		),
		fx.Annotate(
			NewAuthResource,
			fx.ResultTags(`group:"vef:api:resources"`),
		),
	),
)

Functions

func NewAuthManager

func NewAuthManager(authenticators []security.Authenticator) security.AuthManager

func NewAuthResource

func NewAuthResource(params AuthResourceParams) api.Resource

NewAuthResource creates a new authentication resource with the provided auth manager and token generator.

func NewConfigIPWhitelistLoader added in v0.34.0

func NewConfigIPWhitelistLoader(cfg *config.SecurityConfig) (security.IPWhitelistLoader, error)

NewConfigIPWhitelistLoader builds the framework's default security.IPWhitelistLoader from the static vef.security.ip_whitelists configuration. Because the source is immutable deployment config, every whitelist is validated eagerly: a blank name, an empty whitelist, or an entry that is neither an IP address nor a CIDR range fails construction (and therefore application start-up) instead of silently denying every request at runtime.

func NewJWTAuthenticator

func NewJWTAuthenticator(jwt *security.JWT) security.Authenticator

func NewJWTRefreshAuthenticator

func NewJWTRefreshAuthenticator(jwt *security.JWT, userLoader security.UserLoader) security.Authenticator

func NewJWTTokenGenerator

func NewJWTTokenGenerator(jwt *security.JWT, securityConfig *config.SecurityConfig) security.TokenGenerator

func NewPasswordAuthenticator

func NewPasswordAuthenticator(
	loader security.UserLoader,
	encoder password.Encoder,
) security.Authenticator

func NewRBACDataPermissionResolver

func NewRBACDataPermissionResolver(loader security.RolePermissionsLoader) security.DataPermissionResolver

NewRBACDataPermissionResolver creates a new RBAC data permission resolver.

func NewSignatureAuthenticator

func NewSignatureAuthenticator(
	loader security.ExternalAppLoader,
	nonceStore security.NonceStore,
) security.Authenticator

NewSignatureAuthenticator creates a new signature authenticator.

A single long-lived Signature verifier is built here and reused across every request. This is what makes server-side replay protection actually work: the nonce store is shared process-wide rather than recreated per request (a fresh per-request in-memory store would always see every nonce as absent, turning replay detection into a no-op and leaking a GC goroutine on each call). The per-request app secret is supplied to VerifyWithSecret at verification time, so the verifier's own bound secret is never used.

Types

type AuthResource

type AuthResource struct {
	api.Resource
	// contains filtered or unexported fields
}

AuthResource handles authentication-related API endpoints.

func (*AuthResource) GetUserInfo

func (a *AuthResource) GetUserInfo(ctx fiber.Ctx, principal *security.Principal, params api.Params) error

GetUserInfo retrieves user information via UserInfoLoader. Requires a UserInfoLoader implementation to be provided.

func (*AuthResource) Login

func (a *AuthResource) Login(ctx fiber.Ctx, params LoginParams) error

Login authenticates a user and returns a LoginResult. When challenge providers are configured and applicable, the result contains a challenge token and pending challenges instead of auth tokens.

func (*AuthResource) Logout

func (*AuthResource) Logout(ctx fiber.Ctx) error

Logout returns success immediately. Token invalidation should be handled on the client side by removing stored tokens.

func (*AuthResource) Refresh

func (a *AuthResource) Refresh(ctx fiber.Ctx, params RefreshParams) error

Refresh refreshes the access token using a valid refresh token. User data reload logic is handled by JwtRefreshAuthenticator.

func (*AuthResource) ResolveChallenge

func (a *AuthResource) ResolveChallenge(ctx fiber.Ctx, params ResolveChallengeParams) error

ResolveChallenge validates a user's response to a login challenge. On success, either issues real auth tokens (all challenges resolved) or evaluates the next challenge sequentially.

A ChallengeProvider may reject a response by returning a typed result.Error (e.g. security.ErrOTPCodeInvalid) to control the client-facing code; a bare error is normalized to security.ErrChallengeResolveFailed (code security.ErrCodeChallengeResolveFailed).

type AuthResourceParams

type AuthResourceParams struct {
	fx.In

	AuthManager         security.AuthManager
	TokenGenerator      security.TokenGenerator
	ChallengeTokenStore security.ChallengeTokenStore
	UserInfoLoader      security.UserInfoLoader      `optional:"true"`
	ChallengeProviders  []security.ChallengeProvider `group:"vef:security:challenge_providers"`
	Bus                 event.Bus
	SecurityConfig      *config.SecurityConfig
}

AuthResourceParams holds the dependencies for AuthResource construction.

type AuthenticatorAuthManager

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

func (*AuthenticatorAuthManager) Authenticate

func (am *AuthenticatorAuthManager) Authenticate(ctx context.Context, authentication security.Authentication) (*security.Principal, error)

type JWTRefreshAuthenticator

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

func (*JWTRefreshAuthenticator) Authenticate

func (j *JWTRefreshAuthenticator) Authenticate(ctx context.Context, authentication security.Authentication) (*security.Principal, error)

func (*JWTRefreshAuthenticator) Supports

func (*JWTRefreshAuthenticator) Supports(authType string) bool

type JWTTokenAuthenticator

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

func (*JWTTokenAuthenticator) Authenticate

func (ja *JWTTokenAuthenticator) Authenticate(_ context.Context, authentication security.Authentication) (*security.Principal, error)

func (*JWTTokenAuthenticator) Supports

func (*JWTTokenAuthenticator) Supports(authType string) bool

type JWTTokenGenerator

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

func (*JWTTokenGenerator) Generate

func (g *JWTTokenGenerator) Generate(principal *security.Principal) (*security.AuthTokens, error)

type LoginParams

type LoginParams struct {
	api.P

	Type        string `json:"type" validate:"required" label_i18n:"auth_type"`
	Principal   string `json:"principal" validate:"required" label_i18n:"auth_principal"`
	Credentials any    `json:"credentials" validate:"required" label_i18n:"auth_credentials"`
}

LoginParams represents the request parameters for user login.

type PasswordAuthenticator

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

PasswordAuthenticator verifies username/password credentials with optional decryption support for scenarios where clients encrypt passwords before transmission.

func (*PasswordAuthenticator) Authenticate

func (p *PasswordAuthenticator) Authenticate(ctx context.Context, authentication security.Authentication) (*security.Principal, error)

func (*PasswordAuthenticator) Supports

func (*PasswordAuthenticator) Supports(authType string) bool

type RBACDataPermissionResolver

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

RBACDataPermissionResolver implements role-based data permission resolution.

func (*RBACDataPermissionResolver) ResolveDataScope

func (r *RBACDataPermissionResolver) ResolveDataScope(
	ctx context.Context,
	principal *security.Principal,
	permission string,
) (security.DataScope, error)

ResolveDataScope resolves the applicable DataScope for the given principal and permission token. When a user has multiple roles with the same permission token but different data scopes, the scope with the highest priority wins. Returns nil if no matching permission is found.

type RBACPermissionChecker

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

func (*RBACPermissionChecker) HasPermission

func (c *RBACPermissionChecker) HasPermission(
	ctx context.Context,
	principal *security.Principal,
	permissionToken string,
) (bool, error)

HasPermission uses sequential role loading rather than parallel to optimize for common case (1-3 roles).

type RefreshParams

type RefreshParams struct {
	api.P

	RefreshToken string `json:"refreshToken" validate:"required" label_i18n:"auth_refresh_token"`
}

RefreshParams represents the request parameters for token refresh operation.

type ResolveChallengeParams

type ResolveChallengeParams struct {
	api.P

	ChallengeToken string `json:"challengeToken" validate:"required" label_i18n:"auth_challenge_token"`
	Type           string `json:"type" validate:"required" label_i18n:"auth_challenge_type"`
	Response       any    `json:"response" validate:"required" label_i18n:"auth_challenge_response"`
}

ResolveChallengeParams represents the request for resolving a login challenge.

type SignatureAuthenticator

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

SignatureAuthenticator validates HMAC-based signatures for external app authentication.

func (*SignatureAuthenticator) Authenticate

func (a *SignatureAuthenticator) Authenticate(ctx context.Context, authentication security.Authentication) (*security.Principal, error)

func (*SignatureAuthenticator) Supports

func (*SignatureAuthenticator) Supports(authType string) bool

Jump to

Keyboard shortcuts

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