SECURITY

Security Model

Zero-knowledge architecture, client-side encryption, and defense in depth. How Helix protects your data without requiring trust.

~4 min read

"

Security through mathematics, not promises.

Traditional cloud services ask you to trust them with your data. Helix takes a different approach: we've designed a system where trust isn't required. Even if our servers were completely compromised, your data would remain secure.

Zero-Knowledge Architecture

"Zero-knowledge" means we never have access to your unencrypted data. This isn't a policy decision—it's a mathematical guarantee built into the architecture.

Your Browser (Trust Boundary)
Plaintext FileAES-GCM EncryptionEncryption Key (stored locally)Key never leaves browser
Helix Servers
Sees: Ciphertext onlySees: Encrypted metadataSees: Wallet addressNever sees: Plaintext, Keys, File names
Arweave Network
Stores: Encrypted blobsPublicly accessibleAnyone can downloadNo one can decrypt

What This Means

Even if an attacker gained complete access to our servers and the Arweave network, they would only have encrypted blobs. Without your encryption keys, which never leave your browser, the data is useless.

Encryption Details

Algorithm: AES-256-GCM

We use AES-256-GCM (Galois/Counter Mode), the same algorithm used by governments and financial institutions worldwide. It provides both confidentiality and authenticity.

PropertyValueWhy It Matters
AlgorithmAES-256-GCMNIST-approved, quantum-resistant key size
Key Size256 bits2^256 possible keys—unbreakable by brute force
IV Size96 bitsUnique per encryption, prevents pattern analysis
Auth Tag128 bitsDetects any tampering with ciphertext

Key Generation

Encryption keys are generated using the Web Crypto API's cryptographically secure random number generator. Each file gets a unique key.

key-generation.ts
// Generate cryptographically secure key
const key = await crypto.subtle.generateKey(
  {
    name: 'AES-GCM',
    length: 256  // 256-bit key
  },
  true,          // Extractable (for storage)
  ['encrypt', 'decrypt']
);

// Key is generated from CSPRNG
// Entropy source: window.crypto.getRandomValues()
// Backed by OS-level entropy (e.g., /dev/urandom)

IV (Initialization Vector)

A fresh random IV is generated for every encryption operation. This ensures that even identical files produce different ciphertext.

iv-generation.ts
// 96-bit IV, randomly generated per encryption
const iv = crypto.getRandomValues(new Uint8Array(12));

// IV is prepended to ciphertext (not secret)
// Format: [IV (12 bytes)][Ciphertext][Auth Tag (16 bytes)]

Never Reuse IVs

AES-GCM's security completely breaks down if an IV is reused with the same key. By generating a fresh random IV every time, we eliminate this risk entirely.

Key Management

Encryption keys are the crown jewels. Here's how we handle them:

Local Storage

Keys are stored in your browser's localStorage, keyed to your wallet address. They never touch our servers.

Export Format

Keys can be exported as base64 strings for backup. You control your keys completely.

Per-File Keys

Each file has its own unique key. Compromising one key doesn't affect other files.

No Recovery

We cannot recover lost keys. This is a feature—it means we can never access your data.

key-storage.ts
// Store key in localStorage
const keyData = await crypto.subtle.exportKey('raw', key);
const keyBase64 = btoa(String.fromCharCode(...new Uint8Array(keyData)));

localStorage.setItem(
  `helix_key_${transactionId}`,
  JSON.stringify({
    key: keyBase64,
    createdAt: Date.now(),
    walletAddress: wallet.publicKey.toString()
  })
);

// Keys are isolated by wallet address
// Switching wallets = different key namespace

Key Backup Responsibility

Because we can't recover your keys, backing them up is your responsibility. We provide export functionality—use it for important files. Future versions will support encrypted key sync.

Threat Model

We've designed Helix to be secure against a wide range of threats:

Protected Against
  • Server Compromise: Attackers get encrypted blobs only
  • Database Breach: No plaintext data, no keys stored
  • Network Interception: TLS + encryption = double protection
  • Malicious Employees: We can't access data we can't decrypt
  • Government Requests: We can only provide encrypted data
  • Arweave Node Operators: They see encrypted blobs only
Your Responsibility
  • Browser Security: Keep your browser updated
  • Device Security: Protect your computer from malware
  • Wallet Security: Protect your wallet's seed phrase
  • Key Backup: Export and securely store encryption keys
  • Phishing: Verify you're on the real Helix site
Cannot Protect Against
  • Compromised Device: If malware controls your browser
  • Lost Keys: No recovery possible by design
  • Quantum Computers: AES-256 is resistant, but future-proof isn't guaranteed

Wallet Security

Your Solana wallet is your identity on Helix. Wallet security is critical:

What Your Wallet Does

Signs transactions to authorize payments
Proves ownership of your files (via public key)
Signs authentication messages (no blockchain transaction)

What Your Wallet Doesn't Do

Does NOT generate or store encryption keys
Does NOT encrypt or decrypt files
Does NOT have access to file contents

Wallet vs. Encryption Keys

Your wallet proves who you are. Encryption keys protect your data. These are separate concerns: losing wallet access means losing the ability to upload new files; losing encryption keys means losing access to file contents.

Data Integrity

AES-GCM provides authenticated encryption, meaning it detects any tampering with the ciphertext:

integrity-check.ts
// When decrypting, GCM verifies the auth tag
try {
  const decrypted = await crypto.subtle.decrypt(
    { name: 'AES-GCM', iv },
    key,
    ciphertext
  );
  // Success: data is authentic and unmodified
} catch (error) {
  // Decryption failed: data was tampered with
  // or wrong key was used
  throw new Error('Data integrity check failed');
}

Additionally, Arweave provides content addressing—the transaction ID is derived from the data itself. If anyone modified the stored data, the ID wouldn't match.

01

Original Upload

Data → SHA-256 hash → Transaction ID: abc123...

02

Later Download

Fetch abc123... → Data → SHA-256 → abc123... ✓ (Match!)

03

If Tampered

Modified Data → SHA-256 → xyz789... ✗ (Different ID doesn't exist)

Security Roadmap

Security is never "done." Here's what we're working on:

Third-party security audit (in progress)
Encrypted key sync across devices
Hardware wallet key derivation
Post-quantum encryption options
"

We publish our security model because transparency builds trust. If you find a vulnerability, please report it responsibly.

Last updated: February 2025