8.5 KiB
8.5 KiB
NIP-42 Authentication Integration Plan
Overview
This document outlines the integration of NIP-42 client-to-relay authentication into the existing ginxsom authentication system. The goal is to support both NIP-42 (kind 22242) and Blossom (kind 24242) authentication methods in a unified system.
Current System Analysis
Existing Authentication Flow
-
Blossom Protocol (kind 24242): Operation-specific authorization
- Tags:
t(method),x(hash),expiration - Purpose: Authorize specific file operations (upload, delete, etc.)
- Location:
validate_nostr_event()inrequest_validator.c:379
- Tags:
-
Rules Engine: Policy-based access control
- Pubkey whitelist/blacklist
- Hash blacklist
- MIME type restrictions
- File size limits
- Location:
evaluate_auth_rules()inrequest_validator.c:1029
Integration Points Identified
- Header Structure: Extend
nostr_request_tto support NIP-42 context - Event Validation: Support both kind 22242 (NIP-42) and 24242 (Blossom)
- Challenge Management: Add challenge generation and storage
- Database Schema: Add challenge storage tables
- Authentication Flow: Support dual authentication modes
NIP-42 Integration Architecture
Dual Authentication Strategy
Client Authentication (NIP-42) → Operation Authorization (Blossom) → Rules Engine
- NIP-42 (kind 22242): Proves client identity to relay
- Blossom (kind 24242): Authorizes specific operations
- Rules Engine: Applies policy-based restrictions
Authentication Flow Options
- NIP-42 Only: Client authenticates identity, all operations allowed by rules
- Blossom Only: Current system - operation-specific authorization
- Dual Mode: NIP-42 identity + Blossom operation authorization
- Rules Only: No cryptographic auth, rules-based access only
Technical Implementation Plan
1. Extend Request Validator Header (request_validator.h)
// Add NIP-42 support structures
typedef struct {
char challenge[256]; // Current challenge for client
time_t challenge_created; // Challenge timestamp
char relay_url[256]; // Relay URL for challenge
int is_authenticated; // NIP-42 auth status
char authenticated_pubkey[65]; // Pubkey from NIP-42 auth
} nostr_nip42_context_t;
// Extend nostr_request_t
typedef struct {
// ... existing fields ...
nostr_nip42_context_t* nip42_context; // NIP-42 authentication context
const char* challenge; // Challenge for this request
} nostr_request_t;
2. Database Schema Extensions
-- NIP-42 challenge storage
CREATE TABLE IF NOT EXISTS nip42_challenges (
challenge_id TEXT PRIMARY KEY,
challenge TEXT NOT NULL,
relay_url TEXT NOT NULL,
created_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
client_ip TEXT
);
-- NIP-42 authentication sessions
CREATE TABLE IF NOT EXISTS nip42_sessions (
session_id TEXT PRIMARY KEY,
pubkey TEXT NOT NULL,
challenge_id TEXT NOT NULL,
authenticated_at INTEGER NOT NULL,
expires_at INTEGER NOT NULL,
client_ip TEXT,
FOREIGN KEY (challenge_id) REFERENCES nip42_challenges(challenge_id)
);
3. Core Functions to Add
// NIP-42 challenge management
int nostr_nip42_generate_server_challenge(char* challenge_out, size_t challenge_size);
int nostr_nip42_store_challenge(const char* challenge, const char* relay_url, const char* client_ip);
int nostr_nip42_verify_challenge_response(const char* auth_header, const char* relay_url, nostr_request_result_t* result);
// Enhanced validation
int validate_nip42_event(struct cJSON* event, const char* expected_challenge, const char* relay_url);
int validate_blossom_event(struct cJSON* event, const char* expected_hash, const char* method);
// Dual authentication support
int nostr_validate_request_dual(const nostr_request_t* request, nostr_request_result_t* result);
4. Enhanced Event Validation
Extend validate_nostr_event() to handle both event kinds:
static int validate_nostr_event(struct cJSON* event, const char* expected_hash, const char* method) {
struct cJSON* kind_json = cJSON_GetObjectItem(event, "kind");
int kind = cJSON_GetNumberValue(kind_json);
switch (kind) {
case 22242: // NIP-42 authentication
return validate_nip42_event(event, expected_hash, method);
case 24242: // Blossom authorization
return validate_blossom_event(event, expected_hash, method);
default:
return NOSTR_ERROR_EVENT_INVALID_KIND;
}
}
5. Ginxsom Integration Points
Main.c Changes
// Add challenge endpoint
if (strcmp(request_method, "GET") == 0 && strstr(request_uri, "/.well-known/nostr/challenge")) {
handle_nip42_challenge_request(response);
return;
}
// Enhanced authentication in existing endpoints
int handle_upload_request(FCGX_Request* request) {
// ... existing code ...
// Check for NIP-42 challenge header
const char* challenge_header = FCGX_GetParam("HTTP_X_NOSTR_CHALLENGE", request->envp);
nostr_request_t nostr_request = {
.operation = "upload",
.auth_header = auth_header,
.resource_hash = file_hash,
.mime_type = content_type,
.file_size = content_length,
.challenge = challenge_header,
.nip42_context = &nip42_ctx
};
}
Configuration Options
New Configuration Keys
-- NIP-42 specific settings
INSERT OR REPLACE INTO auth_config VALUES ('nip42_enabled', 'true');
INSERT OR REPLACE INTO auth_config VALUES ('nip42_challenge_ttl', '600');
INSERT OR REPLACE INTO auth_config VALUES ('nip42_session_ttl', '3600');
INSERT OR REPLACE INTO auth_config VALUES ('auth_mode', 'dual'); -- dual, nip42_only, blossom_only, rules_only
INSERT OR REPLACE INTO auth_config VALUES ('relay_url', 'http://localhost:9001');
Authentication Modes
- dual: NIP-42 + Blossom + Rules (most secure)
- nip42_only: NIP-42 + Rules (client identity required)
- blossom_only: Blossom + Rules (current system)
- rules_only: Rules only (no cryptographic auth)
Testing Strategy
Test Cases to Add
- NIP-42 Challenge Flow: Generate challenge, verify response
- Kind 22242 Validation: Test NIP-42 event structure and signatures
- Dual Authentication: NIP-42 auth + Blossom authorization
- Challenge Expiration: Test challenge TTL and cleanup
- Session Management: Test session creation and expiration
- Mixed Mode Testing: Different auth modes in same server
- Error Handling: Invalid challenges, expired sessions, etc.
Test File Structure
tests/
├── nip42_basic_test.sh # Basic NIP-42 functionality
├── nip42_challenge_test.sh # Challenge generation and validation
├── nip42_dual_auth_test.sh # Dual authentication mode
└── nip42_integration_test.sh # Full integration testing
Build System Integration
Files to Update
- build.sh: Already includes
nip042.cin sources - nostr_core.h: Already includes
nip042.h - Makefile: May need to link additional NIP-42 functions
Implementation Order
- ✅ Analysis Complete: Current system understood
- Extend Headers: Add NIP-42 structures to request_validator.h
- Database Schema: Add challenge and session tables
- Core Functions: Implement challenge management
- Event Validation: Extend validation for kind 22242
- Request Validation: Update nostr_validate_request()
- Ginxsom Integration: Add challenge endpoints and auth checks
- Build Integration: Ensure NIP-42 is compiled
- Testing: Create comprehensive test suite
- Documentation: Update API documentation
Benefits of This Integration
- Standards Compliance: Full NIP-42 support for Nostr ecosystem compatibility
- Flexible Authentication: Support multiple auth modes based on use case
- Enhanced Security: Dual authentication provides defense in depth
- Backward Compatibility: Existing Blossom auth continues to work
- Future Proof: Ready for Nostr relay ecosystem integration
Migration Path
Phase 1: Basic NIP-42 Support
- Add NIP-42 validation alongside existing system
- No breaking changes to current auth
Phase 2: Enhanced Integration
- Add challenge management and session handling
- Optional dual authentication mode
Phase 3: Full Integration
- Complete NIP-42 relay compatibility
- Advanced session management features
This integration maintains full backward compatibility while adding powerful new authentication capabilities that align with Nostr ecosystem standards.