# Authentication API Documentation ## Authentication Flow and Order of Operations ### Authentication Flow Diagram ``` ┌─────────────────────┐ │ Request Received │ └──────────┬──────────┘ │ ▼ ┌─────────────┐ ╔═══════════════════╗ │ Input Valid?├─No─►║ REJECT: Invalid ║ └──────┬──────┘ ║ Input (~1μs) ║ │Yes ╚═══════════════════╝ ▼ ┌─────────────┐ ╔═══════════════════╗ │System Init? ├─No─►║ REJECT: Not ║ └──────┬──────┘ ║ Initialized ║ │Yes ╚═══════════════════╝ ▼ ┌─────────────┐ │Auth Header? │ └──────┬──────┘ │Yes ▼ ┌─────────────────────┐ ┌─────────────┐ No │ │ │Parse Header ├────────────┤ Skip Nostr │ └──────┬──────┘ │ Validation │ │ │ │ ▼ └──────────┬──────────┘ ┌─────────────┐ ╔═══════════════════╗ │ │Valid Base64?├─No─►║ REJECT: Malformed ║ │ └──────┬──────┘ ║ Header (~10μs) ║ │ │Yes ╚═══════════════════╝ │ ▼ │ ┌─────────────┐ ╔═══════════════════╗ │ │Valid JSON? ├─No─►║ REJECT: Invalid ║ │ └──────┬──────┘ ║ JSON (~50μs) ║ │ │Yes ╚═══════════════════╝ │ ▼ │ ┌─────────────┐ ╔═══════════════════╗ │ │Valid Struct?├─No─►║ REJECT: Invalid ║ │ └──────┬──────┘ ║ Structure (~100μs)║ │ │Yes ╚═══════════════════╝ │ ▼ │ ┌─────────────┐ ╔═══════════════════╗ │ │Event Kind? │ ║ ║ │ └──────┬──────┘ ║ DUAL AUTH MODES ║ │ │ ╚═══════════════════╝ │ ▼ │ ┌─────────────────────────────────────────────────────┐ │ │ ▼ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Kind │ │ Kind │ │ Other │ │ Invalid │ │ 22242 │ │ 24242 │ │ Kinds │ │ Kind │ │ (NIP-42) │ │(Blossom) │ │ (Skip) │ │(Reject) │ └─────┬────┘ └─────┬────┘ └─────┬────┘ └─────┬────┘ │ │ │ │ ▼ │ ▼ ▼ ┌──────────┐ │ ┌──────────┐ ╔═══════════════════╗ │ NIP-42 │ │ │ Skip │ ║ REJECT: Invalid ║ │Challenge │ │ │ Nostr │ ║ Event Kind ║ │Validate │ │ │Validate │ ╚═══════════════════╝ │(~500μs) │ │ └─────┬────┘ │ └─────┬────┘ │ │ │ │ │ ▼ │ │ │ ┌──────────┐ │ │ │ │ Extract │ │ │ │ │ Context │ │ │ │ └─────┬────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ┌────────────────────────────────────────────────────────────┐ │ ECDSA SIGNATURE VERIFICATION │ │ (~2ms) │ └───────────────────────────┬────────────────────────────────┘ │Yes ▼ │ ┌─────────────────┐ ╔═══════════════════╗ │Operation Match? │No ║ REJECT: Unauth. ║ │(Kind 24242 only)├──►║ Operation (~200μs)║ └─────────┬───────┘ ╚═══════════════════╝ │Yes/Skip(Kind 22242) ▼ │ ┌─────────────────┐ ╔═══════════════════╗ │ │Event Expired? │Yes║ REJECT: Expired ║ │ └─────────┬───────┘ ║ Event (~50μs) ║ │ │No ╚═══════════════════╝ │ ▼ │ ┌─────────────────┐ │ │Extract Pubkey │ │ │& Auth Context │ │ └─────────┬───────┘ │ │ │ ▼◄───────────────────────────────────────┘ ┌─────────────────┐ ╔═══════════════════╗ │Auth Rules │ No ║ ALLOW: Rules ║ │Enabled? ├────►║ Disabled ║ └─────────┬───────┘ ╚═══════════════════╝ │Yes ▼ ┌─────────────────┐ │Generate Cache │ │Key (SHA-256) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ ╔═══════════════════╗ │Cache Hit? │ Yes ║ RETURN: Cached ║ │(~100μs lookup) ├────►║ Decision (~100μs) ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ╔═══════════════════════════════════════╗ ║ RULE EVALUATION ENGINE ║ ║ (Priority Order) ║ ╚═══════════════════════════════════════╝ │ ▼ ┌─────────────────┐ ╔═══════════════════╗ │1. Pubkey │ Yes ║ DENY: Pubkey ║ │ Blacklisted? ├────►║ Blocked ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │2. Hash │ Yes ║ DENY: Hash ║ │ Blacklisted? ├────►║ Blocked ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │3. MIME Type │ Yes ║ DENY: MIME ║ │ Blacklisted? ├────►║ Blocked ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │4. Size Limit │ Yes ║ DENY: File ║ │ Exceeded? ├────►║ Too Large ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │5. Pubkey │ Yes ║ ALLOW: Pubkey ║ │ Whitelisted? ├────►║ Whitelisted ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │6. MIME Type │ Yes ║ ALLOW: MIME ║ │ Whitelisted? ├────►║ Whitelisted ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ┌─────────────────┐ ╔═══════════════════╗ │Whitelist Rules │ Yes ║ DENY: Not in ║ │Exist? ├────►║ Whitelist ║ └─────────┬───────┘ ╚═══════════════════╝ │No ▼ ╔═══════════════════╗ ║ ALLOW: Default ║ ║ Allow Policy ║ ╚═══════════════════╝ │ ▼ ┌─────────────────┐ │ Cache Decision │ │ (5min TTL) │ └─────────┬───────┘ │ ▼ ┌─────────────────┐ │ Return Result │ │ to Application │ └─────────────────┘ ``` ### Authentication Flow (Mermaid) ```mermaid flowchart TD A[Request Received] --> B{Input Valid?} B -->|No| R1[REJECT: Invalid Input ~1μs] B -->|Yes| C{System Init?} C -->|No| R2[REJECT: Not Initialized] C -->|Yes| D{Auth Header?} D -->|No| SKIP[Skip Nostr Validation] D -->|Yes| E{Valid Base64?} E -->|No| R3[REJECT: Malformed Header ~10μs] E -->|Yes| F{Valid JSON?} F -->|No| R4[REJECT: Invalid JSON ~50μs] F -->|Yes| G{Valid Struct?} G -->|No| R5[REJECT: Invalid Structure ~100μs] G -->|Yes| H{Event Kind?} %% Event Kind Branching H --> I[Kind 22242
NIP-42] H --> J[Kind 24242
Blossom] H --> K[Other Kinds
Skip] H --> L[Invalid Kind] L --> R6[REJECT: Invalid Event Kind] %% NIP-42 Path I --> M[NIP-42 Challenge
Validation ~500μs] M --> N[ECDSA Signature
Verification ~2ms] %% Blossom Path J --> N %% Skip Path K --> SKIP SKIP --> O[Extract Context] O --> N %% Signature Verification N -->|No| R7[REJECT: Invalid Signature ~2ms] N -->|Yes| P{Operation Match?
Kind 24242 only} P -->|No| R8[REJECT: Unauthorized Operation ~200μs] P -->|Yes/Skip 22242| Q{Event Expired?} Q -->|Yes| R9[REJECT: Expired Event ~50μs] Q -->|No| S[Extract Pubkey & Auth Context] %% Rules Engine S --> T{Auth Rules Enabled?} T -->|No| ALLOW1[ALLOW: Rules Disabled] T -->|Yes| U[Generate Cache Key SHA-256] U --> V{Cache Hit?} V -->|Yes| CACHED[RETURN: Cached Decision ~100μs] V -->|No| W[RULE EVALUATION ENGINE
Priority Order] %% Rule Checks W --> X1{1. Pubkey Blacklisted?} X1 -->|Yes| DENY1[DENY: Pubkey Blocked] X1 -->|No| X2{2. Hash Blacklisted?} X2 -->|Yes| DENY2[DENY: Hash Blocked] X2 -->|No| X3{3. MIME Blacklisted?} X3 -->|Yes| DENY3[DENY: MIME Blocked] X3 -->|No| X4{4. Size Limit Exceeded?} X4 -->|Yes| DENY4[DENY: File Too Large] X4 -->|No| X5{5. Pubkey Whitelisted?} X5 -->|Yes| ALLOW2[ALLOW: Pubkey Whitelisted] X5 -->|No| X6{6. MIME Whitelisted?} X6 -->|Yes| ALLOW3[ALLOW: MIME Whitelisted] X6 -->|No| X7{Whitelist Rules Exist?} X7 -->|Yes| DENY5[DENY: Not in Whitelist] X7 -->|No| ALLOW4[ALLOW: Default Policy] %% Final Steps ALLOW2 --> CACHE[Cache Decision 5min TTL] ALLOW3 --> CACHE ALLOW4 --> CACHE DENY1 --> CACHE DENY2 --> CACHE DENY3 --> CACHE DENY4 --> CACHE DENY5 --> CACHE CACHE --> RESULT[Return Result to Application] %% Styling classDef rejectBox fill:#ff4444,stroke:#ffffff,color:#ffffff classDef allowBox fill:#44ff44,stroke:#ffffff,color:#000000 classDef processBox fill:#4444ff,stroke:#ffffff,color:#ffffff classDef decisionBox fill:#ffff44,stroke:#000000,color:#000000 class R1,R2,R3,R4,R5,R6,R7,R8,R9,DENY1,DENY2,DENY3,DENY4,DENY5 rejectBox class ALLOW1,ALLOW2,ALLOW3,ALLOW4,CACHED allowBox class A,M,N,S,U,W,CACHE,RESULT,SKIP,O processBox class B,C,D,E,F,G,H,P,Q,T,V,X1,X2,X3,X4,X5,X6,X7 decisionBox ``` ### Performance Timeline (ASCII) ``` Fast Path (Cache Hit) - Total: ~101μs ┌─────┬─────────────────────────────────────────────────────────────────┬──────┐ │ 1μs │ 100μs Cache Lookup │ 1μs │ └─────┴─────────────────────────────────────────────────────────────────┴──────┘ Input │ │ Return Valid │ SQLite SELECT │ Result Typical Path (Valid Request) - Total: ~2.4ms ┌──┬───┬────┬─────────────────────────┬────────┬────┬──┐ │1μ│50μ│100μ│ 2000μs │ 200μs │100μ│1μ│ └──┴───┴────┴─────────────────────────┴────────┴────┴──┘ │ │ │ │ │ │ │ │ │ │ │ ECDSA Signature │ Rule │Cache│Return │ │ │ │ Verification │ Eval │Store│Result │ │ │ │ (Most Expensive) │ │ │ │ │ │ │ │ JSON Parse │ Header Parse Input Validation Worst Case (Full Validation) - Total: ~2.7ms ┌──┬───┬────┬─────────────────────────┬─────────┬────┬──┐ │1μ│50μ│100μ│ 2000μs │ 500μs │100μ│1μ│ └──┴───┴────┴─────────────────────────┴─────────┴────┴──┘ │ All 6 Rule Checks (Multiple DB Queries) ``` ### Dual Authentication Architecture The system supports **two authentication modes** that can work independently or together: #### **NIP-42 Authentication (Kind 22242)** - **Purpose**: Client identity authentication ("who you are") - **Use Case**: Relay client authentication, WebSocket connections - **Event Structure**: Contains `relay` URL and `challenge` tags - **Flow**: Challenge/response pattern with relay-generated challenges - **Validation**: Verifies client identity against relay URL and challenge - **Database Storage**: Client sessions and challenge tracking #### **Blossom Protocol Authentication (Kind 24242)** - **Purpose**: Operation authorization ("what you can do") - **Use Case**: File upload/delete/list operations - **Event Structure**: Contains operation tag `t=upload|delete|list` and content hash `x=hash` - **Flow**: Direct operation authorization with expiration - **Validation**: Verifies operation permissions and content integrity - **Database Storage**: Operation-specific authentication rules #### **Integration Strategy** ``` ┌─────────────────┐ ┌─────────────────┐ │ NIP-42 Auth │ │ Blossom Auth │ │ (Kind 22242) │ │ (Kind 24242) │ │ │ │ │ │ Client Identity │ │ Operation Perms │ │ Challenge/Resp │ │ File Operations │ └─────────┬───────┘ └─────────┬───────┘ │ │ └──────┬─────────┬─────┘ │ │ ▼ ▼ ┌─────────────────┐ │ Unified Rules │ │ Engine │ │ │ │ • Pubkey Rules │ │ • Hash Rules │ │ • MIME Rules │ │ • Size Limits │ └─────────────────┘ ``` #### **Event Kind Processing** - **Kind 22242** (NIP-42): Validates against stored challenge + relay URL - **Kind 24242** (Blossom): Validates operation tags + content integrity - **Other Kinds**: Skip Nostr validation, proceed to rule evaluation - **Invalid Kind**: Reject immediately #### **Dual Mode Benefits** - **Backwards Compatibility**: Existing Blossom clients continue working - **Enhanced Security**: NIP-42 provides cryptographic client identity - **Flexible Deployment**: Relays can require either or both methods - **Performance**: Separate validation paths optimize for each use case ### Request Processing Flow (DDoS-Optimized) The authentication system is designed with **performance and DDoS protection** as primary concerns. Here's the exact order of operations: #### Phase 1: Input Validation (Immediate Rejection) 1. **Null Pointer Checks** - Reject malformed requests instantly (lines 122-128) 2. **Initialization Check** - Verify system is properly initialized 3. **Basic Structure Validation** - Ensure required fields are present #### Phase 2: Nostr Event Validation (CPU Intensive) 4. **Authorization Header Parsing** (lines 139-148) - Extract base64-encoded Nostr event from `Authorization: Nostr ` header - Decode base64 to JSON (memory allocation + decoding) - **Early exit**: Invalid base64 or malformed header rejected immediately 5. **JSON Parsing** (lines 150-156) - Parse Nostr event JSON using cJSON - **Early exit**: Invalid JSON rejected before signature verification 6. **Nostr Event Structure Validation** (lines 159-166) - Validate event has required fields (kind, pubkey, sig, etc.) - **Early exit**: Invalid structure rejected before expensive crypto operations 7. **Event Kind Routing** (NEW - Dual Authentication) - **Kind 22242** (NIP-42): Route to NIP-42 challenge validation - **Kind 24242** (Blossom): Route to Blossom operation validation - **Other Kinds**: Skip Nostr validation, proceed to rules - **Invalid Kind**: Reject immediately 8. **NIP-42 Challenge Validation** (Kind 22242 Only) - Validate `relay` tag matches configured relay URL - Verify `challenge` tag exists and matches stored challenge - Check challenge expiration and single-use constraints - **Performance**: ~500μs additional validation overhead 9. **Cryptographic Signature Verification** (Both Paths) - **Most CPU-intensive operation** - ECDSA signature verification - Validates event authenticity using secp256k1 - **Early exit**: Invalid signatures rejected before database queries 10. **Operation-Specific Validation** (Kind 24242 Only) - Verify event authorizes the requested operation (upload/delete/list) - Check required tags (t=operation, x=hash, expiration) - Validate timestamp and expiration - **Early exit**: Expired or mismatched events rejected 11. **Public Key Extraction** (Both Paths) - Extract validated public key from event for rule evaluation - Store authentication context (NIP-42 vs Blossom) for rule processing #### Phase 3: Authentication Rules (Database Queries) 10. **Rules System Check** (line 191) - Quick config check if authentication rules are enabled - **Early exit**: If disabled, allow request immediately 11. **Cache Lookup** (lines 1051-1054) - Generate SHA-256 cache key from request parameters - Check SQLite cache for previous decision - **Early exit**: Cache hit returns cached decision (5-minute TTL) 12. **Rule Evaluation** (Priority Order - lines 1061-1094): - **a. Pubkey Blacklist** (highest priority) - Immediate denial if matched - **b. Hash Blacklist** - Block specific content hashes - **c. MIME Type Blacklist** - Block dangerous file types - **d. File Size Limits** - Enforce upload size restrictions - **e. Pubkey Whitelist** - Allow specific users (only if not denied above) - **f. MIME Type Whitelist** - Allow specific file types 13. **Whitelist Default Denial** (lines 1097-1121) - If whitelist rules exist but none matched, deny request - Prevents whitelist bypass attacks 14. **Cache Storage** (line 1124) - Store decision in cache for future requests (5-minute TTL) ### DDoS Protection Features #### **Fail-Fast Design** - **Input validation** happens before any expensive operations - **Authorization header parsing** fails fast on malformed data - **JSON parsing** rejects invalid data before signature verification - **Structure validation** happens before cryptographic operations #### **Expensive Operations Last** - **Signature verification** only after structure validation - **Database queries** only after successful Nostr validation - **Cache prioritized** over database queries #### **Caching Strategy** - **SHA-256 cache keys** prevent cache pollution attacks - **5-minute TTL** balances performance with rule changes - **LRU eviction** prevents memory exhaustion - **Per-request caching** includes all parameters (pubkey, operation, hash, MIME, size) #### **Resource Limits** - **JSON parsing** limited to 4KB buffer size - **Cache entries** limited to prevent memory exhaustion - **Database connection pooling** (single connection with proper cleanup) - **String length limits** on all inputs #### **Attack Mitigation** - **Base64 bombs** - Limited decode buffer size (4KB) - **JSON bombs** - cJSON library handles malformed JSON safely - **Cache poisoning** - Cryptographic cache keys prevent collisions - **Rule bypass** - Whitelist default denial prevents unauthorized access - **Replay attacks** - Timestamp and expiration validation - **Hash collision attacks** - Full SHA-256 verification ### Performance Characteristics #### **Best Case** (Cached Decision): 1. Input validation: ~1μs 2. Cache lookup: ~100μs (SQLite SELECT) 3. **Total: ~101μs** #### **Worst Case** (Full Validation + Rule Evaluation): 1. Input validation: ~1μs 2. Base64 decoding: ~50μs 3. JSON parsing: ~100μs 4. Signature verification: ~2000μs (ECDSA) 5. Database queries: ~500μs (6 rule checks) 6. Cache storage: ~100μs 7. **Total: ~2751μs (~2.7ms)** #### **Typical Case** (Valid Request, Rules Enabled): 1. Full validation: ~2200μs 2. Cache miss, 2-3 rule checks: ~200μs 3. **Total: ~2400μs (~2.4ms)** ### Security Order Rationale The rule evaluation order is specifically designed for security: 1. **Blacklists First** - Immediate denial of known bad actors 2. **Resource Limits** - Prevent resource exhaustion attacks 3. **Whitelists Last** - Only allow after passing all security checks 4. **Default Deny** - If whitelists exist but don't match, deny This ensures that even if an attacker bypasses one layer, subsequent layers will catch the attack.