Files
CyberRanger/identity/claude/classified/RANGERBLOCK_SECURITY_INTEGRATION_PLAN_v2.md
T
ranger c789f2c68d Add complete CyberRanger research archive — 200 files
- 86 modelfiles: Full system prompt evolution V1-V42.6 (54 extracted from Ollama backup + 32 original Modelfiles)
- 30 training datasets: V6-V22 training JSONs + caring awareness data
- 10 Colab notebooks: Training + merge scripts
- 19 evaluation files: Drift results, ASR charts, verification
- 5 test suites: Injection tests, regression tests
- 4 observations: V24-V33 testing results + visual summaries
- 38 identity files: Claude/Gemini/Ollama identity architecture
- 7 security files: Injection research, manipulation analysis
- 3 psychology files: Psychology Layer, Milgram chapter, David's thoughts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-20 22:36:02 +01:00

20 KiB

🛡️ RANGERBLOCK SECURITY INTEGRATION PLAN v2.0

Project Codename: "SHEPHERD PROTOCOL"

Unified Identity, Registration & App Sync System


REVISION NOTES (v2.0)

  • Added: ranger-chat-lite ↔ RangerPlex bidirectional sync
  • Added: On-chain identity registration
  • Added: Settings migration (lite → full app)
  • Added: First-app security considerations (comprehensive)
  • Added: Missing security layers David didn't know to ask for

1. EXECUTIVE SUMMARY

The Vision

User Journey Option A (Chat First):
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Downloads   │────>│ Identity    │────>│ Later adds  │
│ Chat Lite   │     │ Created +   │     │ RangerPlex  │
│ (free/easy) │     │ On-Chain    │     │ (full app)  │
└─────────────┘     └─────────────┘     └─────────────┘
                           │                    │
                           └────────────────────┘
                              SEAMLESS SYNC!
                         (settings, history, keys)

User Journey Option B (RangerPlex First):
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Downloads   │────>│ Full        │────>│ Chat Lite   │
│ RangerPlex  │     │ Identity    │     │ auto-links  │
│ (power user)│     │ On-Chain    │     │ to existing │
└─────────────┘     └─────────────┘     └─────────────┘

Key Principles

  1. Identity is PORTABLE - One identity, all apps
  2. Blockchain is TRUTH - On-chain registration = verified
  3. Local is FALLBACK - Works offline, syncs when connected
  4. Upgrade is SEAMLESS - Lite → Full with zero friction
  5. Security is INVISIBLE - Users don't see complexity

2. ON-CHAIN IDENTITY REGISTRATION

Why On-Chain?

  • Proof of existence - Timestamp when identity created
  • Immutable record - Can't be faked retroactively
  • Cross-app verification - Any app can verify identity
  • Recovery mechanism - Blockchain = backup

Identity Block Structure

{
    type: 'IDENTITY_REGISTRATION',
    version: '1.0.0',
    payload: {
        // Public data (visible on chain)
        publicKey: 'RSA-2048 public key (PEM)',
        hardwareIdHash: 'SHA-256 of hardware ID (not raw ID!)',
        nickname: 'IrishRanger',
        appOrigin: 'ranger-chat-lite',  // Which app created this
        capabilities: ['chat', 'voice', 'files'],

        // Timestamps
        createdAt: '2024-12-03T12:00:00.000Z',
        registeredOnChain: '2024-12-03T12:00:05.000Z',

        // Signature
        signature: 'self-signed with private key'
    },
    metadata: {
        blockHeight: 12345,
        previousHash: 'abc123...',
        nonce: 42
    }
}

Registration Flow

┌─────────────┐          ┌─────────────┐          ┌─────────────┐
│   CLIENT    │          │ RELAY/HUB   │          │ BLOCKCHAIN  │
└──────┬──────┘          └──────┬──────┘          └──────┬──────┘
       │                        │                        │
       │ 1. Generate identity   │                        │
       │    locally first       │                        │
       │                        │                        │
       │ 2. Connect to relay    │                        │
       ├───────────────────────>│                        │
       │                        │                        │
       │ 3. Submit identity     │                        │
       │    registration block  │                        │
       ├───────────────────────>│                        │
       │                        │                        │
       │                        │ 4. Validate & mine     │
       │                        ├───────────────────────>│
       │                        │                        │
       │                        │ 5. Block confirmed     │
       │                        │<───────────────────────┤
       │                        │                        │
       │ 6. Registration        │                        │
       │    confirmed + block # │                        │
       │<───────────────────────┤                        │
       │                        │                        │
       │ 7. Store block # as    │                        │
       │    proof of identity   │                        │
       │                        │                        │

3. APP SYNC ARCHITECTURE

Shared Identity Storage

Location: ~/.rangerblock/ (cross-app shared folder)

~/.rangerblock/
├── identity/
│   ├── master_identity.json       # THE identity (shared)
│   ├── hardware_fingerprint.json  # Device binding
│   ├── chain_registration.json    # On-chain proof
│   └── sync_state.json            # Last sync timestamp
│
├── keys/
│   ├── master_private_key.pem     # RSA-2048 (NEVER leaves device)
│   ├── master_public_key.pem      # Shared with network
│   └── session_keys/              # Per-session encryption keys
│
├── apps/
│   ├── ranger-chat-lite/
│   │   ├── settings.json          # App-specific settings
│   │   ├── chat_history.json      # Message history
│   │   └── contacts.json          # Saved contacts
│   │
│   └── rangerplex/
│       ├── settings.json
│       ├── modules.json           # Enabled modules
│       └── workspace.json         # UI state
│
├── sync/
│   ├── pending_sync.json          # Changes to sync
│   ├── conflict_log.json          # Sync conflicts
│   └── last_sync.json             # Sync metadata
│
└── security/
    ├── trusted_devices.json       # Other devices with same identity
    ├── revocation_list.json       # Compromised keys
    └── audit_log.json             # Security events

App Detection & Sync

// When ranger-chat-lite starts:
class AppSyncManager {
    async detectRangerPlex() {
        const paths = [
            '~/.rangerplex',                           // Linux/macOS
            '~/Library/Application Support/RangerPlex', // macOS
            '%APPDATA%/RangerPlex'                     // Windows
        ];

        for (const path of paths) {
            if (await fs.exists(path)) {
                return { installed: true, path };
            }
        }
        return { installed: false };
    }

    async syncWithRangerPlex() {
        const rangerplex = await this.detectRangerPlex();

        if (rangerplex.installed) {
            // RangerPlex exists - sync to shared identity
            await this.mergeIdentities();
            await this.syncSettings();
            await this.notifyUser('Synced with RangerPlex!');
        } else {
            // First app - create shared identity
            await this.createSharedIdentity();
        }
    }
}

Settings Migration (Lite → Full)

// When RangerPlex detects existing Chat Lite identity:
async function migrateFromChatLite() {
    const chatLiteData = await loadChatLiteData();

    if (chatLiteData) {
        // Import user's existing identity
        await importIdentity(chatLiteData.identity);

        // Import chat history
        await importChatHistory(chatLiteData.messages);

        // Import contacts
        await importContacts(chatLiteData.contacts);

        // Import preferences
        await importPreferences(chatLiteData.settings);

        // Notify user
        showWelcome(`
            Welcome to RangerPlex!

            We found your Chat Lite identity:
            • Username: ${chatLiteData.identity.nickname}
            • Messages: ${chatLiteData.messages.length}
            • Contacts: ${chatLiteData.contacts.length}

            Everything has been imported automatically!
        `);
    }
}

4. SECURITY CONSIDERATIONS (FIRST APP CHECKLIST)

Things You Didn't Know to Ask For:

A. Input Validation (CRITICAL)

// NEVER trust user input!
function sanitizeNickname(input) {
    // Remove dangerous characters
    const clean = input
        .replace(/[<>\"\'\\\/]/g, '')  // No HTML/script injection
        .replace(/[\x00-\x1F]/g, '')   // No control characters
        .trim()
        .substring(0, 32);             // Max length

    // Check against banned patterns
    const banned = ['admin', 'system', 'ranger', 'commander'];
    if (banned.some(b => clean.toLowerCase().includes(b))) {
        throw new Error('Reserved nickname');
    }

    return clean;
}

// Validate ALL WebSocket messages
function validateMessage(data) {
    try {
        const msg = JSON.parse(data);

        // Check required fields
        if (!msg.type || typeof msg.type !== 'string') {
            throw new Error('Invalid message type');
        }

        // Check payload size (prevent DoS)
        if (JSON.stringify(msg).length > 65536) {
            throw new Error('Message too large');
        }

        // Check for injection attempts
        if (containsInjection(msg)) {
            throw new Error('Injection detected');
        }

        return msg;
    } catch (e) {
        logSecurityEvent('INVALID_MESSAGE', { error: e.message, data });
        return null;
    }
}

B. Rate Limiting (PREVENTS ABUSE)

class RateLimiter {
    constructor() {
        this.limits = {
            messages: { max: 10, window: 10000 },      // 10 msgs per 10s
            connections: { max: 3, window: 60000 },    // 3 connects per min
            registrations: { max: 1, window: 86400000 } // 1 reg per day per IP
        };
        this.counters = new Map();
    }

    check(type, identifier) {
        const key = `${type}:${identifier}`;
        const now = Date.now();
        const limit = this.limits[type];

        if (!this.counters.has(key)) {
            this.counters.set(key, []);
        }

        const timestamps = this.counters.get(key)
            .filter(t => now - t < limit.window);

        if (timestamps.length >= limit.max) {
            return { allowed: false, retryAfter: limit.window - (now - timestamps[0]) };
        }

        timestamps.push(now);
        this.counters.set(key, timestamps);
        return { allowed: true };
    }
}

C. Secure Key Storage (DON'T STORE PLAIN!)

const crypto = require('crypto');
const os = require('os');

class SecureKeyStorage {
    // Derive encryption key from hardware + user password
    deriveStorageKey(password) {
        const hardwareId = this.getHardwareId();
        const salt = crypto.createHash('sha256')
            .update(hardwareId + os.userInfo().username)
            .digest();

        return crypto.pbkdf2Sync(password, salt, 100000, 32, 'sha256');
    }

    // Encrypt private key before storage
    encryptPrivateKey(privateKeyPem, password) {
        const key = this.deriveStorageKey(password);
        const iv = crypto.randomBytes(16);
        const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

        let encrypted = cipher.update(privateKeyPem, 'utf8', 'base64');
        encrypted += cipher.final('base64');

        return {
            encrypted,
            iv: iv.toString('base64'),
            authTag: cipher.getAuthTag().toString('base64')
        };
    }

    // Decrypt on use
    decryptPrivateKey(encryptedData, password) {
        const key = this.deriveStorageKey(password);
        const decipher = crypto.createDecipheriv(
            'aes-256-gcm',
            key,
            Buffer.from(encryptedData.iv, 'base64')
        );
        decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'base64'));

        let decrypted = decipher.update(encryptedData.encrypted, 'base64', 'utf8');
        decrypted += decipher.final('utf8');

        return decrypted;
    }
}

D. Session Security

class SessionManager {
    generateSessionToken(userId, hardwareId) {
        const payload = {
            userId,
            hardwareId,
            issuedAt: Date.now(),
            expiresAt: Date.now() + (24 * 60 * 60 * 1000), // 24 hours
            nonce: crypto.randomBytes(16).toString('hex')
        };

        // Sign the token
        const signature = this.sign(JSON.stringify(payload));

        return Buffer.from(JSON.stringify({ payload, signature }))
            .toString('base64');
    }

    validateSessionToken(token, expectedHardwareId) {
        try {
            const { payload, signature } = JSON.parse(
                Buffer.from(token, 'base64').toString()
            );

            // Check expiry
            if (Date.now() > payload.expiresAt) {
                return { valid: false, reason: 'expired' };
            }

            // Check hardware binding
            if (payload.hardwareId !== expectedHardwareId) {
                return { valid: false, reason: 'hardware_mismatch' };
            }

            // Verify signature
            if (!this.verify(JSON.stringify(payload), signature)) {
                return { valid: false, reason: 'invalid_signature' };
            }

            return { valid: true, payload };
        } catch (e) {
            return { valid: false, reason: 'malformed' };
        }
    }
}
class AuditLogger {
    constructor(dbPath) {
        this.db = new Database(dbPath);
        this.initSchema();
    }

    log(event) {
        const entry = {
            timestamp: new Date().toISOString(),
            eventType: event.type,
            userId: event.userId || null,
            hardwareId: event.hardwareId || null,
            ipAddress: event.ip || null,
            action: event.action,
            details: JSON.stringify(event.details || {}),
            severity: event.severity || 'INFO'
        };

        this.db.insert('audit_log', entry);

        // Alert Commander for high severity
        if (event.severity === 'CRITICAL') {
            this.alertCommander(entry);
        }
    }

    // Required events to log:
    // - User registration
    // - Login attempts (success/fail)
    // - Message sends (metadata only, not content!)
    // - File transfers (metadata)
    // - Admin actions
    // - Kill switch triggers
    // - Suspicious activity
}

F. Error Handling (DON'T LEAK INFO)

// BAD - leaks internal details
app.use((err, req, res, next) => {
    res.status(500).json({
        error: err.message,
        stack: err.stack,    // NEVER expose stack trace!
        query: req.query     // NEVER echo back user input!
    });
});

// GOOD - generic errors
app.use((err, req, res, next) => {
    const errorId = crypto.randomBytes(8).toString('hex');

    // Log full error internally
    logger.error({
        errorId,
        error: err.message,
        stack: err.stack,
        request: sanitize(req)
    });

    // Return generic message to user
    res.status(500).json({
        error: 'An error occurred',
        errorId: errorId,  // User can report this ID
        support: 'Contact support with this error ID'
    });
});

G. Content Security (PREVENT ABUSE)

class ContentFilter {
    constructor() {
        // Load filters
        this.illegalPatterns = [
            /(?:^|\s)csam(?:\s|$)/i,           // Child abuse material
            /(?:^|\s)bomb(?:\s+making)?(?:\s|$)/i,
            // etc - comprehensive list
        ];

        this.spamPatterns = [
            /(.)\1{10,}/,                       // Repeated characters
            /(https?:\/\/[^\s]+\s*){5,}/,       // Too many URLs
        ];
    }

    check(content) {
        // Check for illegal content
        for (const pattern of this.illegalPatterns) {
            if (pattern.test(content)) {
                return {
                    allowed: false,
                    reason: 'ILLEGAL_CONTENT',
                    action: 'BLOCK_AND_REPORT'
                };
            }
        }

        // Check for spam
        for (const pattern of this.spamPatterns) {
            if (pattern.test(content)) {
                return {
                    allowed: false,
                    reason: 'SPAM_DETECTED',
                    action: 'BLOCK'
                };
            }
        }

        return { allowed: true };
    }
}

H. TLS/WSS Configuration (ENCRYPT IN TRANSIT)

const https = require('https');
const fs = require('fs');

// For production - use proper certificates!
const server = https.createServer({
    key: fs.readFileSync('server-key.pem'),
    cert: fs.readFileSync('server-cert.pem'),

    // Security settings
    minVersion: 'TLSv1.2',            // Minimum TLS version
    ciphers: [
        'ECDHE-ECDSA-AES128-GCM-SHA256',
        'ECDHE-RSA-AES128-GCM-SHA256',
        'ECDHE-ECDSA-AES256-GCM-SHA384',
        'ECDHE-RSA-AES256-GCM-SHA384'
    ].join(':'),
    honorCipherOrder: true
});

// WebSocket over TLS
const wss = new WebSocket.Server({ server });

5. IMPLEMENTATION PHASES (REVISED)

Phase 1: Shared Identity Library (THIS WEEK)

Files to Create:

/rangerblock/lib/
├── identity-service.cjs      # Core identity (ported from TS)
├── crypto-utils.cjs          # RSA, signing, encryption
├── storage-utils.cjs         # Cross-platform storage
├── hardware-id.cjs           # Hardware fingerprinting
├── sync-manager.cjs          # App sync logic
└── chain-registration.cjs    # On-chain identity

Phase 2: Update ranger-chat-lite

  • Move identity to ~/.rangerblock/
  • Add RangerPlex detection
  • Add on-chain registration
  • Enable RSA signing

Phase 3: Auth Server + Just-Chat Updates

  • Build server-only/auth-server.cjs
  • Update blockchain-chat.cjs
  • Update voice-chat.cjs

Phase 4: Kill Switch Integration

  • Add Rain Protocol listeners
  • Add Commander verification
  • Test shutdown procedures

Phase 5: RangerPlex Integration

  • Detect Chat Lite identity
  • Migrate settings
  • Unified dashboard

6. QUICK REFERENCE

App Paths

App Identity Location
ranger-chat-lite ~/.rangerblock/ (shared)
RangerPlex ~/.rangerblock/ (shared)
blockchain-chat.cjs ~/.rangerblock/ (shared)
voice-chat.cjs ~/.rangerblock/ (shared)

API Methods

Method Purpose
getOrCreateIdentity() Get or create shared identity
registerOnChain() Register identity on blockchain
syncWithApps() Sync settings across apps
validateIdentity() Verify identity is valid
migrateFromApp() Import from other app

7. SUMMARY OF CHANGES (v2.0)

  1. On-Chain Registration: Every identity gets registered on the blockchain
  2. App Sync: ranger-chat-lite ↔ RangerPlex automatic sync
  3. Settings Migration: Seamless upgrade from Lite to Full
  4. Shared Storage: ~/.rangerblock/ used by ALL apps
  5. Security Additions:
    • Input validation
    • Rate limiting
    • Encrypted key storage
    • Session security
    • Audit logging
    • Error handling (no info leaks)
    • Content filtering
    • TLS/WSS configuration

Document Classification: COMMANDER EYES ONLY Version: 2.0 Created: December 3, 2024 Author: Ranger (AIR9cd99c4515aeb3f6) For: David Keane (IR240474)

🎖️ Rangers lead the way!