16 KiB
C-Relay Administrator API Implementation Plan
Problem Analysis
Current Issues Identified:
- Schema Mismatch: Storage system (config.c) vs Validation system (request_validator.c) use different column names and values
- Missing API Endpoint: No way to clear auth_rules table for testing
- Configuration Gap: Auth rules enforcement may not be properly enabled
- 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 23455: Configuration Management (Ephemeral)
- Update relay settings, limits, authentication policies
- Standard Mode: Commands in tags
["config_key", "config_value"] - Encrypted Mode: Commands NIP-44 encrypted in content
{"encrypted_tags": "..."} - Content: Descriptive text or encrypted payload
- Security: Optional NIP-44 encryption for sensitive operations
Kind 23456: Auth Rules & System Management (Ephemeral)
- Auth rules: Add/remove/query whitelist/blacklist rules
- System commands: clear rules, status, cache management
- Standard Mode: Commands in tags
- Rule format:
["rule_type", "pattern_type", "pattern_value"] - Query format:
["auth_query", "filter"] - System format:
["system_command", "command_name"]
- Rule format:
- Encrypted Mode: Commands NIP-44 encrypted in content
{"encrypted_tags": "..."} - Content: Action description + optional encrypted payload
- Security: Optional NIP-44 encryption for sensitive operations
Configuration Query Commands (using Kind 23455)
-
List All Configuration Keys (Standard):
{ "kind": 23455, "content": "Discovery query", "tags": [["config_query", "list_all_keys"]] } -
List All Configuration Keys (Encrypted):
{ "kind": 23455, "content": "{\"query\":\"list_config_keys\",\"encrypted_tags\":\"nip44_encrypted_payload\"}", "tags": [] }Encrypted payload contains:
[["config_query", "list_all_keys"]] -
Get Current Configuration (Standard):
{ "kind": 23455, "content": "Config query", "tags": [["config_query", "get_current_config"]] } -
Get Current Configuration (Encrypted):
{ "kind": 23455, "content": "{\"query\":\"get_config\",\"encrypted_tags\":\"nip44_encrypted_payload\"}", "tags": [] }Encrypted payload contains:
[["config_query", "get_current_config"]]
System Management Commands (using Kind 23456)
-
Clear All Auth Rules (Standard):
{ "kind": 23456, "content": "{\"action\":\"clear_all\"}", "tags": [["system_command", "clear_all_auth_rules"]] } -
Clear All Auth Rules (Encrypted):
{ "kind": 23456, "content": "{\"action\":\"clear_all\",\"encrypted_tags\":\"nip44_encrypted_payload\"}", "tags": [] }Encrypted payload contains:
[["system_command", "clear_all_auth_rules"]] -
Query All Auth Rules (Standard):
{ "kind": 23456, "content": "{\"query\":\"list_auth_rules\"}", "tags": [["auth_query", "all"]] } -
Query All Auth Rules (Encrypted):
{ "kind": 23456, "content": "{\"query\":\"list_auth_rules\",\"encrypted_tags\":\"nip44_encrypted_payload\"}", "tags": [] }Encrypted payload contains:
[["auth_query", "all"]] -
Add Blacklist Rule (Standard):
{ "kind": 23456, "content": "{\"action\":\"add\"}", "tags": [["blacklist", "pubkey", "deadbeef1234abcd..."]] } -
Add Blacklist Rule (Encrypted):
{ "kind": 23456, "content": "{\"action\":\"add\",\"encrypted_tags\":\"nip44_encrypted_payload\"}", "tags": [] }Encrypted payload contains:
[["blacklist", "pubkey", "deadbeef1234abcd..."]]
Phase 2: Auth Rules Schema Alignment
Option A: Fix Validator to Match Schema (RECOMMENDED)
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
Option B: Update Schema to Match Validator (NOT RECOMMENDED)
Would require changing schema, migration scripts, and storage logic.
Phase 3: Implementation Priority
High Priority (Critical for blacklist functionality):
- Fix request_validator.c schema mismatch
- Ensure auth_required configuration is enabled
- Update tests to use ephemeral event kinds (23455/23456)
- Test blacklist enforcement
Medium Priority (Enhanced Admin Features):
- Implement NIP-44 Encryption Support:
- Detect empty tags array for Kind 23455/23456 events
- Parse
encrypted_tagsfield from content JSON - Decrypt using admin privkey and relay pubkey
- Process decrypted tags as normal commands
- Add clear_all_auth_rules system command
- Add auth rule query functionality (both standard and encrypted modes)
- Add configuration discovery (list available config keys)
- Enhanced error reporting in admin API
- Conflict resolution (same pubkey in whitelist + blacklist)
Security Priority (NIP-44 Implementation):
- Encryption Detection Logic: Check for empty tags + encrypted_tags field
- Key Pair Management: Use admin private key + relay public key for NIP-44
- Backward Compatibility: Support both standard and encrypted modes
- Error Handling: Graceful fallback if decryption fails
- Performance: Cache decrypted results to avoid repeated decryption
Low Priority (Documentation & Polish):
- Complete README.md API documentation
- Example usage scripts
- 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.
## Configuration Management (Kind 23455 - Ephemeral)
Update relay configuration parameters or query available settings.
**Configuration Update Event:**
```json
{
"kind": 23455,
"content": "Configuration update",
"tags": [
["config_key1", "config_value1"],
["config_key2", "config_value2"]
]
}
List Available Config Keys:
{
"kind": 23455,
"content": "{\"query\":\"list_config_keys\",\"description\":\"Get editable config keys\"}",
"tags": [
["config_query", "list_all_keys"]
]
}
Get Current Configuration:
{
"kind": 23455,
"content": "{\"query\":\"get_config\",\"description\":\"Get current config values\"}",
"tags": [
["config_query", "get_current_config"]
]
}
Auth Rules Management (Kind 23456 - Ephemeral)
Manage whitelist and blacklist rules.
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 textrelay_contact: Contact informationauth_enabled: Enable authentication systemmax_connections: Maximum concurrent connectionspow_min_difficulty: Minimum proof-of-work difficulty- ... (full list of config keys)
Examples
Enable Authentication & Add Blacklist
# 1. Enable auth system
nak event -k 23455 --content "Enable authentication" \
-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": 23455,
"content": "{\"config_keys\": [\"auth_enabled\", \"max_connections\"], \"descriptions\": {\"auth_enabled\": \"Enable whitelist/blacklist rules\"}}",
"tags": [["response_type", "config_keys_list"]]
}]
Current Config Response
["EVENT", "subscription_id", {
"kind": 23455,
"content": "{\"current_config\": {\"auth_enabled\": \"true\", \"max_connections\": \"1000\"}}",
"tags": [["response_type", "current_config"]]
}]
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
- Document API (this file) ✅
- Update to ephemeral event kinds ✅
- Fix request_validator.c schema mismatch
- Update tests to use Kind 23455/23456
- Add auth rule query functionality
- Add configuration discovery feature
- Test blacklist functionality
- Add remaining system commands
Testing Plan
- Fix schema mismatch and test basic blacklist
- Add clear_auth_rules and test table cleanup
- Test whitelist/blacklist conflict scenarios
- Test all admin API commands end-to-end
- 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 23455 or 23456 with empty tags
if ((event->kind == 23455 || 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
- Receive Event: Kind 23455/23456 with admin signature
- Check Mode: Empty tags = encrypted, populated tags = standard
- Decrypt if Needed: Extract and decrypt
encrypted_tagsfrom content - Process Commands: Use decrypted/standard tags for command processing
- Execute: Same logic for both modes after tag extraction
- 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 23455/23456 (Configuration/Auth Rules) 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.