Files
c-relay/docs/admin_api_plan.md
2025-09-30 05:32:23 -04:00

14 KiB

C-Relay Administrator API Implementation Plan

Problem Analysis

Current Issues Identified:

  1. Schema Mismatch: Storage system (config.c) vs Validation system (request_validator.c) use different column names and values
  2. Missing API Endpoint: No way to clear auth_rules table for testing
  3. Configuration Gap: Auth rules enforcement may not be properly enabled
  4. Documentation Gap: Admin API commands not documented

Root Cause: Auth Rules Schema Inconsistency

Current Schema (sql_schema.h lines 140-150):

CREATE TABLE auth_rules (
    rule_type TEXT CHECK (rule_type IN ('whitelist', 'blacklist')),
    pattern_type TEXT CHECK (pattern_type IN ('pubkey', 'hash')),  
    pattern_value TEXT,
    action TEXT CHECK (action IN ('allow', 'deny')),
    active INTEGER DEFAULT 1
);

Storage Implementation (config.c):

  • Stores: rule_type='blacklist', pattern_type='pubkey', pattern_value='hex', action='allow'

Validation Implementation (request_validator.c):

  • Queries: rule_type='pubkey_blacklist', rule_target='hex', operation='event', enabled=1

MISMATCH: Validator looks for non-existent columns and wrong rule_type values!

Proposed Solution Architecture

Phase 1: API Documentation & Standardization

Admin API Commands (via WebSocket with admin private key)

Kind 23456: Unified Admin API (Ephemeral)

  • Configuration management: Update relay settings, limits, authentication policies
  • Auth rules: Add/remove/query whitelist/blacklist rules
  • System commands: clear rules, status, cache management
  • Unified Format: All commands use NIP-44 encrypted content with ["p", "relay_pubkey"] tags
  • Command Types:
    • Configuration: ["config_key", "config_value"]
    • Auth rules: ["rule_type", "pattern_type", "pattern_value"]
    • Queries: ["auth_query", "filter"] or ["system_command", "command_name"]
  • Security: All admin commands use NIP-44 encryption for privacy and security

Configuration Commands (using Kind 23456)

  1. Update Configuration:

    {
      "kind": 23456,
      "content": "base64_nip44_encrypted_command_array",
      "tags": [["p", "relay_pubkey"]]
    }
    

    Encrypted content contains: ["relay_description", "My Relay"]

  2. Query System Status:

    {
      "kind": 23456,
      "content": "base64_nip44_encrypted_command_array",
      "tags": [["p", "relay_pubkey"]]
    }
    

    Encrypted content contains: ["system_command", "system_status"]

Auth Rules and System Commands (using Kind 23456)

  1. Clear All Auth Rules:

    {
      "kind": 23456,
      "content": "base64_nip44_encrypted_command_array",
      "tags": [["p", "relay_pubkey"]]
    }
    

    Encrypted content contains: ["system_command", "clear_all_auth_rules"]

  2. Query All Auth Rules:

    {
      "kind": 23456,
      "content": "base64_nip44_encrypted_command_array",
      "tags": [["p", "relay_pubkey"]]
    }
    

    Encrypted content contains: ["auth_query", "all"]

  3. Add Blacklist Rule:

    {
      "kind": 23456,
      "content": "base64_nip44_encrypted_command_array",
      "tags": [["p", "relay_pubkey"]]
    }
    

    Encrypted content contains: ["blacklist", "pubkey", "deadbeef1234abcd..."]

Phase 2: Auth Rules Schema Alignment

Update request_validator.c:

-- OLD (broken):
WHERE rule_type = 'pubkey_blacklist' AND rule_target = ? AND operation = ? AND enabled = 1

-- NEW (correct):
WHERE rule_type = 'blacklist' AND pattern_type = 'pubkey' AND pattern_value = ? AND active = 1

Benefits:

  • Matches actual database schema
  • Simpler rule_type values ('blacklist' vs 'pubkey_blacklist')
  • Uses existing columns (pattern_value vs rule_target)
  • Consistent with storage implementation

Would require changing schema, migration scripts, and storage logic.

Phase 3: Implementation Priority

High Priority (Critical for blacklist functionality):

  1. Fix request_validator.c schema mismatch
  2. Ensure auth_required configuration is enabled
  3. Update tests to use unified ephemeral event kind (23456)
  4. Test blacklist enforcement

Medium Priority (Enhanced Admin Features):

  1. Implement NIP-44 Encryption Support:
    • Detect NIP-44 encrypted content for Kind 23456 events
    • Parse encrypted_tags field from content JSON
    • Decrypt using admin privkey and relay pubkey
    • Process decrypted tags as normal commands
  2. Add clear_all_auth_rules system command
  3. Add auth rule query functionality (both standard and encrypted modes)
  4. Add configuration discovery (list available config keys)
  5. Enhanced error reporting in admin API
  6. Conflict resolution (same pubkey in whitelist + blacklist)

Security Priority (NIP-44 Implementation):

  1. Encryption Detection Logic: Check for empty tags + encrypted_tags field
  2. Key Pair Management: Use admin private key + relay public key for NIP-44
  3. Backward Compatibility: Support both standard and encrypted modes
  4. Error Handling: Graceful fallback if decryption fails
  5. Performance: Cache decrypted results to avoid repeated decryption

Low Priority (Documentation & Polish):

  1. Complete README.md API documentation
  2. Example usage scripts
  3. Admin client tools

Phase 4: Expected API Structure

README.md Documentation Format:

# C-Relay Administrator API

## Authentication
All admin commands require signing with the admin private key generated during first startup.

## Unified Admin API (Kind 23456 - Ephemeral)
Update relay configuration parameters or query available settings.

**Configuration Update Event:**
```json
{
  "kind": 23456,
  "content": "base64_nip44_encrypted_command_array",
  "tags": [["p", "relay_pubkey"]]
}

Encrypted content contains: ["relay_description", "My Relay Description"]

Auth Rules Management:

Add Rule Event:

{
  "kind": 23456,
  "content": "{\"action\":\"add\",\"description\":\"Block malicious user\"}",
  "tags": [
    ["blacklist", "pubkey", "deadbeef1234..."]
  ]
}

Remove Rule Event:

{
  "kind": 23456,
  "content": "{\"action\":\"remove\",\"description\":\"Unblock user\"}",
  "tags": [
    ["blacklist", "pubkey", "deadbeef1234..."]
  ]
}

Query All Auth Rules:

{
  "kind": 23456,
  "content": "{\"query\":\"list_auth_rules\",\"description\":\"Get all rules\"}",
  "tags": [
    ["auth_query", "all"]
  ]
}

Query Whitelist Rules Only:

{
  "kind": 23456,
  "content": "{\"query\":\"list_auth_rules\",\"description\":\"Get whitelist\"}",
  "tags": [
    ["auth_query", "whitelist"]
  ]
}

Check Specific Pattern:

{
  "kind": 23456,
  "content": "{\"query\":\"check_pattern\",\"description\":\"Check if pattern exists\"}",
  "tags": [
    ["auth_query", "pattern", "deadbeef1234..."]
  ]
}

System Management (Kind 23456 - Ephemeral)

System administration commands using the same kind as auth rules.

Clear All Auth Rules:

{
  "kind": 23456,
  "content": "{\"action\":\"clear_all\",\"description\":\"Clear all auth rules\"}",
  "tags": [
    ["system_command", "clear_all_auth_rules"]
  ]
}

System Status:

{
  "kind": 23456,
  "content": "{\"action\":\"system_status\",\"description\":\"Get system status\"}",
  "tags": [
    ["system_command", "system_status"]
  ]
}

Response Format

All admin commands return JSON responses via WebSocket:

Success Response:

["OK", "event_id", true, "success_message"]

Error Response:

["OK", "event_id", false, "error_message"]

Configuration Keys

  • relay_description: Relay description text
  • relay_contact: Contact information
  • auth_enabled: Enable authentication system
  • max_connections: Maximum concurrent connections
  • pow_min_difficulty: Minimum proof-of-work difficulty
  • ... (full list of config keys)

Examples

Enable Authentication & Add Blacklist

# 1. Enable auth system
nak event -k 23456 --content "base64_nip44_encrypted_command" \
  -t "auth_enabled=true" \
  --sec $ADMIN_PRIVKEY | nak event ws://localhost:8888

# 2. Add user to blacklist
nak event -k 23456 --content '{"action":"add","description":"Spam user"}' \
  -t "blacklist=pubkey;$SPAM_USER_PUBKEY" \
  --sec $ADMIN_PRIVKEY | nak event ws://localhost:8888

# 3. Query all auth rules
nak event -k 23456 --content '{"query":"list_auth_rules","description":"Get all rules"}' \
  -t "auth_query=all" \
  --sec $ADMIN_PRIVKEY | nak event ws://localhost:8888

# 4. Clear all rules for testing
nak event -k 23456 --content '{"action":"clear_all","description":"Clear all rules"}' \
  -t "system_command=clear_all_auth_rules" \
  --sec $ADMIN_PRIVKEY | nak event ws://localhost:8888

Expected Response Formats

Configuration Query Response

["EVENT", "subscription_id", {
  "kind": 23457,
  "content": "base64_nip44_encrypted_response",
  "tags": [["p", "admin_pubkey"]]
}]

Current Config Response

["EVENT", "subscription_id", {
  "kind": 23457,
  "content": "base64_nip44_encrypted_response",
  "tags": [["p", "admin_pubkey"]]
}]

Auth Rules Query Response

["EVENT", "subscription_id", {
  "kind": 23456,
  "content": "{\"auth_rules\": [{\"rule_type\": \"blacklist\", \"pattern_type\": \"pubkey\", \"pattern_value\": \"deadbeef...\"}, {\"rule_type\": \"whitelist\", \"pattern_type\": \"pubkey\", \"pattern_value\": \"cafebabe...\"}]}",
  "tags": [["response_type", "auth_rules_list"], ["query_type", "all"]]
}]

Pattern Check Response

["EVENT", "subscription_id", {
  "kind": 23456,
  "content": "{\"pattern_exists\": true, \"rule_type\": \"blacklist\", \"pattern_value\": \"deadbeef...\"}",
  "tags": [["response_type", "pattern_check"], ["pattern", "deadbeef..."]]
}]

Implementation Steps

  1. Document API (this file)
  2. Update to ephemeral event kinds
  3. Fix request_validator.c schema mismatch
  4. Update tests to use unified Kind 23456
  5. Add auth rule query functionality
  6. Add configuration discovery feature
  7. Test blacklist functionality
  8. Add remaining system commands

Testing Plan

  1. Fix schema mismatch and test basic blacklist
  2. Add clear_auth_rules and test table cleanup
  3. Test whitelist/blacklist conflict scenarios
  4. Test all admin API commands end-to-end
  5. Update integration tests

This plan addresses the immediate blacklist issue while establishing a comprehensive admin API framework for future expansion.

NIP-44 Encryption Implementation Details

Server-Side Detection Logic

// In admin event processing function
bool is_encrypted_command(struct nostr_event *event) {
    // Check if Kind 23456 with NIP-44 encrypted content
    if (event->kind == 23456 &&
        event->tags_count == 0) {
        return true;
    }
    return false;
}

cJSON *decrypt_admin_tags(struct nostr_event *event) {
    cJSON *content_json = cJSON_Parse(event->content);
    if (!content_json) return NULL;
    
    cJSON *encrypted_tags = cJSON_GetObjectItem(content_json, "encrypted_tags");
    if (!encrypted_tags) {
        cJSON_Delete(content_json);
        return NULL;
    }
    
    // Decrypt using NIP-44 with admin pubkey and relay privkey
    char *decrypted = nip44_decrypt(
        cJSON_GetStringValue(encrypted_tags),
        admin_pubkey,           // Shared secret with admin
        relay_private_key       // Our private key
    );
    
    cJSON *decrypted_tags = cJSON_Parse(decrypted);
    free(decrypted);
    cJSON_Delete(content_json);
    
    return decrypted_tags; // Returns tag array: [["key1", "val1"], ["key2", "val2"]]
}

Admin Event Processing Flow

  1. Receive Event: Kind 23456 with admin signature
  2. Check Mode: Empty tags = encrypted, populated tags = standard
  3. Decrypt if Needed: Extract and decrypt encrypted_tags from content
  4. Process Commands: Use decrypted/standard tags for command processing
  5. Execute: Same logic for both modes after tag extraction
  6. Respond: Standard response format (optionally encrypt response)

Security Benefits

  • Command Privacy: Admin operations invisible in event tags
  • Replay Protection: NIP-44 includes timestamp/randomness
  • Key Management: Uses existing admin/relay key pair
  • Backward Compatible: Standard mode still works
  • Performance: Only decrypt when needed (empty tags detection)

NIP-44 Library Integration

The relay will need to integrate a NIP-44 encryption/decryption library:

// Required NIP-44 functions
char* nip44_encrypt(const char* plaintext, const char* sender_privkey, const char* recipient_pubkey);
char* nip44_decrypt(const char* ciphertext, const char* recipient_privkey, const char* sender_pubkey);

Implementation Priority (Updated)

Phase 1: Core Infrastructure (Complete)

  • Event-based admin authentication system
  • Kind 23456 (Unified Admin API) processing
  • Basic configuration parameter updates
  • Auth rule add/remove/clear functionality
  • Updated to ephemeral event kinds
  • Designed NIP-44 encryption support

Phase 2: NIP-44 Encryption Support (Next Priority)

  • Add NIP-44 library dependency to project
  • Implement encryption detection logic (is_encrypted_command())
  • Add decrypt_admin_tags() function with NIP-44 support
  • Update admin command processing to handle both modes
  • Test encrypted admin commands end-to-end

Phase 3: Enhanced Features

  • Auth rule query functionality (both standard and encrypted modes)
  • Configuration discovery API (list available config keys)
  • Enhanced error messages with encryption status
  • Performance optimization (caching, async decrypt)

Phase 4: Schema Fixes (Critical)

  • Fix request_validator.c schema mismatch
  • Enable blacklist enforcement with encrypted commands
  • Update tests to use both standard and encrypted modes

This enhanced admin API provides enterprise-grade security while maintaining ease of use for basic operations.