Files
c-relay/admin_spec.md
2025-09-05 14:45:32 -04:00

12 KiB

Ginxsom Admin System - Comprehensive Specification

Overview

The Ginxsom admin system provides both programmatic (API-based) and interactive (web-based) administration capabilities for the Ginxsom Blossom server. The system is designed around Nostr-based authentication and supports multiple administration workflows including first-run setup, ongoing configuration management, and operational monitoring.

Architecture Components

1. Configuration System

  • File-based configuration: Signed Nostr events stored as JSON files following XDG Base Directory specification
  • Database configuration: Key-value pairs stored in SQLite for runtime configuration
  • Interactive setup: Command-line wizard for initial server configuration
  • Manual setup: Scripts for generating signed configuration events

2. Authentication & Authorization

  • Nostr-based auth: All admin operations require valid Nostr event signatures
  • Admin pubkey verification: Only configured admin public keys can perform admin operations
  • Event validation: Full cryptographic verification of Nostr events including structure, signature, and expiration
  • Method-specific authorization: Different event types for different operations (upload, admin, delete, etc.)

3. API System

  • RESTful endpoints: /api/* routes for programmatic administration
  • Command-line testing: Complete test suite using nak and curl
  • JSON responses: Structured data for all admin operations
  • CORS support: Cross-origin requests for web admin interface

4. Web Interface (Future)

  • Single-page application: Self-contained HTML file with inline CSS/JS
  • Real-time monitoring: Statistics and system health dashboards
  • Configuration management: GUI for server settings
  • File management: Browse and manage uploaded blobs

Configuration System Architecture

File-based Configuration (Priority 1)

Location: Follows XDG Base Directory Specification

  • $XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json
  • Falls back to $HOME/.config/ginxsom/ginxsom_config_event.json

Format: Signed Nostr event containing server configuration

{
  "kind": 33333,
  "created_at": 1704067200,
  "tags": [
    ["server_privkey", "server_private_key_hex"],
    ["cdn_origin", "https://cdn.example.com"],
    ["max_file_size", "104857600"],
    ["nip94_enabled", "true"]
  ],
  "content": "Ginxsom server configuration",
  "pubkey": "admin_public_key_hex",
  "id": "event_id_hash",
  "sig": "event_signature"
}

Loading Process:

  1. Check for file-based config at XDG location
  2. Validate Nostr event structure and signature
  3. Extract configuration from event tags
  4. Apply settings to server (database storage)
  5. Fall back to database-only config if file missing/invalid

Database Configuration (Priority 2)

Table: server_config

CREATE TABLE server_config (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL,
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Key Configuration Items:

  • admin_pubkey: Authorized admin public key
  • admin_enabled: Enable/disable admin interface
  • cdn_origin: Base URL for blob access
  • max_file_size: Maximum upload size in bytes
  • nip94_enabled: Enable NIP-94 metadata emission
  • auth_rules_enabled: Enable authentication rules system

Setup Workflows

Interactive Setup (Command Line)

# First-run detection
if [[ ! -f "$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json" ]]; then
    echo "=== Ginxsom First-Time Setup Required ==="
    echo "1. Run interactive setup wizard"
    echo "2. Exit and create config manually"
    read -p "Choice (1/2): " choice
    
    if [[ "$choice" == "1" ]]; then
        ./scripts/setup.sh
    else
        echo "Manual setup: Run ./scripts/generate_config.sh"
        exit 1
    fi
fi

Manual Setup (Script-based)

# Generate configuration event
./scripts/generate_config.sh --admin-key <admin_pubkey> \
    --server-key <server_privkey> \
    --cdn-origin "https://cdn.example.com" \
    --output "$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json"

C Implementation Functions

Configuration Loading

// Get XDG-compliant config file path
int get_config_file_path(char* path, size_t path_size);

// Load and validate config event from file
int load_server_config(const char* config_path);

// Extract config from validated event and apply to server
int apply_config_from_event(cJSON* event);

// Interactive setup runner for first-run
int run_interactive_setup(const char* config_path);

Security Features

  • Server private key stored only in memory (never in database)
  • Config file must be signed Nostr event
  • Full cryptographic validation of config events
  • Admin pubkey verification for all operations

Admin API Specification

Authentication Model

All admin API endpoints (except /api/health) require Nostr authentication:

Authorization Header Format:

Authorization: Nostr <base64-encoded-event>

Required Event Structure:

{
  "kind": 24242,
  "created_at": 1704067200,
  "tags": [
    ["t", "GET"],
    ["expiration", "1704070800"]
  ],
  "content": "admin_request",
  "pubkey": "admin_public_key",
  "id": "event_id",
  "sig": "event_signature"
}

API Endpoints

GET /api/health

Purpose: System health check (no authentication required) Response:

{
  "status": "success",
  "data": {
    "database": "connected",
    "blob_directory": "accessible",
    "server_time": 1704067200,
    "uptime": 3600,
    "disk_usage": {
      "total_bytes": 1073741824,
      "used_bytes": 536870912,
      "available_bytes": 536870912,
      "usage_percent": 50.0
    }
  }
}

GET /api/stats

Purpose: Server statistics and metrics Authentication: Required (admin pubkey) Response:

{
  "status": "success",
  "data": {
    "total_files": 1234,
    "total_bytes": 104857600,
    "total_size_mb": 100.0,
    "unique_uploaders": 56,
    "first_upload": 1693929600,
    "last_upload": 1704067200,
    "avg_file_size": 85049,
    "file_types": {
      "image/png": 45,
      "image/jpeg": 32,
      "application/pdf": 12,
      "other": 8
    }
  }
}

GET /api/config

Purpose: Retrieve current server configuration Authentication: Required (admin pubkey) Response:

{
  "status": "success",
  "data": {
    "cdn_origin": "http://localhost:9001",
    "max_file_size": "104857600",
    "nip94_enabled": "true",
    "auth_rules_enabled": "false",
    "auth_cache_ttl": "300"
  }
}

PUT /api/config

Purpose: Update server configuration Authentication: Required (admin pubkey) Request Body:

{
  "max_file_size": "209715200",
  "nip94_enabled": "true",
  "cdn_origin": "https://cdn.example.com"
}

Response:

{
  "status": "success",
  "message": "Configuration updated successfully",
  "updated_keys": ["max_file_size", "cdn_origin"]
}

GET /api/files

Purpose: List recent files with pagination Authentication: Required (admin pubkey) Parameters:

  • limit (default: 50): Number of files to return
  • offset (default: 0): Pagination offset Response:
{
  "status": "success",
  "data": {
    "files": [
      {
        "sha256": "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553",
        "size": 184292,
        "type": "application/pdf",
        "uploaded_at": 1725105921,
        "uploader_pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
        "filename": "document.pdf",
        "url": "http://localhost:9001/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf"
      }
    ],
    "total": 1234,
    "limit": 50,
    "offset": 0
  }
}

Implementation Status

Completed Components

  1. Database-based configuration loading - Implemented in main.c
  2. Admin API authentication system - Implemented in admin_api.c
  3. Nostr event validation - Full cryptographic verification
  4. Admin pubkey verification - Database-backed authorization
  5. Basic API endpoints - Health, stats, config, files

Recently Completed Components

  1. File-based configuration system - Fully implemented in main.c with XDG compliance
  2. Interactive setup wizard - Complete shell script with guided setup process (scripts/setup.sh)
  3. Manual config generation - Full-featured command-line config generator (scripts/generate_config.sh)
  4. Testing infrastructure - Comprehensive admin API test suite (scripts/test_admin.sh)
  5. Documentation system - Complete setup and usage documentation (scripts/README.md)

📋 Planned Components

  1. Web admin interface - Single-page HTML application
  2. Enhanced monitoring - Real-time statistics dashboard
  3. Bulk operations - Multi-file management APIs
  4. Configuration validation - Advanced config checking
  5. Audit logging - Admin action tracking

Setup Instructions

1. Enable Admin Interface

# Configure admin pubkey and enable interface
sqlite3 db/ginxsom.db << EOF
INSERT OR REPLACE INTO server_config (key, value, description) VALUES
    ('admin_pubkey', 'your_admin_public_key_here', 'Authorized admin public key'),
    ('admin_enabled', 'true', 'Enable admin interface');
EOF

2. Test API Access

# Generate admin authentication event
ADMIN_PRIVKEY="your_admin_private_key"
EVENT=$(nak event -k 24242 -c "admin_request" \
    --tag t="GET" \
    --tag expiration="$(date -d '+1 hour' +%s)" \
    --sec "$ADMIN_PRIVKEY")

# Test admin API
AUTH_HEADER="Nostr $(echo "$EVENT" | base64 -w 0)"
curl -H "Authorization: $AUTH_HEADER" http://localhost:9001/api/stats

3. Configure File-based Setup (Future)

# Create XDG config directory
mkdir -p "$XDG_CONFIG_HOME/ginxsom"

# Generate signed config event
./scripts/generate_config.sh \
    --admin-key "your_admin_pubkey" \
    --server-key "generated_server_privkey" \
    --output "$XDG_CONFIG_HOME/ginxsom/ginxsom_config_event.json"

Security Considerations

Authentication Security

  • Event expiration: All admin events must include expiration timestamps
  • Signature validation: Full secp256k1 cryptographic verification
  • Replay protection: Event IDs tracked to prevent reuse
  • Admin key rotation: Support for updating admin pubkeys

Configuration Security

  • File permissions: Config files should be readable only by server user
  • Private key handling: Server private keys never stored in database
  • Config validation: All configuration changes validated before application
  • Backup verification: Config events cryptographically verifiable

Operational Security

  • Access logging: All admin operations logged with timestamps
  • Rate limiting: API endpoints protected against abuse
  • Input validation: All user input sanitized and validated
  • Database security: Prepared statements prevent SQL injection

Future Enhancements

1. Web Admin Interface

  • Self-contained HTML file with inline CSS/JavaScript
  • Real-time monitoring dashboards
  • Visual configuration management
  • File upload/management interface

2. Advanced Monitoring

  • Performance metrics collection
  • Alert system for critical events
  • Historical data trending
  • Resource usage tracking

3. Multi-admin Support

  • Multiple authorized admin pubkeys
  • Role-based permissions (read-only vs full admin)
  • Admin action audit trails
  • Delegation capabilities

4. Integration Features

  • Nostr relay integration for admin events
  • Webhook notifications for admin actions
  • External authentication providers
  • API key management for programmatic access

This specification represents the current understanding and planned development of the Ginxsom admin system, focusing on security, usability, and maintainability.