If this project helps your work, support ongoing maintenance and new features.
ETH Donation Wallet
0x11282eE5726B3370c8B480e321b3B2aA13686582
Scan the QR code or copy the wallet address above.
- Overview
- Warrant Canary
- Quick Start
- Operating Modes
- Architecture
- Security Attack Scenarios
- OpSec Guidelines
- Storage Providers
- FAQ
- Project Status
- Contributing
- License
Sanctum is a zero-trust, client-side encrypted vault system designed for activists, journalists, whistleblowers, and anyone facing physical duress, device seizure, or censorship. It provides cryptographically sound plausible deniability through passphrase-derived hidden layers while leveraging decentralized IPFS storage.
Most "secure storage" apps rely on "trust me bro" promises. Sanctum is Cryptographically Deniable with Decentralized Storage.
🗞️ Journalist Protecting Sources
- Decoy: Published articles and public research notes
- Hidden: Confidential source documents and whistleblower communications
- Scenario: Device seized at border crossing - reveal decoy, sources stay protected
✊ Activist in Authoritarian Regime
- Decoy: Personal photos and innocuous social media content
- Hidden: Protest coordination plans and evidence of government abuse
- Scenario: Police raid - show decoy layer, cannot prove hidden content exists
💰 Crypto Holder Under Duress
- Decoy: Small wallet with $200 ("this is all I have")
- Hidden: Main wallet with life savings
- Scenario: $5 wrench attack - hand over decoy wallet, real funds stay safe
🔔 Whistleblower Securing Evidence
- Decoy: Work documents and meeting notes
- Hidden: Evidence of corporate fraud or government corruption
- Scenario: Employer demands access - show work files, evidence remains hidden
🏠 Domestic Abuse Survivor
- Decoy: Shared family photos and household documents
- Hidden: Escape plan, evidence of abuse, emergency contacts
- Scenario: Abuser demands access - show family content, safety plan protected
🕵️ Intelligence Operative
- Decoy: Tourist photos and travel itinerary
- Hidden: Mission briefings, contact networks, classified intelligence
- Scenario: Captured by hostile forces - reveal tourist cover, mission data stays secure
🌍 Human Rights Defender
- Decoy: Public advocacy materials and educational content
- Hidden: Witness testimonies and documentation of atrocities
- Scenario: Interrogation - reveal public work, witnesses stay anonymous
- 🎭 Plausible Deniability - Hidden layers indistinguishable from decoy content
- 🚨 Panic Passphrase - Shows "vault deleted" under duress (3rd layer)
- ⏰ 30-Day Grace Period - Accidentally expired vaults can be recovered
- 🌐 Decentralized Storage - Data pinned on IPFS via free services (Pinata/Filebase)
- 🔑 XChaCha20-Poly1305 - Military-grade encryption with split-key architecture
- 🚫 Zero Server Trust - All crypto operations in browser, keys never touch server
- 🧠 RAM-Only Storage - No disk persistence, immune to forensic recovery
- 💰 100% Free - No credit card required, stack multiple free tiers
- 🔒 Auto-Lock - Locks after 5 minutes of inactivity
- ⚡ Panic Key - Double-press Escape for instant lockout
- 📋 Secure Clipboard - Auto-clears after 60 seconds
- 📦 File Support - Upload .zip/.rar archives up to 25MB
Strategy: Create multiple vault triplets (panic/decoy/hidden) with progressively sensitive data to reveal incrementally under escalating duress while keeping the most critical secrets buried.
How it works:
Vault 1 (Low Sensitivity):
├─ Panic: "Vault deleted"
├─ Decoy: Public social media, family photos ($50 wallet)
└─ Hidden: Personal documents, small crypto wallet ($500)
Vault 2 (Medium Sensitivity):
├─ Panic: "Vault deleted"
├─ Decoy: Work files, meeting notes ($500 wallet)
└─ Hidden: Business contracts, medium crypto wallet ($5,000)
Vault 3 (High Sensitivity):
├─ Panic: "Vault deleted"
├─ Decoy: Old backups, archived projects ($5,000 wallet)
└─ Hidden: REAL SECRETS - whistleblower evidence, main wallet ($50,000+)
Duress Response Protocol:
- Initial Coercion → Reveal Vault 1 decoy ("this is everything")
- Increased Pressure → "Okay, I have a backup vault" → Reveal Vault 2 decoy
- Severe Duress → "Fine, here's my real vault" → Reveal Vault 2 hidden layer
- Extreme Torture → "I swear that's all!" → Reveal Vault 3 decoy
- Final Secrets → Vault 3 hidden layer stays protected (adversary believes they got everything)
Psychological Advantage:
- Each "confession" appears genuine (real funds, real documents)
- Adversary's confidence increases with each reveal
- Final vault remains undiscovered ("why would there be more?")
- Cryptographically impossible to prove additional vaults exist
Implementation:
# Create 3 separate vaults with different IPFS providers
Vault 1: Pinata (low sensitivity)
Vault 2: Filebase (medium sensitivity)
Vault 3: Self-hosted IPFS node (high sensitivity)
# Store links separately
Vault 1 link: Memorized or written down
Vault 2 link: Password manager
Vault 3 link: Encrypted USB drive in safe locationBest Practices:
- Make each decoy layer believable (real transaction history, realistic amounts)
- Space out "confessions" (don't reveal all at once)
- Act reluctant when revealing each layer ("okay, you got me")
- Never mention the existence of multiple vaults
- Use different IPFS providers to avoid pattern detection
View Live Canary - Auto-updates with current timestamp on every visit
Statement:
As of the date above, Sanctum developers have:
✅ NOT received any:
- National Security Letters (NSLs)
- FISA court orders
- Gag orders preventing disclosure of legal demands
- Requests to implement backdoors or weaken encryption
- Requests to log user activity or decrypt user data
- Warrants requiring disclosure of user information
✅ NOT been:
- Compelled to modify source code
- Required to hand over cryptographic keys (none exist server-side)
- Forced to compromise the integrity of the system
✅ Architecture guarantees:
- Zero-knowledge: We cannot decrypt user vaults (client-side encryption)
- No user logs: We don't collect IP addresses, usage patterns, or metadata
- No backdoors: All code is open-source and auditable
- RAM-only: No persistent storage of keys or credentials
Verification:
- This canary is updated quarterly
- Signed commits verify authenticity
- If this section is removed or not updated for >90 days, assume compromise
- Check commit history:
git log --show-signature README.md
What We CAN Be Compelled To Do:
- Take down the hosted service (users can self-host)
- Remove specific vault IDs from our database (data remains on IPFS)
- Provide encrypted vault metadata (useless without KeyA in URL)
What We CANNOT Be Compelled To Do:
- Decrypt user vaults (cryptographically impossible)
- Provide user passphrases (never transmitted to server)
- Log future user activity (architecture prevents it)
If This Canary Dies:
- Assume legal compromise
- Self-host immediately:
npm run dev - Use Tor Browser for all vault access
- Rotate all passphrases
- Migrate to new IPFS providers
- Visit sanctumvault.online
- Configure Pinata or Filebase (free IPFS providers)
- Create your vault with optional decoy content
- Set passphrase for hidden layer
- Share the link - only you know the passphrase
# Clone repository
git clone https://github.com/Teycir/Sanctum.git
cd Sanctum
# Install dependencies
npm install
# Login to Cloudflare (for deployment)
npx wrangler login
# Run development server
npm run dev- Project Status - Current implementation status
- Security Features - Auto-lock, panic key, secure clipboard
- RAM-Only Storage - Forensic-resistant architecture
- Timing Attack Mitigation - Defense against timing attacks
- Security Audit - Security analysis and recommendations
Use Case: Secure backup of sensitive data without duress concerns.
Basic encrypted storage without deniability. Single encrypted blob uploaded to IPFS.
2️⃣ Duress Hidden (Current Implementation)
Use Case: $5 wrench attacks, device seizures, coercion scenarios.
How it works:
Client-Side (Browser):
- User creates vault with decoy + hidden content
- Browser encrypts both layers with XChaCha20-Poly1305
- Uploads encrypted blobs to IPFS (Pinata/Filebase)
- Generates split keys: KeyA (stays in URL) + KeyB (sent to server)
- Server encrypts KeyB and stores with encrypted IPFS CIDs
Server-Side (Cloudflare D1):
- Stores: Encrypted KeyB, Encrypted CIDs, vault metadata
- Two-stage cleanup prevents database overflow:
- Stage 1: Expired vaults marked inactive (
is_active = 0) - soft delete - Stage 2: Vaults inactive for 30+ days permanently deleted
- Stage 1: Expired vaults marked inactive (
- 30-day grace period: Accidentally expired vaults can be recovered
Unlock Flow:
- User enters passphrase
- Browser fetches encrypted metadata from server
- Combines KeyA (from URL) + KeyB (from server) to decrypt IPFS CIDs
- Downloads encrypted blobs from IPFS
- Decrypts with passphrase → reveals decoy or hidden layer
Passphrase Behavior:
- Empty/Decoy passphrase → Shows decoy layer (innocent content)
- Hidden passphrase → Shows hidden layer (real secrets)
- Panic passphrase → Shows "vault deleted" error (duress protection)
- Wrong passphrase → Error: "Invalid passphrase"
Error Messages (Plausible Deniability):
All unavailable scenarios show identical message: "Vault content has been deleted from storage providers"
- Panic passphrase entered
- Vault expired (soft deleted)
- Vault doesn't exist
- IPFS blobs missing
3-Layer Protection:
- Decoy Layer - Innocent content (optional)
- Hidden Layer - Real secrets (required)
- Panic Layer - Shows "vault erased" (cryptographically indistinguishable from real deletion)
- Frontend: Next.js 15 + React + Web Crypto API
- Hosting: Cloudflare Pages (static site, free tier)
- Database: Cloudflare D1 (split-key storage)
- Cryptography: @noble/ciphers + @noble/hashes (XChaCha20-Poly1305, Argon2id)
- Storage: IPFS via Pinata/Filebase with public gateway fallback
- State: RAM-only (Web Workers, no persistence)
- Keys never written to disk
- Auto-wiped on browser close
- Protected from disk forensics
- Isolated in Web Worker memory
- Backend: Minimal (only split-key storage, no content access)
┌─────────────────────────────────────┐
│ Browser (Client) │
│ ┌─────────────────────────────┐ │
│ │ Web Worker (RAM-only) │ │
│ │ • Argon2id key derivation │ │
│ │ • XChaCha20 encryption │ │
│ │ • Split-key architecture │ │
│ │ • Auto-clear on idle │ │
│ └─────────────────────────────┘ │
└──────────────┬──────────────────────┘
│
├──────────► Cloudflare D1
│ • Encrypted KeyB
│ • Encrypted CIDs
│ • Vault metadata
│
├──────────► IPFS (Pinata/Filebase)
│ • Encrypted blobs
│ • Public gateways
│ • Decentralized storage
Critical: All encryption client-side. Server only stores encrypted fragments.
✅ YES, BY DESIGN. Reveal the decoy layer. The adversary:
- Sees funded wallet + innocent files
- Cannot prove hidden layers exist
- Cryptographically indistinguishable from simple vault
✅ MITIGATED. Each layer is padded to standard sizes, making size analysis unreliable.
❌ NO. Argon2id with 256MB memory and 3 iterations makes brute-force computationally infeasible. Use strong passphrases (6+ Diceware words).
✅ SAFE. Sanctum uses RAM-only storage with zero disk persistence:
- No localStorage/sessionStorage for sensitive data
- Keys cleared on tab close
- Ephemeral salts regenerated per session
- Immune to disk carving and SSD wear-leveling analysis
See RAM-ONLY-STORAGE.md for technical details.
✅ SAFE. Data is encrypted before upload. Providers only see encrypted blobs. Without your passphrase and vault link, decryption is impossible.
💀 LOST FOREVER. No recovery mechanism exists (by design). Save your links securely.
❌ NO. IPFS data is immutable. Workaround: Don't share the link.
- ✅ Physical duress ($5 wrench attacks, torture)
- ✅ Device seizure (law enforcement, border control)
- ✅ Censorship (government blocking, deplatforming)
Cryptographic:
- Plausible Deniability - Hidden layers cryptographically indistinguishable from decoy
- XChaCha20-Poly1305 - Authenticated encryption with 256-bit keys
- Argon2id KDF - 256MB memory, 3 iterations (brute-force resistant)
- Split-Key Architecture - KeyA (URL) + KeyB (encrypted in DB)
- Vault ID Integrity - 16-byte hash prevents cross-vault contamination
- Password Uniqueness - Enforces distinct passwords (hidden ≠ decoy ≠ panic)
Access Control:
- Auto-Lock - 5 minutes inactivity timeout
- Panic Key - Double-press Escape for instant lockout
- Rate Limiting - 5 attempts/min per vault, 50/hour per fingerprint
- Fingerprint Tracking - SHA-256(IP + User-Agent) for abuse detection
- Honeypot Protection - Auto-ban on suspicious activity
Privacy & Forensics:
- RAM-Only Storage - Zero disk persistence, immune to forensics
- History Clearing - Vault URL auto-removed from browser history
- Secure Clipboard - Auto-clears after 60 seconds
- Provider Isolation - Pinata/Filebase are separate namespaces
Attack Mitigation:
- Randomized Timing - 500-2000ms delay prevents timing analysis
- CSRF Protection - Origin/referer validation
- Security Headers - X-Frame-Options, X-XSS-Protection, nosniff
- Input Sanitization - HTML entity encoding on all user input
See Security Features and RAM-Only Storage for details.
- Anonymous IPFS accounts - Create Pinata/Filebase accounts with anonymous emails (Tutanota, ProtonMail) via Tor Browser
- Fund decoy realistically - $50-500 matching your financial status, include transaction history
- Memorize passphrases - 12+ chars (uppercase, lowercase, number, special). Example:
MySecret#Vault2024 - Use Tor Browser - Hides IP, defeats timing attacks (100-500ms noise)
- Test before trusting - Verify decoy unlocks, practice plausible deniability script
- Never reveal hidden layers - Act natural, claim "this is all I have"
- Store links securely - Password manager (KeePassXC/Bitwarden), never email/cloud
- Anti-keylogger - Copy/paste from password manager, inspect USB ports
Duress Response: Reveal decoy passphrase only. Adversary cannot prove hidden layers exist (cryptographic guarantee).
- Free Tier: 1 GB storage, 500 files, 10 GB bandwidth/month
- Signup: Email only (no credit card)
- Free Tier: 5 GB storage, unlimited bandwidth
- Signup: Email only (no credit card)
This is a security feature, not a bug. Duress vaults always upload 2 encrypted blobs:
- Decoy blob - Even if empty, creates cryptographic chaff
- Hidden blob - Your actual secret content
Security advantages:
- Metadata resistance - Adversary cannot determine which blob is decoy vs hidden
- Plausible deniability - You can claim "I forgot the other passphrase" or "It's a backup"
- Consistent behavior - All vaults look identical (2 blobs, same size), preventing pattern analysis
- Future-proofing - Can add decoy content later without changing structure
Even "empty" encrypted blobs have minimum size (salt + nonce + auth tag + padding), making them indistinguishable from real data. This is exactly how VeraCrypt's hidden volumes work.
The small IPFS storage cost (~few KB) is worth the security benefit.
- Open the vault link
- Enter passphrase (no passphrase = decoy, correct passphrase = hidden)
- Download or copy the decrypted content
💀 LOST FOREVER. No recovery mechanism exists (by design).
Best practices: Save in password manager, print QR code, never share over unencrypted channels
Maximum: 25 MB (per file, .zip or .rar archives supported)
Phase: Production Ready ✅
Tests: 115/115 passing (19 test suites)
Coverage: Core crypto, duress layers, storage, services, vault expiry, security features
See PROJECT-STATUS.md for details.
We welcome contributions! Open an issue or submit a pull request on GitHub.
- 🔐 Security auditing
- 🧪 Testing (unit, integration, e2e)
- 🌍 Internationalization
- 📚 Documentation
- 🎨 UI/UX improvements
Business Source License 1.1 - see LICENSE for details.
Summary: Free for non-production use. Production use requires a commercial license after 4 years from release date.
- TimeSeal - Parent project providing cryptographic patterns
- Cloudflare Pages - Free static site hosting
- Pinata - Free IPFS pinning service
- Filebase - Free IPFS storage service
- VeraCrypt - Inspiration for plausible deniability
- Website: sanctumvault.online
- TimeSeal: timeseal.online
- Ghost Chat: ghost-chat.pages.dev
- Issues: GitHub Issues
- Contact: teycirbensoltane.tn
✅ Legitimate Privacy Needs:
- Journalists protecting sources
- Activists in authoritarian regimes
- Crypto holders preventing theft
- Whistleblowers securing evidence
- Individuals under threat of violence
❌ Prohibited Use:
- Illegal content storage
- Facilitating crimes
- Evading lawful investigations (where no duress exists)
Sanctum is a tool for legitimate privacy and security needs. Users are responsible for complying with local laws. The developers do not condone illegal activities.
Built with ❤️ and 🔒 by Teycir Ben Soltane
