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/auth/README.md | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) (limited to 'internal/auth/README.md') diff --git a/internal/auth/README.md b/internal/auth/README.md index 366e110..de37010 100644 --- a/internal/auth/README.md +++ b/internal/auth/README.md @@ -142,8 +142,15 @@ import ( // Create auth options authOpts := &auth.InterceptorOptions{ + Read: auth.OperationAuthConfig{ + Enabled: true, // Require auth for reads + AllowedNpubs: nil, // Accept any valid signature + }, + Write: auth.OperationAuthConfig{ + Enabled: true, + AllowedNpubs: []string{"hex-pubkey-1", "hex-pubkey-2"}, // Whitelist + }, TimestampWindow: 60, // Accept events within 60 seconds - Required: true, // Reject unauthenticated requests } // Create gRPC server with interceptors @@ -206,23 +213,25 @@ authOpts := &auth.InterceptorOptions{ ### InterceptorOptions +- **`Read`**: Authentication config for read operations (Subscribe, QueryEvents, CountEvents) + - **`Enabled`**: false = no auth (allow all), true = auth required + - **`AllowedNpubs`**: Optional whitelist (hex format, normalized from npub in config) + - If `Enabled=false`: no auth required + - If `Enabled=true && AllowedNpubs=[]`: auth required, any valid signature accepted + - If `Enabled=true && AllowedNpubs=[...]`: auth required, only whitelisted npubs accepted + +- **`Write`**: Authentication config for write operations (PublishEvent, PublishBatch) + - Same structure as `Read` + - **`TimestampWindow`**: Maximum age of events in seconds (default: 60) -- **`Required`**: Whether to reject unauthenticated requests (default: false) - **`ValidatePayload`**: Whether to verify payload hash when present (default: false) -- **`AllowedNpubsRead`**: Optional whitelist of allowed pubkeys for read operations (nil = allow all) - - Config accepts npub format only (human-readable bech32) - - Automatically normalized to hex format (computer-readable) at config load time - - Controls access to Query, Get, List, Subscribe, and other read methods -- **`AllowedNpubsWrite`**: Optional whitelist of allowed pubkeys for write operations (nil = allow all) - - Config accepts npub format only (human-readable bech32) - - Automatically normalized to hex format (computer-readable) at config load time - - Controls access to Publish, Delete, Create, Update, and other write methods +- **`SkipMethods`**: List of methods that bypass auth (e.g., health checks) **Access Control Patterns:** -- **Public relay**: Set `AllowedNpubsWrite` (only some can publish), leave `AllowedNpubsRead` empty (everyone can read) -- **Private relay**: Set both lists (restricted read and write access) -- **Open relay**: Leave both empty (everyone can read and write) -- **Read-only relay**: Set `AllowedNpubsRead`, block all writes +- **Public relay**: `Read.Enabled=false`, `Write.Enabled=true` with whitelist +- **Private relay**: Both `Enabled=true` with whitelists +- **Open relay**: Both `Enabled=false` +- **Authenticated reads, open writes**: `Read.Enabled=true`, `Write.Enabled=false` ### NostrCredentials Options -- cgit v1.2.3