Documentation
ΒΆ
Overview ΒΆ
Package env provides environment variable loading and management.
Adapter Pattern Implementation ΒΆ
This file implements adapters for internal types that need to be exposed via public interfaces with extended functionality.
Interface hierarchy (simplified):
- env.KeyValidator = internal.KeyValidator
- env.ValueValidator = internal.ValueValidator
- env.VariableExpander = internal.VariableExpander
- env.AuditLogger = internal.AuditLogger
The remaining adapters handle cases where the public interface has more methods than the minimal internal interface:
- auditorAdapter: internal.Auditor β FullAuditLogger
- validatorInterfaceWrapper: minimal validator β Validator (with ValidateRequired)
- auditorInterfaceWrapper: minimal auditor β FullAuditLogger
Package env provides a high-security environment variable library for Go 1.24+. It is designed for applications where security, concurrent access, and production-grade features are critical.
The library supports multiple file formats (.env, JSON, YAML), secure memory handling for sensitive values, comprehensive audit logging, and extensive validation.
Two Usage Modes ΒΆ
The library provides two complementary usage patterns:
## Global Mode (Simple)
Use package-level functions after calling Load(). Best for simple applications:
err := env.Load(".env")
if err != nil {
log.Fatal(err)
}
port := env.GetInt("PORT", 8080)
host := env.GetString("DATABASE_HOST", "localhost")
## Instance Mode (Advanced)
Create isolated Loader instances with New(). Best for tests and fine-grained control:
cfg := env.DefaultConfig()
cfg.Filenames = []string{".env"}
loader, err := env.New(cfg)
if err != nil {
log.Fatal(err)
}
defer loader.Close()
value := loader.GetString("DATABASE_URL")
When to Use Which Mode ΒΆ
Use Global Mode when:
- Simple application with single configuration
- Want automatic apply to os.Environ (Load does this by default)
- Quick scripts, prototypes, or small services
Use Instance Mode when:
- Writing tests that need isolation
- Multiple configurations in same process
- Need control over when variables are applied to os.Environ
- Want explicit lifecycle management with Close()
Secure Value Handling ΒΆ
For sensitive values like API keys and passwords, use SecureValue:
sv := loader.GetSecure("API_KEY")
if sv != nil {
defer sv.Release()
data := sv.Bytes()
// use data securely
env.ClearBytes(data)
}
Struct Mapping ΒΆ
Map environment variables to structs using tags:
type Config struct {
Host string `env:"DB_HOST" envDefault:"localhost"`
Port int `env:"DB_PORT" envDefault:"5432"`
}
var cfg Config
if err := env.ParseInto(&cfg); err != nil {
log.Fatal(err)
}
Environment Presets ΒΆ
The library provides preset configurations for different environments:
- DefaultConfig: Secure defaults for general use
- DevelopmentConfig: Relaxed limits, overwrite enabled
- TestingConfig: Isolated, compact limits
- ProductionConfig: Strict limits, audit enabled
File Format Support ΒΆ
Supported file formats:
- .env: Standard dotenv format with KEY=value pairs
- .json: JSON files with nested structure (flattened with underscores)
- .yaml/.yml: YAML files with nested structure (flattened with underscores)
Thread Safety ΒΆ
All Loader methods are safe for concurrent use. The library uses sharded locking for optimal performance in high-concurrency scenarios.
Error Types ΒΆ
The library defines several error types for precise error handling:
- ErrFileNotFound: File does not exist
- ErrFileTooLarge: File exceeds size limit
- ErrInvalidKey: Key format validation failed
- ErrSecurityViolation: Security policy violation
- ErrClosed: Loader has been closed
- ParseError: Parsing failure with file/line info
- ValidationError: Configuration or value validation failure
- SecurityError: Security-related error
- FileError: File operation error
- ExpansionError: Variable expansion error
- JSONError: JSON parsing error
- YAMLError: YAML parsing error
- MarshalError: Marshaling/unmarshaling error
Package env provides environment variable loading and management.
Component Factory ΒΆ
This file implements ComponentFactory which creates and manages shared components used by Loader and Parser. It provides a clean lifecycle for validator, auditor, and expander instances.
The factory uses adapters (defined in adapters.go) to bridge between public interfaces and internal interfaces, allowing both built-in and custom components to work seamlessly.
Index ΒΆ
- Constants
- Variables
- func All() map[string]string
- func ClearBytes(b []byte)
- func Delete(key string) error
- func ForceRegisterParser(format FileFormat, factory ParserFactory) error
- func GetBool(key string, defaultValue ...bool) bool
- func GetDuration(key string, defaultValue ...time.Duration) time.Duration
- func GetInt(key string, defaultValue ...int64) int64
- func GetSlice[T sliceElement](key string, defaultValue ...[]T) []T
- func GetSliceFrom[T sliceElement](loader *Loader, key string, defaultValue ...[]T) []T
- func GetString(key string, defaultValue ...string) string
- func IsMarshalError(err error) bool
- func IsMemoryLockEnabled() bool
- func IsMemoryLockStrict() bool
- func IsMemoryLockSupported() bool
- func IsSensitiveKey(key string) bool
- func Keys() []string
- func Len() int
- func Load(filenames ...string) error
- func LoadWithConfig(cfg Config) error
- func Lookup(key string) (string, bool)
- func Marshal(data interface{}, format ...FileFormat) (string, error)
- func MarshalStruct(v interface{}) (map[string]string, error)
- func MaskKey(key string) string
- func MaskSensitiveInString(s string) string
- func MaskValue(key, value string) string
- func ParseInto(v interface{}) error
- func RegisterParser(format FileFormat, factory ParserFactory) error
- func ResetDefaultLoader() error
- func SanitizeForLog(s string) string
- func Set(key, value string) error
- func SetMemoryLockEnabled(enabled bool)
- func SetMemoryLockStrict(strict bool)
- func UnmarshalInto(data map[string]string, v interface{}) error
- func UnmarshalMap(data string, format ...FileFormat) (map[string]string, error)
- func UnmarshalStruct(data string, v interface{}, format ...FileFormat) error
- func Validate() error
- type AuditAction
- type AuditEvent
- type AuditHandler
- type AuditLogger
- type ChannelAuditHandler
- type ComponentConfig
- type ComponentFactory
- func (f *ComponentFactory) Auditor() FullAuditLogger
- func (f *ComponentFactory) Close() error
- func (f *ComponentFactory) Expander() VariableExpander
- func (f *ComponentFactory) IsClosed() bool
- func (f *ComponentFactory) LineParserAuditor() internal.LineAuditLogger
- func (f *ComponentFactory) LineParserExpander() internal.LineExpander
- func (f *ComponentFactory) LineParserValidator() internal.LineKeyValidator
- func (f *ComponentFactory) Validator() Validator
- type Config
- type EnvApplicator
- type EnvCloser
- type EnvFileLoader
- type EnvGetter
- type EnvLoader
- type EnvParser
- type EnvSetter
- type EnvStorage
- type ExpansionError
- type File
- type FileConfig
- type FileError
- type FileFormat
- type FileSystem
- type FullAuditLogger
- type JSONAuditHandler
- type JSONConfig
- type JSONError
- type KeyValidator
- type LimitsConfig
- type Loader
- func (l *Loader) All() map[string]string
- func (l *Loader) Apply() error
- func (l *Loader) Close() error
- func (l *Loader) Config() Config
- func (l *Loader) Delete(key string) error
- func (l *Loader) GetBool(key string, defaultValue ...bool) bool
- func (l *Loader) GetDuration(key string, defaultValue ...time.Duration) time.Duration
- func (l *Loader) GetInt(key string, defaultValue ...int64) int64
- func (l *Loader) GetSecure(key string) *SecureValue
- func (l *Loader) GetString(key string, defaultValue ...string) string
- func (l *Loader) IsApplied() bool
- func (l *Loader) IsClosed() bool
- func (l *Loader) Keys() []string
- func (l *Loader) Len() int
- func (l *Loader) LoadFiles(filenames ...string) error
- func (l *Loader) LoadTime() time.Time
- func (l *Loader) Lookup(key string) (string, bool)
- func (l *Loader) ParseInto(v interface{}) error
- func (l *Loader) Set(key, value string) error
- func (l *Loader) Validate() error
- type LogAuditHandler
- type MarshalError
- type Marshaler
- type NopAuditHandler
- type OSFileSystem
- func (OSFileSystem) Getenv(key string) string
- func (OSFileSystem) LookupEnv(key string) (string, bool)
- func (OSFileSystem) MkdirAll(path string, perm os.FileMode) error
- func (OSFileSystem) Open(name string) (File, error)
- func (OSFileSystem) OpenFile(name string, flag int, perm os.FileMode) (File, error)
- func (OSFileSystem) Remove(name string) error
- func (OSFileSystem) Rename(oldpath, newpath string) error
- func (OSFileSystem) Setenv(key, value string) error
- func (OSFileSystem) Stat(name string) (os.FileInfo, error)
- func (OSFileSystem) Unsetenv(key string) error
- type ParseError
- type ParserFactory
- type ParsingConfig
- type RequiredValidator
- type SecureValue
- func (sv *SecureValue) Bytes() []byte
- func (sv *SecureValue) Close() error
- func (sv *SecureValue) IsClosed() bool
- func (sv *SecureValue) IsMemoryLocked() bool
- func (sv *SecureValue) Length() int
- func (sv *SecureValue) Masked() string
- func (sv *SecureValue) MemoryLockError() error
- func (sv *SecureValue) Release()
- func (sv *SecureValue) String() string
- type SecurityError
- type Unmarshaler
- type ValidationConfig
- type ValidationError
- type Validator
- type ValueValidator
- type VariableExpander
- type YAMLConfig
- type YAMLError
Constants ΒΆ
const ( // DefaultMaxFileSize is the maximum allowed file size (2 MB). DefaultMaxFileSize = internal.DefaultMaxFileSize // DefaultMaxLineLength is the maximum allowed line length. DefaultMaxLineLength = internal.DefaultMaxLineLength // DefaultMaxKeyLength is the maximum allowed key length. DefaultMaxKeyLength = internal.DefaultMaxKeyLength // DefaultMaxValueLength is the maximum allowed value length. DefaultMaxValueLength = internal.DefaultMaxValueLength // DefaultMaxVariables is the maximum number of variables per file. DefaultMaxVariables = internal.DefaultMaxVariables // DefaultMaxExpansionDepth is the maximum variable expansion depth. DefaultMaxExpansionDepth = internal.DefaultMaxExpansionDepth )
Default security limits for high-security configurations. These values are intentionally conservative to prevent various attacks.
Variables ΒΆ
var ( // ErrFileNotFound indicates the specified file does not exist. ErrFileNotFound = errors.New("file not found") // ErrFileTooLarge indicates the file exceeds the maximum allowed size. // Re-exported from internal/errors for backward compatibility. ErrFileTooLarge = ierrors.ErrFileTooLarge // ErrLineTooLong indicates a line exceeds the maximum allowed length. // Re-exported from internal/errors for backward compatibility. ErrLineTooLong = ierrors.ErrLineTooLong // ErrInvalidKey indicates the key does not match the required pattern. ErrInvalidKey = errors.New("invalid key format") // ErrForbiddenKey indicates the key is not allowed for security reasons. ErrForbiddenKey = errors.New("key is forbidden for security reasons") // ErrSecurityViolation indicates a general security policy violation. // Re-exported from internal/errors for backward compatibility. ErrSecurityViolation = ierrors.ErrSecurityViolation // ErrExpansionDepth indicates variable expansion exceeded the maximum depth. ErrExpansionDepth = errors.New("variable expansion depth exceeded") // ErrMaxVariables indicates the maximum number of variables has been reached. ErrMaxVariables = errors.New("maximum number of variables exceeded") // ErrNullByte indicates a null byte was detected in the input. ErrNullByte = errors.New("null byte detected in input") // ErrControlChar indicates a control character was detected in the input. ErrControlChar = errors.New("control character detected in input") // ErrInvalidValue indicates the value contains invalid content. // Re-exported from internal/errors for backward compatibility. ErrInvalidValue = ierrors.ErrInvalidValue // ErrMissingRequired indicates a required key is missing. ErrMissingRequired = errors.New("required key is missing") // ErrDuplicateKey indicates a duplicate key was encountered. ErrDuplicateKey = errors.New("duplicate key encountered") // ErrClosed indicates the loader has been closed. ErrClosed = errors.New("loader has been closed") // ErrInvalidConfig indicates the configuration is invalid. ErrInvalidConfig = errors.New("invalid configuration") )
Sentinel errors provide simple error comparison using errors.Is().
var DefaultKeyPattern *regexp.Regexp = nil
DefaultKeyPattern is the default pattern for valid keys. Set to nil to use fast byte-level validation (isValidDefaultKey) instead of regex. This provides ~10x performance improvement for key validation. The regex pattern ^[A-Za-z][A-Za-z0-9_]*$ is still available for reference:
var defaultKeyPatternRegex = regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_]*$`)
var ErrAlreadyInitialized = errors.New("default loader already initialized")
ErrAlreadyInitialized is returned when attempting to set a default loader when one has already been initialized.
var ErrValidateRequiredUnsupported = errors.New(
"custom validator does not implement ValidateRequired; " +
"implement Validator interface for required key validation",
)
ErrValidateRequiredUnsupported is returned when a custom validator does not implement the ValidateRequired method. Users who need required key validation should implement the full Validator interface.
Functions ΒΆ
func All ΒΆ
All returns all environment variables from the default loader as a map. Returns nil if the loader cannot be initialized.
Example:
vars := env.All()
for key, value := range vars {
fmt.Printf("%s = %s\n", key, value)
}
func ClearBytes ΒΆ
func ClearBytes(b []byte)
ClearBytes securely zeros a byte slice. Use this function to clear sensitive data returned by SecureValue.Bytes().
Example:
data := sv.Bytes() defer env.ClearBytes(data)
func Delete ΒΆ
Delete removes a key from the default loader. Returns an error if the loader cannot be initialized.
Example:
if err := env.Delete("TEMP_VAR"); err != nil {
log.Fatal(err)
}
func ForceRegisterParser ΒΆ added in v1.1.0
func ForceRegisterParser(format FileFormat, factory ParserFactory) error
ForceRegisterParser registers a parser factory, allowing override of built-in parsers (FormatEnv, FormatJSON, FormatYAML).
WARNING: Use with caution. Overriding built-in parsers may introduce security vulnerabilities if the replacement parser doesn't implement the same security checks (key validation, value validation, size limits, etc.). Ensure your custom parser properly validates all input.
This is intended for advanced use cases where you need complete control over parsing behavior, such as:
- Adding custom security checks to the built-in parser
- Implementing format extensions (e.g., HEREDOC support, multi-line values)
- Testing with mock parsers
Example:
// Override the default .env parser with a custom implementation
err := env.ForceRegisterParser(env.FormatEnv, func(cfg env.Config, factory *env.ComponentFactory) (env.EnvParser, error) {
return &MyCustomEnvParser{
validator: factory.Validator(),
auditor: factory.Auditor(),
}, nil
})
func GetBool ΒΆ
GetBool retrieves a boolean value from the default loader with optional default. Returns false if the loader cannot be initialized or the key is not found and no default is provided.
Example:
debug := env.GetBool("DEBUG") // Returns false if not found
debug := env.GetBool("DEBUG", true) // Returns true if not found
func GetDuration ΒΆ
GetDuration retrieves a duration value from the default loader with optional default. Returns 0 if the loader cannot be initialized or the key is not found and no default is provided.
Example:
timeout := env.GetDuration("TIMEOUT") // Returns 0 if not found
timeout := env.GetDuration("TIMEOUT", 30*time.Second) // Returns 30s if not found
func GetInt ΒΆ
GetInt retrieves an integer value from the default loader with optional default. Returns 0 if the loader cannot be initialized or the key is not found and no default is provided.
Example:
port := env.GetInt("PORT") // Returns 0 if not found
port := env.GetInt("PORT", 8080) // Returns 8080 if not found
func GetSlice ΒΆ
func GetSlice[T sliceElement](key string, defaultValue ...[]T) []T
GetSlice retrieves a slice of values from the default loader. Returns nil if the loader cannot be initialized or the key is not found and no default is provided.
Indexed keys are searched in format: KEY_0, KEY_1, KEY_2, etc. Also supports comma-separated values as fallback for .env files.
Example:
ports := env.GetSlice[int]("PORTS")
hosts := env.GetSlice[string]("HOSTS", []string{"localhost"})
func GetSliceFrom ΒΆ
GetSliceFrom retrieves a slice of values from a loader by iterating through indexed keys. If the key is not found and no default is provided, returns nil. Supports dot-notation path resolution for nested keys.
Indexed keys are searched in format: KEY_0, KEY_1, KEY_2, etc. Also supports comma-separated values as fallback for .env files.
Why a Function Instead of a Method? ΒΆ
This is a generic function rather than a method because Go does not support type parameters on methods. The pattern is:
// Method approach (not possible in Go):
// loader.GetSlice[int]("PORTS") // β Compile error
// Function approach (current implementation):
env.GetSliceFrom[int](loader, "PORTS") // β Works
For package-level usage without a loader instance, use GetSlice[T]().
Example:
ports := env.GetSliceFrom[int](loader, "PORTS") // Returns []int{8080, 8081} from PORTS_0, PORTS_1
hosts := env.GetSliceFrom[string](loader, "HOSTS", []string{"localhost"}) // With default
func GetString ΒΆ
GetString retrieves a value from the default loader with optional default. Returns an empty string if the loader cannot be initialized or the key is not found and no default is provided. Use Lookup to distinguish between "not found" and "empty value".
Example:
value := env.GetString("KEY") // Returns "" if not found
value := env.GetString("KEY", "default") // Returns "default" if not found
func IsMarshalError ΒΆ
IsMarshalError checks if an error is a marshaling error.
func IsMemoryLockEnabled ΒΆ
func IsMemoryLockEnabled() bool
IsMemoryLockEnabled returns whether memory locking is currently enabled.
func IsMemoryLockStrict ΒΆ
func IsMemoryLockStrict() bool
IsMemoryLockStrict returns whether strict mode is enabled.
func IsMemoryLockSupported ΒΆ
func IsMemoryLockSupported() bool
IsMemoryLockSupported returns whether the current platform supports memory locking. This returns false on platforms like wasm or nacl where memory locking is not available.
Note: This only indicates platform support, not whether the process has the required privileges to actually lock memory.
func IsSensitiveKey ΒΆ
IsSensitiveKey determines if a key likely contains sensitive data.
func Keys ΒΆ
func Keys() []string
Keys returns all keys from the default loader. Returns nil if the loader cannot be initialized.
Example:
for _, key := range env.Keys() {
fmt.Printf("%s = %s\n", key, env.GetString(key))
}
func Len ΒΆ
func Len() int
Len returns the number of loaded variables from the default loader. Returns 0 if the loader cannot be initialized.
Example:
count := env.Len()
fmt.Printf("Loaded %d environment variables\n", count)
func Load ΒΆ
Load initializes the default loader with the given files.
IMPORTANT: This function:
- Sets the package-level default loader (used by GetString, GetInt, etc.)
- Auto-applies all loaded variables to os.Environ
For isolated instances without auto-apply, use New().
Files are loaded sequentially; later files can override values from earlier files.
Supported file formats:
- .env files (dotenv format)
- .json files (JSON format with nested structure)
- .yaml/.yml files (YAML format with nested structure)
For JSON/YAML files, nested values are flattened and can be accessed using dot-notation:
// config.json: {"database": {"host": "localhost", "port": 5432}}
env.Load("config.json")
host := env.GetString("database.host") // "localhost"
port := env.GetInt("database.port") // 5432
Returns ErrAlreadyInitialized if the default loader has already been initialized.
Example:
// Initialize with default .env file
if err := env.Load(); err != nil {
log.Fatal(err)
}
// Initialize with multiple files
if err := env.Load(".env", ".env.local"); err != nil {
log.Fatal(err)
}
// Now use package-level functions
port := env.GetInt("PORT", 8080)
func LoadWithConfig ΒΆ added in v1.1.0
LoadWithConfig initializes the default loader with a custom configuration.
IMPORTANT: This function:
- Sets the package-level default loader (used by GetString, GetInt, etc.)
- Forces AutoApply=true regardless of cfg.AutoApply value
For isolated instances without setting the default, use New().
Returns ErrAlreadyInitialized if the default loader has already been initialized.
Example:
cfg := env.DefaultConfig()
cfg.Filenames = []string{".env.production"}
cfg.OverwriteExisting = true
if err := env.LoadWithConfig(cfg); err != nil {
log.Fatal(err)
}
func Lookup ΒΆ
Lookup retrieves a value and existence from the default loader.
Example:
value, exists := env.Lookup("DATABASE_URL")
if !exists {
log.Fatal("DATABASE_URL is required")
}
func Marshal ΒΆ
func Marshal(data interface{}, format ...FileFormat) (string, error)
Marshal converts data to the specified format with sorted keys (default: .env format). The input can be a map[string]string or a struct (will be converted to map first). The format parameter is optional; if not provided, defaults to .env format. Supported formats: FormatEnv, FormatJSON, FormatYAML.
Keys are always sorted for consistent output.
Example:
// Map to .env format (sorted) envString, _ := env.Marshal(mapData) // Struct to .env format (sorted) envString, _ := env.Marshal(config) // Map to JSON format (sorted) jsonString, _ := env.Marshal(mapData, env.FormatJSON) // Struct to YAML format (sorted) yamlString, _ := env.Marshal(config, env.FormatYAML)
func MarshalStruct ΒΆ
MarshalStruct converts a struct to environment variables. Struct fields can be tagged with `env:"KEY"` to specify the env variable name. Nested structs are flattened with underscore-separated keys.
func MaskSensitiveInString ΒΆ
MaskSensitiveInString masks potentially sensitive content in a string.
func MaskValue ΒΆ
MaskValue masks a value based on its sensitivity. This is a utility function for general value masking.
func ParseInto ΒΆ
func ParseInto(v interface{}) error
ParseInto populates a struct from the default loader's environment variables. Struct fields can be tagged with `env:"KEY"` to specify the env variable name. Optional `envDefault:"value"` sets a default if the key is not found.
This function automatically reads all loaded environment variables and maps them to struct fields based on the `env` tags. It eliminates the need to manually build a data map before calling UnmarshalStruct.
Example:
type Config struct {
Host string `env:"DB_HOST"`
Port int `env:"DB_PORT,envDefault:5432"`
Debug bool `env:"DEBUG,envDefault:false"`
}
if err := env.Load(".env"); err != nil {
log.Fatal(err)
}
var cfg Config
if err := env.ParseInto(&cfg); err != nil {
log.Fatal(err)
}
func RegisterParser ΒΆ
func RegisterParser(format FileFormat, factory ParserFactory) error
RegisterParser registers a custom parser factory for a specific file format. Returns an error if a factory is already registered for the format. Built-in formats (DotEnv, JSON, YAML) cannot be overridden for security.
Example:
err := env.RegisterParser(env.FormatEnv, func(cfg env.Config, factory *env.ComponentFactory) (env.EnvParser, error) {
return &MyCustomParser{validator: factory.Validator()}, nil
})
func ResetDefaultLoader ΒΆ
func ResetDefaultLoader() error
ResetDefaultLoader resets the default loader singleton and clears any cached error. This function is intended for use in tests to ensure isolation between test cases. It is safe for concurrent use.
Returns any error that occurred while closing the old loader. A nil return value indicates either no loader was set or it was closed successfully.
Design: The function atomically swaps the loader to nil while holding the lock, then closes the old loader outside the lock. This design choice:
- Ensures only one reset can happen at a time (mutex protected)
- Allows new loaders to be created immediately after the swap
- Clears cached initialization errors to allow retry
- Avoids blocking concurrent operations during potentially slow Close()
- The old and new loaders are completely independent
Concurrent getDefaultLoader() calls during reset will:
- Either see the old loader (before swap) - safe to use
- Or see nil and create a new loader (after swap) - safe to use
They will never receive a closed loader.
Example:
func TestSomething(t *testing.T) {
if err := env.ResetDefaultLoader(); err != nil {
t.Logf("warning: failed to reset loader: %v", err)
}
defer env.ResetDefaultLoader()
// ... test code
}
func SanitizeForLog ΒΆ
SanitizeForLog removes potentially sensitive information from a string. It scans for patterns that might indicate sensitive data and masks them.
func Set ΒΆ
Set sets a value in the default loader.
Example:
if err := env.Set("DEBUG", "true"); err != nil {
log.Fatal(err)
}
func SetMemoryLockEnabled ΒΆ
func SetMemoryLockEnabled(enabled bool)
SetMemoryLockEnabled enables or disables memory locking globally. This affects all new SecureValue objects created after the call. Existing SecureValue objects are not affected.
This function is safe to call from multiple goroutines simultaneously.
Example:
func main() {
// Enable at application startup
env.SetMemoryLockEnabled(true)
// ... rest of application
}
func SetMemoryLockStrict ΒΆ
func SetMemoryLockStrict(strict bool)
SetMemoryLockStrict sets whether memory locking failures should return errors. By default, locking failures are silently ignored for compatibility. Enable strict mode for high-security applications that require confirmation that memory is actually locked.
Example:
env.SetMemoryLockEnabled(true)
env.SetMemoryLockStrict(true) // Now locking failures will return errors
sv := env.NewSecureValue("sensitive-data")
// If locking failed, sv will still be valid but the error is logged
func UnmarshalInto ΒΆ
UnmarshalInto populates a struct from a map[string]string. Struct fields can be tagged with `env:"KEY"` to specify the env variable name. Optional `envDefault:"value"` sets a default if the key is not found.
func UnmarshalMap ΒΆ
func UnmarshalMap(data string, format ...FileFormat) (map[string]string, error)
UnmarshalMap parses a formatted string into a map[string]string. The format parameter is optional and defaults to FormatEnv. Use FormatAuto for automatic format detection.
Nested structures (JSON/YAML) are flattened with underscore delimiter.
Example:
// .env format (default)
m, _ := env.UnmarshalMap("KEY=value")
// JSON format
m, _ := env.UnmarshalMap(`{"server": {"host": "localhost"}}`, env.FormatJSON)
// Auto-detect format
m, _ := env.UnmarshalMap(jsonString, env.FormatAuto)
func UnmarshalStruct ΒΆ
func UnmarshalStruct(data string, v interface{}, format ...FileFormat) error
UnmarshalStruct parses a formatted string and populates the struct. The format parameter is optional and defaults to FormatEnv. Use FormatAuto for automatic format detection.
Struct fields should use `env:"KEY"` tags for mapping.
Example:
type Config struct {
Host string `env:"SERVER_HOST"`
Port int `env:"SERVER_PORT"`
}
// .env format (default)
var cfg Config
_ = env.UnmarshalStruct("SERVER_HOST=localhost\nSERVER_PORT=8080", &cfg)
// JSON format
_ = env.UnmarshalStruct(`{"server": {"host": "localhost"}}`, &cfg, env.FormatJSON)
Types ΒΆ
type AuditAction ΒΆ
AuditAction represents the type of action being audited. Use these constants with AuditLogger.Log() to record security-relevant events.
const ( ActionLoad AuditAction = internal.ActionLoad ActionParse AuditAction = internal.ActionParse ActionGet AuditAction = internal.ActionGet ActionSet AuditAction = internal.ActionSet ActionDelete AuditAction = internal.ActionDelete ActionValidate AuditAction = internal.ActionValidate ActionExpand AuditAction = internal.ActionExpand ActionSecurity AuditAction = internal.ActionSecurity ActionError AuditAction = internal.ActionError ActionFileAccess AuditAction = internal.ActionFileAccess )
Audit constants for common actions. These are used with AuditLogger methods to categorize audit events:
- ActionLoad: File loading operations
- ActionParse: Parsing operations for env, JSON, YAML files
- ActionGet: Variable retrieval operations
- ActionSet: Variable assignment operations
- ActionDelete: Variable deletion operations
- ActionValidate: Validation operations
- ActionExpand: Variable expansion operations
- ActionSecurity: Security-related events (path validation, forbidden keys)
- ActionError: Error conditions
- ActionFileAccess: File system access operations
type AuditHandler ΒΆ
AuditHandler defines the interface for audit log handlers.
type AuditLogger ΒΆ
type AuditLogger = internal.AuditLogger
AuditLogger is an alias for internal.AuditLogger. This interface requires only LogError, making it easy to implement custom loggers. For full audit capabilities, see FullAuditLogger.
type ChannelAuditHandler ΒΆ
type ChannelAuditHandler = internal.ChannelHandler
ChannelAuditHandler sends audit events to a channel.
func NewChannelAuditHandler ΒΆ
func NewChannelAuditHandler(ch chan<- AuditEvent) *ChannelAuditHandler
NewChannelAuditHandler creates a new ChannelAuditHandler.
type ComponentConfig ΒΆ added in v1.1.0
type ComponentConfig struct {
CustomValidator Validator // Custom key/value validator
CustomExpander VariableExpander // Custom variable expander
CustomAuditor AuditLogger // Custom audit logger
FileSystem FileSystem // Custom file system (for testing)
AuditHandler AuditHandler // Custom audit handler
AuditEnabled bool // Enable audit logging
Prefix string // Only process vars with this prefix
}
ComponentConfig holds custom component implementations and advanced options.
type ComponentFactory ΒΆ
type ComponentFactory struct {
// contains filtered or unexported fields
}
ComponentFactory creates and manages shared components used by Loader and Parser. It provides a clean lifecycle for validator, auditor, and expander instances. ComponentFactory is safe for concurrent use.
func (*ComponentFactory) Auditor ΒΆ
func (f *ComponentFactory) Auditor() FullAuditLogger
Auditor returns the audit logger component as FullAuditLogger.
func (*ComponentFactory) Close ΒΆ
func (f *ComponentFactory) Close() error
Close releases resources held by the factory. After calling Close, the factory should not be used. Safe to call multiple times; subsequent calls return nil. This method is safe for concurrent use.
func (*ComponentFactory) Expander ΒΆ added in v1.1.0
func (f *ComponentFactory) Expander() VariableExpander
Expander returns the expander as VariableExpander interface.
func (*ComponentFactory) IsClosed ΒΆ
func (f *ComponentFactory) IsClosed() bool
IsClosed returns true if the factory has been closed. This method is safe for concurrent use.
func (*ComponentFactory) LineParserAuditor ΒΆ added in v1.1.0
func (f *ComponentFactory) LineParserAuditor() internal.LineAuditLogger
LineParserAuditor returns the auditor as internal.LineAuditLogger interface.
func (*ComponentFactory) LineParserExpander ΒΆ added in v1.1.0
func (f *ComponentFactory) LineParserExpander() internal.LineExpander
LineParserExpander returns the expander as internal.LineExpander interface.
func (*ComponentFactory) LineParserValidator ΒΆ added in v1.1.0
func (f *ComponentFactory) LineParserValidator() internal.LineKeyValidator
LineParserValidator returns the validator as internal.LineKeyValidator interface.
func (*ComponentFactory) Validator ΒΆ
func (f *ComponentFactory) Validator() Validator
Validator returns the validator component as a Validator interface.
type Config ΒΆ
type Config struct {
FileConfig // File loading behavior
ValidationConfig // Key and value validation
LimitsConfig // Size and count limits
JSONConfig // JSON parsing options
YAMLConfig // YAML parsing options
ParsingConfig // General parsing behavior
ComponentConfig // Custom components and advanced options
}
Config holds all configuration options for the Loader.
Configuration is organized into nested structures for better organization while maintaining backward compatibility through Go's struct embedding. You can access fields either way:
// Old way (still works via field promotion):
cfg.Filenames = []string{".env"}
cfg.MaxFileSize = 1024
// New way (recommended for clarity):
cfg.FileConfig.Filenames = []string{".env"}
cfg.LimitsConfig.MaxFileSize = 1024
For sensible defaults, use DefaultConfig():
cfg := env.DefaultConfig()
cfg.FileConfig.Filenames = []string{".env"}
func DefaultConfig ΒΆ
func DefaultConfig() Config
DefaultConfig returns a Config with secure default values. These defaults are suitable for high-security environments.
func DevelopmentConfig ΒΆ
func DevelopmentConfig() Config
DevelopmentConfig returns a Config optimized for development environments. This configuration prioritizes developer experience and flexibility:
- FailOnMissingFile: false (graceful handling of missing .env files)
- OverwriteExisting: true (easy iteration during development)
- AllowYamlSyntax: true (supports YAML-style values)
- Relaxed size limits (10MB files, 500 variables)
- Value validation ENABLED for security (prevents injection attacks)
Example:
cfg := env.DevelopmentConfig()
cfg.FileConfig.Filenames = []string{".env.development"}
loader, err := env.New(cfg)
func ProductionConfig ΒΆ
func ProductionConfig() Config
ProductionConfig returns a Config optimized for production environments. This configuration provides maximum security for production deployments:
- FailOnMissingFile: true (fail fast on configuration errors)
- AuditEnabled: true (compliance and security monitoring)
- Strict size limits (64KB files, 50 variables)
- Value validation enabled
Example:
cfg := env.ProductionConfig()
cfg.FileConfig.Filenames = []string{"/etc/app/.env"}
cfg.ComponentConfig.AuditHandler = env.NewJSONAuditHandler(os.Stdout)
loader, err := env.New(cfg)
func TestingConfig ΒΆ
func TestingConfig() Config
TestingConfig returns a Config optimized for testing environments. This configuration is designed for isolated, repeatable tests:
- FailOnMissingFile: false (tests may not have .env files)
- OverwriteExisting: true (test isolation)
- Compact size limits (test files are typically small)
- No audit logging (reduces test noise)
Example:
func TestSomething(t *testing.T) {
cfg := env.TestingConfig()
cfg.FileConfig.Filenames = []string{".env.test"}
loader, err := env.New(cfg)
if err != nil {
t.Fatal(err)
}
defer loader.Close()
}
func (*Config) IsZero ΒΆ added in v1.1.0
IsZero returns true if the Config appears to be uninitialized (all fields zero). This is useful to determine if DefaultConfig() should be applied.
Note: A partially-initialized Config may not be detected as zero. Always start from DefaultConfig() for custom configurations:
cfg := env.DefaultConfig()
cfg.Filenames = []string{".env.production"}
type EnvApplicator ΒΆ
type EnvApplicator interface {
// Apply applies all loaded variables to the process environment.
Apply() error
}
EnvApplicator handles applying loaded variables to the process environment. Use this interface when you only need to apply variables to os.Environ.
type EnvCloser ΒΆ
type EnvCloser interface {
// Close closes the loader and releases resources.
Close() error
}
EnvCloser handles lifecycle management. Use this interface when you only need to close and release resources.
type EnvFileLoader ΒΆ
type EnvFileLoader interface {
// LoadFiles loads environment variables from multiple files.
// If no filenames are provided, defaults to ".env".
LoadFiles(filenames ...string) error
}
EnvFileLoader handles loading environment variables from files and strings. Use this interface when you only need file loading capabilities.
type EnvGetter ΒΆ
type EnvGetter interface {
// Get retrieves a value by key with optional default.
GetString(key string, defaultValue ...string) string
// Lookup retrieves a value by key and reports whether it exists.
Lookup(key string) (string, bool)
// Keys returns all keys.
Keys() []string
// All returns all environment variables as a map.
All() map[string]string
}
EnvGetter handles reading environment variable values. Use this interface when you only need read access to variables.
type EnvLoader ΒΆ
type EnvLoader interface {
EnvFileLoader
EnvGetter
EnvSetter
EnvApplicator
EnvCloser
}
EnvLoader defines the full interface for loading and managing environment variables. It combines all fine-grained interfaces for convenience.
For new code, consider using the fine-grained interfaces (EnvFileLoader, EnvGetter, EnvSetter, EnvApplicator, EnvCloser) which follow the Interface Segregation Principle and allow for more precise dependency declarations.
type EnvParser ΒΆ
type EnvParser interface {
// Parse reads and parses environment variables from an io.Reader.
// The filename parameter is used for error messages and audit logging.
Parse(r io.Reader, filename string) (map[string]string, error)
}
EnvParser defines the interface for parsing environment files.
type EnvSetter ΒΆ
type EnvSetter interface {
// Set sets a value for a key with validation.
Set(key, value string) error
// Delete removes a key.
Delete(key string) error
}
EnvSetter handles writing environment variable values. Use this interface when you only need write access to variables. Note: Set and Delete methods return error for validation failures, unlike EnvStorage.Set which is a simple storage operation.
type EnvStorage ΒΆ
type EnvStorage interface {
// Get retrieves a value by key. Returns the value and whether it exists.
Get(key string) (string, bool)
// Set stores a value for a key.
Set(key, value string)
// Delete removes a key.
Delete(key string)
// Keys returns all keys in the storage.
Keys() []string
// Len returns the number of entries.
Len() int
// ToMap returns a copy of all values as a regular map.
ToMap() map[string]string
// Clear removes all entries.
Clear()
}
EnvStorage defines the interface for storing and retrieving environment variables.
type ExpansionError ΒΆ
type ExpansionError = ierrors.ExpansionError
ExpansionError provides detailed information about variable expansion failures. This is an alias for internal.ExpansionError to maintain backward compatibility.
type File ΒΆ
File defines the interface for file operations. It combines common io interfaces with file-specific operations.
type FileConfig ΒΆ added in v1.1.0
type FileConfig struct {
Filenames []string // Files to load (default: [".env"])
FailOnMissingFile bool // Return error if file doesn't exist
OverwriteExisting bool // Overwrite existing environment variables
AutoApply bool // Auto-apply to os.Environ
}
FileConfig controls file loading behavior.
type FileError ΒΆ
FileError provides detailed information about file-related errors. This is an alias for internal.FileError to maintain backward compatibility.
type FileFormat ΒΆ
type FileFormat int
FileFormat represents the file format for environment configuration.
const ( // FormatAuto automatically detects the format based on file extension. FormatAuto FileFormat = iota // FormatEnv represents the .env file format. FormatEnv // FormatJSON represents a JSON file format. FormatJSON // FormatYAML represents a YAML file format. FormatYAML )
func DetectFormat ΒΆ
func DetectFormat(filename string) FileFormat
DetectFormat detects the file format based on the file extension. Returns FormatEnv for ".env" files, FormatJSON for ".json" files, FormatYAML for ".yaml" and ".yml" files, and FormatAuto for unknown extensions.
func (FileFormat) String ΒΆ
func (f FileFormat) String() string
String returns the string representation of the file format. Returns "auto", "dotenv", "json", "yaml", or "unknown" based on the format value.
type FileSystem ΒΆ
type FileSystem interface {
// Open opens a file for reading.
Open(name string) (File, error)
// OpenFile opens a file with the specified flags and permissions.
OpenFile(name string, flag int, perm os.FileMode) (File, error)
// Stat returns file information.
Stat(name string) (os.FileInfo, error)
// MkdirAll creates a directory and any necessary parents.
MkdirAll(path string, perm os.FileMode) error
// Remove removes a file.
Remove(name string) error
// Rename renames a file.
Rename(oldpath, newpath string) error
// Getenv retrieves the value of the environment variable named by the key.
Getenv(key string) string
// Setenv sets the value of the environment variable named by the key.
Setenv(key, value string) error
// Unsetenv unsets the environment variable named by the key.
Unsetenv(key string) error
// LookupEnv retrieves the value of the environment variable named by the key.
LookupEnv(key string) (string, bool)
}
FileSystem defines the interface for file system operations. This interface allows for dependency injection, making code more testable by enabling mock implementations.
var DefaultFileSystem FileSystem = OSFileSystem{}
DefaultFileSystem is the default file system implementation using the real OS.
type FullAuditLogger ΒΆ added in v1.1.0
type FullAuditLogger interface {
AuditLogger
// Log records an audit event.
Log(action AuditAction, key, reason string, success bool) error
// LogWithFile records an audit event with file information.
LogWithFile(action AuditAction, key, file, reason string, success bool) error
// LogWithDuration records an audit event with timing information.
LogWithDuration(action AuditAction, key, reason string, success bool, duration time.Duration) error
// Close closes the audit logger and releases resources.
Close() error
}
FullAuditLogger provides extended audit logging capabilities. It extends AuditLogger with additional methods for detailed logging. The built-in internal.Auditor implements this interface.
type JSONAuditHandler ΒΆ
type JSONAuditHandler = internal.JSONHandler
JSONAuditHandler writes audit events as JSON to an io.Writer.
func NewJSONAuditHandler ΒΆ
func NewJSONAuditHandler(w io.Writer) *JSONAuditHandler
NewJSONAuditHandler creates a new JSONAuditHandler.
type JSONConfig ΒΆ added in v1.1.0
type JSONConfig struct {
JSONNullAsEmpty bool // Convert null to empty string
JSONNumberAsString bool // Convert numbers to strings
JSONBoolAsString bool // Convert booleans to strings
JSONMaxDepth int // Maximum nesting depth
}
JSONConfig controls JSON parsing behavior.
type JSONError ΒΆ
JSONError represents a JSON parsing error. This is an alias for internal.JSONError to maintain backward compatibility.
type KeyValidator ΒΆ
type KeyValidator = internal.KeyValidator
KeyValidator is an alias for internal.KeyValidator. Implementations can enforce naming conventions, security policies, and length limits.
type LimitsConfig ΒΆ added in v1.1.0
type LimitsConfig struct {
MaxFileSize int64 // Maximum file size in bytes
MaxVariables int // Maximum variables per file
MaxLineLength int // Maximum line length
MaxKeyLength int // Maximum key length
MaxValueLength int // Maximum value length
MaxExpansionDepth int // Maximum variable expansion depth
}
LimitsConfig controls size and count limits for parsing.
type Loader ΒΆ
type Loader struct {
// contains filtered or unexported fields
}
Loader is the main type for loading and managing environment variables. It provides thread-safe access to environment variables with full security validation, audit logging, and error handling.
func New ΒΆ
New creates a new Loader with the given configuration.
BEHAVIOR:
- Does NOT set the package-level default loader
- Does NOT auto-apply to os.Environ (unless cfg.AutoApply = true)
- Can be called multiple times to create independent instances
- Requires explicit lifecycle management: defer loader.Close()
If no configuration is provided or a zero-value Config is passed, DefaultConfig() is used automatically.
FOR SIMPLE USE CASES: Use Load() instead, which sets up the package-level default and applies to os.Environ automatically.
WHEN TO USE New():
- Multiple loaders in one application (different configs/files)
- Testing with isolated environment state
- When you need explicit control over when variables are applied
Example:
// Use default configuration
loader, err := env.New()
// Use custom configuration
cfg := env.DefaultConfig()
cfg.Filenames = []string{".env.production"}
cfg.AutoApply = true
loader, err := env.New(cfg)
func (*Loader) Close ΒΆ
Close closes the loader and securely clears all stored values. If the loader owns its ComponentFactory, it will also close the factory.
func (*Loader) Config ΒΆ
Config returns the loader's configuration. Note: The returned Config should be treated as read-only. Modifying the Security.KeyPattern, AllowedKeys, ForbiddenKeys, or RequiredKeys fields may affect the loader's behavior. For a safe mutable copy, manually copy the necessary fields.
func (*Loader) GetBool ΒΆ
GetBool retrieves a boolean value with optional default. If the key is not found and no default is provided, returns false.
Example:
debug := loader.GetBool("DEBUG") // Returns false if not found
debug := loader.GetBool("DEBUG", true) // Returns true if not found
func (*Loader) GetDuration ΒΆ
GetDuration retrieves a duration value with optional default. If the key is not found and no default is provided, returns 0.
Example:
timeout := loader.GetDuration("TIMEOUT") // Returns 0 if not found
timeout := loader.GetDuration("TIMEOUT", 30*time.Second) // Returns 30s if not found
func (*Loader) GetInt ΒΆ
GetInt retrieves an integer value with optional default. If the key is not found and no default is provided, returns 0.
Example:
port := loader.GetInt("PORT") // Returns 0 if not found
port := loader.GetInt("PORT", 8080) // Returns 8080 if not found
func (*Loader) GetSecure ΒΆ
func (l *Loader) GetSecure(key string) *SecureValue
GetSecure retrieves a SecureValue by key.
func (*Loader) GetString ΒΆ
GetString retrieves a value by key with optional default. If the key is not found and no default is provided, returns empty string. Supports dot-notation path resolution for nested keys (e.g., "database.host" -> "DATABASE_HOST").
Example:
value := loader.GetString("KEY") // Returns "" if not found
value := loader.GetString("KEY", "default") // Returns "default" if not found
func (*Loader) IsApplied ΒΆ
IsApplied returns true if the variables have been applied to os.Environ.
func (*Loader) LoadFiles ΒΆ
LoadFiles loads environment variables from multiple files in order. If no filenames are provided, defaults to ".env". Files are loaded sequentially; later files can override values from earlier files.
Example:
// Load default .env file
err := loader.LoadFiles()
// Load specific files
err := loader.LoadFiles(".env", ".env.local")
func (*Loader) Lookup ΒΆ
Lookup retrieves a value by key and reports whether it exists. Supports dot-notation path resolution for nested keys (e.g., "database.host" -> "DATABASE_HOST"). For indexed access (e.g., "service.cors.origins.0"), falls back to comma-separated values if indexed key is not found. Returns the value with leading and trailing whitespace trimmed.
type LogAuditHandler ΒΆ
type LogAuditHandler = internal.LogHandler
LogAuditHandler writes audit events using the standard log package.
func NewLogAuditHandler ΒΆ
func NewLogAuditHandler(logger *log.Logger) *LogAuditHandler
NewLogAuditHandler creates a new LogAuditHandler.
type MarshalError ΒΆ
type MarshalError = ierrors.MarshalError
MarshalError represents a marshaling/unmarshaling error. This is an alias for internal.MarshalError to maintain backward compatibility.
type NopAuditHandler ΒΆ
type NopAuditHandler = internal.NopHandler
NopAuditHandler discards all audit events.
func NewNopAuditHandler ΒΆ
func NewNopAuditHandler() *NopAuditHandler
NewNopAuditHandler creates a new NopAuditHandler.
type OSFileSystem ΒΆ
type OSFileSystem struct{}
OSFileSystem implements FileSystem using the real operating system. OSFileSystem is safe for concurrent use. The zero value is valid and ready to use.
func (OSFileSystem) Getenv ΒΆ
func (OSFileSystem) Getenv(key string) string
Getenv retrieves the value of the environment variable using os.Getenv.
func (OSFileSystem) LookupEnv ΒΆ
func (OSFileSystem) LookupEnv(key string) (string, bool)
LookupEnv retrieves the value of the environment variable using os.LookupEnv.
func (OSFileSystem) MkdirAll ΒΆ
func (OSFileSystem) MkdirAll(path string, perm os.FileMode) error
MkdirAll creates a directory and any necessary parents using os.MkdirAll.
func (OSFileSystem) Open ΒΆ
func (OSFileSystem) Open(name string) (File, error)
Open opens a file for reading using os.Open.
func (OSFileSystem) Remove ΒΆ
func (OSFileSystem) Remove(name string) error
Remove removes a file using os.Remove.
func (OSFileSystem) Rename ΒΆ
func (OSFileSystem) Rename(oldpath, newpath string) error
Rename renames a file using os.Rename.
func (OSFileSystem) Setenv ΒΆ
func (OSFileSystem) Setenv(key, value string) error
Setenv sets the value of the environment variable using os.Setenv.
func (OSFileSystem) Stat ΒΆ
func (OSFileSystem) Stat(name string) (os.FileInfo, error)
Stat returns file information using os.Stat.
func (OSFileSystem) Unsetenv ΒΆ
func (OSFileSystem) Unsetenv(key string) error
Unsetenv unsets the environment variable using os.Unsetenv.
type ParseError ΒΆ
type ParseError = ierrors.ParseError
ParseError provides detailed information about parsing failures. This is an alias for internal.ParseError to maintain backward compatibility.
type ParserFactory ΒΆ
type ParserFactory func(cfg Config, factory *ComponentFactory) (EnvParser, error)
ParserFactory creates an EnvParser from a Config and ComponentFactory. Custom parser implementations should implement this function signature to register their parsers with the library.
type ParsingConfig ΒΆ added in v1.1.0
type ParsingConfig struct {
AllowExportPrefix bool // Allow "export KEY=value" syntax
AllowYamlSyntax bool // Allow YAML-style values in .env
ExpandVariables bool // Expand ${VAR} references
}
ParsingConfig controls general parsing behavior.
type RequiredValidator ΒΆ added in v1.1.0
type RequiredValidator interface {
// ValidateRequired checks that all required keys are present.
ValidateRequired(keys map[string]bool) error
}
RequiredValidator defines the interface for validating required keys.
type SecureValue ΒΆ
type SecureValue struct {
// contains filtered or unexported fields
}
SecureValue wraps a sensitive value with automatic memory zeroing. When the value is garbage collected, its memory is securely cleared. If memory locking is enabled, the data is also protected from being swapped to disk.
func GetSecure ΒΆ
func GetSecure(key string) *SecureValue
GetSecure retrieves a SecureValue from the default loader. Returns nil if the loader cannot be initialized or the key is not found. Use GetSecure for sensitive values that need secure memory handling.
Example:
sv := env.GetSecure("API_KEY")
if sv != nil {
fmt.Println(sv.Masked()) // Safe for logging
data := sv.Bytes()
defer env.ClearBytes(data)
// Use data securely
}
func NewSecureValue ΒΆ
func NewSecureValue(value string) *SecureValue
NewSecureValue creates a new SecureValue from a string. The value is stored in a separate memory allocation that will be zeroed when the SecureValue is garbage collected or explicitly closed. This function uses a pool to reduce allocations.
Memory Locking: If memory locking is enabled globally (via SetMemoryLockEnabled(true)), this function will attempt to lock the memory to prevent swapping. Locking failures are silently ignored unless strict mode is enabled.
func NewSecureValueStrict ΒΆ
func NewSecureValueStrict(value string) (*SecureValue, error)
NewSecureValueStrict creates a new SecureValue and returns an error if memory locking is enabled but fails. Use this function when you need to ensure that the memory is actually protected from being swapped to disk.
Example:
env.SetMemoryLockEnabled(true)
sv, err := env.NewSecureValueStrict("sensitive-data")
if err != nil {
// Memory locking failed - handle appropriately
log.Printf("Warning: memory not locked: %v", err)
}
defer sv.Release()
func (*SecureValue) Bytes ΒΆ
func (sv *SecureValue) Bytes() []byte
Bytes returns a copy of the value as a byte slice. The caller is responsible for securely clearing the returned slice using ClearBytes.
func (*SecureValue) Close ΒΆ
func (sv *SecureValue) Close() error
Close securely clears the value and marks it as closed. After calling Close, all access methods return zero values. Note: This method does NOT return the SecureValue to the pool. For explicit pool return, use Release() instead.
func (*SecureValue) IsClosed ΒΆ
func (sv *SecureValue) IsClosed() bool
IsClosed returns true if the value has been closed.
func (*SecureValue) IsMemoryLocked ΒΆ
func (sv *SecureValue) IsMemoryLocked() bool
IsMemoryLocked returns true if the value's memory is currently locked (protected from being swapped to disk). Returns false if memory locking is not enabled or if locking failed.
func (*SecureValue) Length ΒΆ
func (sv *SecureValue) Length() int
Length returns the length of the value without exposing it.
func (*SecureValue) Masked ΒΆ
func (sv *SecureValue) Masked() string
Masked returns a masked representation for logging.
func (*SecureValue) MemoryLockError ΒΆ
func (sv *SecureValue) MemoryLockError() error
MemoryLockError returns any error that occurred during memory locking. Returns nil if locking was successful or not attempted. This is useful in strict mode to detect if memory locking failed.
func (*SecureValue) Release ΒΆ
func (sv *SecureValue) Release()
Release securely clears the value and returns it to the pool. This is more efficient than Close() for high-frequency operations as it allows the SecureValue to be reused.
The finalizer is cleared before returning to the pool to ensure: 1. The object can be safely reused without finalizer interference 2. NewSecureValue() will set a fresh finalizer when the object is reused
func (*SecureValue) String ΒΆ
func (sv *SecureValue) String() string
String returns the value as a string. This method is provided for convenience but should be used carefully as it creates a copy of the sensitive data.
type SecurityError ΒΆ
type SecurityError = ierrors.SecurityError
SecurityError provides detailed information about security violations. This is an alias for internal.SecurityError to maintain backward compatibility.
type Unmarshaler ΒΆ
Unmarshaler is the interface for types that can unmarshal themselves from env values.
type ValidationConfig ΒΆ added in v1.1.0
type ValidationConfig struct {
RequiredKeys []string // Require these keys to be present
AllowedKeys []string // Only allow these keys (empty = all allowed)
ForbiddenKeys []string // Always forbid these keys
KeyPattern *regexp.Regexp // Pattern for valid keys (nil = default)
ValidateValues bool // Validate values for security issues
ValidateUTF8 bool // Validate that values are valid UTF-8
}
ValidationConfig controls key and value validation.
type ValidationError ΒΆ
type ValidationError = ierrors.ValidationError
ValidationError provides detailed information about validation failures. This is an alias for internal.ValidationError to maintain backward compatibility.
type Validator ΒΆ
type Validator interface {
KeyValidator
ValueValidator
RequiredValidator
}
Validator combines all validation capabilities. Implementations should implement all three methods for full functionality. Partial implementations (only KeyValidator) will return ErrValidateRequiredUnsupported from ValidateRequired.
type ValueValidator ΒΆ
type ValueValidator = internal.ValueValidator
ValueValidator is an alias for internal.ValueValidator. Implementations can check for security issues like null bytes or control characters.
type VariableExpander ΒΆ
type VariableExpander = internal.VariableExpander
VariableExpander is an alias for internal.VariableExpander. Implementations can support different expansion syntaxes ($VAR, ${VAR}, etc.).
type YAMLConfig ΒΆ added in v1.1.0
type YAMLConfig struct {
YAMLNullAsEmpty bool // Convert null/~ to empty string
YAMLNumberAsString bool // Convert numbers to strings
YAMLBoolAsString bool // Convert booleans to strings
YAMLMaxDepth int // Maximum nesting depth
}
YAMLConfig controls YAML parsing behavior.