Security Architecture by User Type
Protocol Media Labs implements distinct security models for each user type, recognizing that readers, journalists, and sources have fundamentally different threat models and protection requirements. This document defines the security architecture, controls, and guarantees for each user category.
Security Overview
The platform's security architecture follows a gradient of privacy: readers enjoy convenience with basic privacy, journalists balance transparency with protection, and sources receive maximum anonymity with military-grade encryption.
Reader Security Architecture
Threat Model
Readers face common web threats but with blockchain-specific considerations:
| Threat | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Account takeover | Medium | Medium | zkLogin with ephemeral keys |
| Payment fraud | Low | Low | Client-side verification |
| Content tampering | Low | Low | Hash verification |
| Privacy breach | Medium | Medium | No PII on-chain |
| Tracking | Low | High | Optional anonymous browsing |
Security Controls
Authentication Security
// zkLogin with privacy-preserving authentication
const readerAuthConfig = {
ephemeral_key_rotation: 24 * 60 * 60 * 1000, // 24 hours
session_timeout: 7 * 24 * 60 * 60 * 1000, // 7 days
selective_disclosure: ['sub'], // Minimal OAuth claims
proof_generation: 'client_side', // No server sees credentials
fallback_auth: 'wallet_connect' // Crypto-native option
};
Transaction Security
- Sponsored Transactions: Readers never handle private keys directly
- Amount Limits: Micropayment caps prevent large unauthorized charges
- Verification: All entitlements verified client-side before content access
Privacy Protections
- No On-chain PII: Only pseudonymous addresses stored
- Local Storage: Preferences and history kept client-side
- Optional Anonymity: Browse without authentication
Implementation Guidelines
// Secure reader session management
class ReaderSecurityManager {
async initializeSession(provider: OAuthProvider) {
// Generate ephemeral keys with automatic rotation
const keys = await this.generateEphemeralKeys();
// Set conservative session parameters
const session = {
keys,
expires: Date.now() + this.SESSION_DURATION,
refresh_at: Date.now() + this.REFRESH_INTERVAL,
max_spend_per_day: 100_000_000, // 0.1 SUI
requires_2fa_above: 1_000_000_000 // 1 SUI
};
// Store securely in browser
await this.secureStorage.setItem('session', session, {
encrypt: true,
expire_on_close: false
});
return session;
}
async verifyContentIntegrity(content: Content) {
const expectedHash = await this.getContentHash(content.id);
const actualHash = await this.hashContent(content.data);
if (expectedHash !== actualHash) {
throw new SecurityError('Content integrity violation');
}
return true;
}
}
Journalist Security Architecture
Threat Model
Journalists face elevated risks due to their public role and financial stakes:
| Threat | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Wallet compromise | Critical | Medium | Hardware wallets + multi-sig |
| Revenue theft | High | Low | Time-locked withdrawals |
| Content theft | Medium | Medium | On-chain attribution |
| Identity doxxing | High | Medium | Optional pseudonymity |
| Censorship | High | Low | Decentralized storage |
| Source compromise | Critical | Low | Isolated communication |
Security Controls
Wallet Security
// Multi-signature configuration for high-value operations
const journalistWalletConfig = {
primary_signer: 'hardware_wallet',
backup_signers: ['mobile_wallet', 'paper_backup'],
thresholds: {
content_publish: 1, // Single sig
bounty_create: 1, // Single sig
large_withdrawal: 2, // Multi-sig required
profile_update: 2, // Multi-sig required
emergency_recovery: 3 // All signers
},
withdrawal_delay: 48 * 60 * 60 * 1000, // 48 hour delay
daily_limit: 100_000_000_000 // 100 SUI
};
Content Protection
- Immutable Attribution: Content NFTs with permanent on-chain record
- Royalty Enforcement: TransferPolicy ensures perpetual royalties
- Version Control: Content updates tracked with clear history
Source Protection
// Isolated communication with sources
class SourceCommunicationManager {
async initializeBountyComms(bountyId: string) {
// Generate unique keypair per bounty
const bountyKeys = await this.generateBountyKeys(bountyId);
// Configure Seal encryption for this bounty
const sealConfig = {
keyServers: this.JOURNALIST_KEY_SERVERS,
threshold: 2, // 2 of 3 servers
policy: {
approvers: [bountyKeys.public],
backup_approvers: [this.EDITOR_KEY],
auto_decrypt_after: 30 * 24 * 60 * 60 * 1000
}
};
// Isolate communication channel
const channel = await this.createIsolatedChannel({
bountyId,
encryption: sealConfig,
metadata_collection: 'none',
ip_logging: false
});
return channel;
}
}
Operational Security
Key Management
- Primary Wallet: Hardware wallet for high-value operations
- Hot Wallet: Limited funds for daily operations
- Backup: Encrypted seed phrases in secure locations
- Recovery: Multi-party recovery with time delays
Revenue Security
// Secure revenue management
class RevenueSecurityManager {
async configureWithdrawal(journalist: Address) {
const config = {
// Time-locked withdrawals
withdrawal_delay: 48 * 60 * 60 * 1000,
// Gradual release schedule
vesting_schedule: {
immediate: 0.2, // 20% immediate
day_7: 0.3, // 30% after 7 days
day_30: 0.5 // 50% after 30 days
},
// Whitelist withdrawal addresses
allowed_destinations: [
journalist.primary_wallet,
journalist.exchange_address
],
// Require multi-sig for changes
config_change_threshold: 2
};
return await this.applyConfig(config);
}
}
Source Security Architecture
Threat Model
Sources face existential risks where security failures can result in imprisonment or death:
| Threat | Impact | Likelihood | Mitigation |
|---|---|---|---|
| Identity exposure | Critical | High | Multi-layer anonymity |
| Communication interception | Critical | High | E2EE with Seal |
| Device compromise | Critical | Medium | Ephemeral sessions |
| Network surveillance | Critical | High | Onion routing |
| Coercion/Torture | Critical | Low | Plausible deniability |
| Honey pot operations | Critical | Medium | Reputation verification |
Security Controls
Anonymity Architecture
// Maximum anonymity configuration
const sourceSecurityConfig = {
// Network layer
network: {
require_tor: true,
min_hops: 3,
exit_nodes: ['switzerland', 'iceland'],
bridge_mode: 'obfs4',
fallback: 'meek'
},
// Identity layer
identity: {
type: 'ephemeral',
lifetime: 24 * 60 * 60 * 1000, // 24 hours max
rotation: 'automatic',
linking: 'prohibited'
},
// Encryption layer
encryption: {
algorithm: 'XChaCha20-Poly1305',
key_exchange: 'X25519',
forward_secrecy: true,
deniable_encryption: true
},
// Operational layer
operational: {
no_javascript: false, // Required for encryption
no_cookies: true,
no_local_storage: true,
memory_only: true
}
};
Submission Security
// Ultra-secure document submission
class SecureSubmissionManager {
async submitDocuments(
documents: File[],
bountyId: string
) {
// Step 1: Sanitize all documents
const sanitized = await this.sanitizeDocuments(documents, {
remove_metadata: true,
remove_timestamps: true,
remove_geolocation: true,
remove_device_info: true,
add_decoy_data: true // Plausible deniability
});
// Step 2: Multi-layer encryption
const encrypted = await this.encryptMultiLayer(sanitized, {
// Layer 1: Seal threshold encryption
seal: {
threshold: 3,
servers: 5,
policy: {
dead_mans_switch: true,
trigger_delay: 30 * 24 * 60 * 60 * 1000
}
},
// Layer 2: Additional symmetric encryption
symmetric: {
algorithm: 'AES-256-GCM',
key_derivation: 'Argon2id',
iterations: 10
},
// Layer 3: Steganographic hiding
steganography: {
enabled: true,
carrier: 'random_data',
density: 0.1
}
});
// Step 3: Anonymous upload
const uploadResult = await this.uploadAnonymously(encrypted, {
route: 'onion',
chunks: true,
chunk_size: 1024 * 100, // 100KB chunks
random_delays: true,
cover_traffic: true
});
return uploadResult;
}
}
Plausible Deniability
// Deniable encryption implementation
class DeniableEncryption {
async encrypt(
realData: Uint8Array,
decoyData: Uint8Array,
realPassword: string,
decoyPassword: string
) {
// Create two valid decryption paths
const container = new DeniableContainer();
// Real data with real password
container.addLayer(realData, realPassword, {
algorithm: 'XChaCha20-Poly1305',
hidden: true
});
// Decoy data with decoy password
container.addLayer(decoyData, decoyPassword, {
algorithm: 'AES-256-GCM',
hidden: false
});
// Container appears as random data
return container.serialize();
}
async decrypt(
container: Uint8Array,
password: string
) {
// Returns different content based on password
// No indication that other layers exist
return await DeniableContainer.decrypt(container, password);
}
}
Emergency Protocols
Dead Man's Switch
// Automatic revelation if source is compromised
class DeadMansSwitch {
async configure(submissionId: string) {
const config = {
trigger_delay: 30 * 24 * 60 * 60 * 1000, // 30 days
check_interval: 24 * 60 * 60 * 1000, // Daily
// Multiple trigger conditions
triggers: [
{ type: 'no_checkin', delay: 30 * 24 * 60 * 60 * 1000 },
{ type: 'duress_code', immediate: true },
{ type: 'journalist_compromised', delay: 7 * 24 * 60 * 60 * 1000 }
],
// Actions when triggered
actions: [
{ type: 'decrypt_submission', target: 'public' },
{ type: 'notify_backup_journalist', encrypted: true },
{ type: 'post_to_blockchain', permanent: true }
]
};
return await this.activate(submissionId, config);
}
}
Cross-Cutting Security Measures
Infrastructure Security
- No Single Points of Failure: Distributed across Sui validators and Walrus nodes
- Censorship Resistance: Content available through multiple paths
- Availability Guarantees: CDN with Walrus fallback ensures access
Cryptographic Standards
const cryptographicStandards = {
// Signing
signatures: 'Ed25519',
// Key exchange
key_exchange: 'X25519',
// Symmetric encryption
symmetric: 'XChaCha20-Poly1305',
// Hashing
hash: 'SHA-256',
kdf: 'Argon2id',
// Zero-knowledge
zk_proofs: 'Groth16',
// Post-quantum ready
pq_ready: true,
pq_algorithms: ['Kyber', 'Dilithium']
};
Audit and Compliance
Security Audits
- Smart Contract Audits: Annual third-party audits
- Penetration Testing: Quarterly security assessments
- Code Reviews: All security-critical code peer-reviewed
- Dependency Scanning: Automated vulnerability scanning
Incident Response
class IncidentResponsePlan {
async handleIncident(incident: SecurityIncident) {
// Immediate actions
await this.containIncident(incident);
await this.notifyStakeholders(incident.severity);
// Investigation
const analysis = await this.analyzeIncident(incident);
// Remediation
await this.remediateVulnerability(analysis);
// Post-incident
await this.publishPostMortem(analysis);
await this.updateSecurityControls(analysis.lessons);
return analysis;
}
}
Security Implementation Checklist
Reader Security
- zkLogin integration with ephemeral keys
- Sponsored transaction limits
- Content integrity verification
- Session timeout handling
- Privacy-preserving analytics
Journalist Security
- Hardware wallet integration
- Multi-signature setup
- Withdrawal time locks
- Revenue tracking security
- Isolated source communication
Source Security
- Tor integration
- Seal threshold encryption
- Document sanitization
- Dead man's switch
- Plausible deniability features
Infrastructure Security
- Security monitoring
- Incident response procedures
- Audit logging
- Vulnerability management
- Disaster recovery
Conclusion
Protocol Media Labs implements defense-in-depth with security controls appropriate to each user type's threat model. Readers enjoy convenient, privacy-preserving access; journalists balance transparency with protection; and sources receive military-grade security with multiple failsafes. This graduated approach ensures the platform can serve all users while maintaining the highest security standards where lives may depend on it.