From 606e0a3329a3534a00889eee19c25e7d432f7d2d Mon Sep 17 00:00:00 2001 From: bndw Date: Sat, 14 Feb 2026 10:11:16 -0800 Subject: refactor: restructure auth config for better UX Changed from flat structure to hierarchical read/write config: Before: auth: enabled: bool required: bool allowed_npubs_read: [] allowed_npubs_write: [] After: auth: read: enabled: bool allowed_npubs: [] write: enabled: bool allowed_npubs: [] Three states per operation: - enabled=false: no auth, allow all - enabled=true, allowed_npubs=[]: auth required, any valid signature - enabled=true, allowed_npubs=[...]: auth required, whitelist only Much clearer semantics and easier to reason about. --- internal/config/config.go | 57 +++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'internal/config/config.go') diff --git a/internal/config/config.go b/internal/config/config.go index 3e52272..294510d 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -39,12 +39,19 @@ type DatabaseConfig struct { // AuthConfig holds authentication configuration. type AuthConfig struct { - Enabled bool `yaml:"enabled"` - Required bool `yaml:"required"` - TimestampWindow int64 `yaml:"timestamp_window"` - AllowedNpubsRead []string `yaml:"allowed_npubs_read"` // npub format only (bech32) - normalized to hex internally - AllowedNpubsWrite []string `yaml:"allowed_npubs_write"` // npub format only (bech32) - normalized to hex internally - SkipMethods []string `yaml:"skip_methods"` + Read AuthOperationConfig `yaml:"read"` + Write AuthOperationConfig `yaml:"write"` + TimestampWindow int64 `yaml:"timestamp_window"` + SkipMethods []string `yaml:"skip_methods"` +} + +// AuthOperationConfig configures auth for a specific operation type (read or write). +type AuthOperationConfig struct { + Enabled bool `yaml:"enabled"` // false = no auth required, true = auth required + AllowedNpubs []string `yaml:"allowed_npubs"` // npub format only - normalized to hex internally + // If enabled=false: no auth, allow all + // If enabled=true && allowed_npubs=[]: auth required, any valid signature accepted + // If enabled=true && allowed_npubs=[...]: auth required, only whitelisted npubs } // RateLimitConfig holds rate limiting configuration. @@ -111,8 +118,14 @@ func Default() *Config { Path: "relay.db", }, Auth: AuthConfig{ - Enabled: false, - Required: false, + Read: AuthOperationConfig{ + Enabled: false, + AllowedNpubs: nil, + }, + Write: AuthOperationConfig{ + Enabled: false, + AllowedNpubs: nil, + }, TimestampWindow: 60, }, RateLimit: RateLimitConfig{ @@ -184,15 +197,15 @@ func normalizeNpubs(cfg *Config) error { var err error // Normalize read allowlist - cfg.Auth.AllowedNpubsRead, err = normalizeNpubList(cfg.Auth.AllowedNpubsRead) + cfg.Auth.Read.AllowedNpubs, err = normalizeNpubList(cfg.Auth.Read.AllowedNpubs) if err != nil { - return fmt.Errorf("allowed_npubs_read: %w", err) + return fmt.Errorf("auth.read.allowed_npubs: %w", err) } // Normalize write allowlist - cfg.Auth.AllowedNpubsWrite, err = normalizeNpubList(cfg.Auth.AllowedNpubsWrite) + cfg.Auth.Write.AllowedNpubs, err = normalizeNpubList(cfg.Auth.Write.AllowedNpubs) if err != nil { - return fmt.Errorf("allowed_npubs_write: %w", err) + return fmt.Errorf("auth.write.allowed_npubs: %w", err) } return nil @@ -299,11 +312,17 @@ func applyEnvOverrides(cfg *Config) { } // Auth - if val := os.Getenv("MUXSTR_AUTH_ENABLED"); val != "" { - cfg.Auth.Enabled = parseBool(val) + if val := os.Getenv("MUXSTR_AUTH_READ_ENABLED"); val != "" { + cfg.Auth.Read.Enabled = parseBool(val) + } + if val := os.Getenv("MUXSTR_AUTH_READ_ALLOWED_NPUBS"); val != "" { + cfg.Auth.Read.AllowedNpubs = strings.Split(val, ",") } - if val := os.Getenv("MUXSTR_AUTH_REQUIRED"); val != "" { - cfg.Auth.Required = parseBool(val) + if val := os.Getenv("MUXSTR_AUTH_WRITE_ENABLED"); val != "" { + cfg.Auth.Write.Enabled = parseBool(val) + } + if val := os.Getenv("MUXSTR_AUTH_WRITE_ALLOWED_NPUBS"); val != "" { + cfg.Auth.Write.AllowedNpubs = strings.Split(val, ",") } if val := os.Getenv("MUXSTR_AUTH_TIMESTAMP_WINDOW"); val != "" { var n int64 @@ -311,12 +330,6 @@ func applyEnvOverrides(cfg *Config) { cfg.Auth.TimestampWindow = n } } - if val := os.Getenv("MUXSTR_AUTH_ALLOWED_NPUBS_READ"); val != "" { - cfg.Auth.AllowedNpubsRead = strings.Split(val, ",") - } - if val := os.Getenv("MUXSTR_AUTH_ALLOWED_NPUBS_WRITE"); val != "" { - cfg.Auth.AllowedNpubsWrite = strings.Split(val, ",") - } // Rate limit if val := os.Getenv("MUXSTR_RATE_LIMIT_ENABLED"); val != "" { -- cgit v1.2.3