c789f2c68d
- 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>
20 KiB
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
- Identity is PORTABLE - One identity, all apps
- Blockchain is TRUTH - On-chain registration = verified
- Local is FALLBACK - Works offline, syncs when connected
- Upgrade is SEAMLESS - Lite → Full with zero friction
- 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' };
}
}
}
E. Audit Logging (LEGAL PROTECTION)
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)
- On-Chain Registration: Every identity gets registered on the blockchain
- App Sync: ranger-chat-lite ↔ RangerPlex automatic sync
- Settings Migration: Seamless upgrade from Lite to Full
- Shared Storage:
~/.rangerblock/used by ALL apps - 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!