Files
Luminary/internal/config/config.go
T
renjue bdf6ff0ae8 Harden security defaults and fix gateway reliability issues.
Fail fast on missing config and reject default encryption keys; use SHA-256 ingress key lookup, trusted-proxy-aware client IP, sentinel gateway errors with correct HTTP status codes, daily provider key counter reset, Anthropic multimodal forwarding, and cache Get methods that return copies.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 12:48:23 +08:00

114 lines
2.6 KiB
Go

package config
import (
"fmt"
"os"
"strings"
"time"
"gopkg.in/yaml.v3"
)
type Config struct {
Server ServerConfig `yaml:"server"`
Database DatabaseConfig `yaml:"database"`
Admin AdminConfig `yaml:"admin"`
Cache CacheConfig `yaml:"cache"`
HealthCheck HealthCheckConfig `yaml:"health_check"`
Security SecurityConfig `yaml:"security"`
Gateway GatewayConfig `yaml:"gateway"`
}
type GatewayConfig struct {
MaxRetries int `yaml:"max_retries"`
RetryBackoffMs int `yaml:"retry_backoff_ms"`
}
type ServerConfig struct {
Addr string `yaml:"addr"`
}
type DatabaseConfig struct {
Path string `yaml:"path"`
}
type AdminConfig struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
}
type CacheConfig struct {
UsageFlushInterval time.Duration `yaml:"usage_flush_interval"`
}
type HealthCheckConfig struct {
Interval time.Duration `yaml:"interval"`
}
type SecurityConfig struct {
EncryptionKey string `yaml:"encryption_key"`
SessionTTL time.Duration `yaml:"session_ttl"`
IPAllowlist []string `yaml:"ip_allowlist"`
TrustedProxies []string `yaml:"trusted_proxies"`
LoginMaxAttempts int `yaml:"login_max_attempts"`
LoginLockout time.Duration `yaml:"login_lockout"`
}
func Load(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read config: %w", err)
}
cfg := Default()
if err := yaml.Unmarshal(data, cfg); err != nil {
return nil, fmt.Errorf("parse config: %w", err)
}
resolveEnv(cfg)
return cfg, nil
}
func Default() *Config {
return &Config{
Server: ServerConfig{Addr: ":8080"},
Database: DatabaseConfig{
Path: "./data/luminary.db",
},
Admin: AdminConfig{
Username: "admin",
Password: "admin123",
},
Cache: CacheConfig{
UsageFlushInterval: 5 * time.Second,
},
HealthCheck: HealthCheckConfig{
Interval: 30 * time.Second,
},
Security: SecurityConfig{
EncryptionKey: "change-me-in-production-32bytes!!",
SessionTTL: 24 * time.Hour,
LoginMaxAttempts: 5,
LoginLockout: 15 * time.Minute,
},
Gateway: GatewayConfig{
MaxRetries: 3,
RetryBackoffMs: 200,
},
}
}
func resolveEnv(cfg *Config) {
cfg.Admin.Username = resolveEnvValue(cfg.Admin.Username)
cfg.Admin.Password = resolveEnvValue(cfg.Admin.Password)
cfg.Security.EncryptionKey = resolveEnvValue(cfg.Security.EncryptionKey)
}
func resolveEnvValue(v string) string {
if strings.HasPrefix(v, "env.") {
key := strings.TrimPrefix(v, "env.")
if val := os.Getenv(key); val != "" {
return val
}
}
return v
}