Security Architecture

Zero-Knowledge by Design

Tijori is built from the ground up with security as the primary concern. Your secrets are encrypted in your browser and never leave your device in plaintext.

Overview

Tijori employs a zero-knowledge architecture where the server never sees plaintext secrets. All encryption and decryption happens client-side in the browser using the Web Crypto API. Even if our database were compromised, your secrets would remain encrypted and unusable without your passcodes.

Encryption Stack

AES-256-GCM
Symmetric Encryption

256-bit key, 96-bit IV, 128-bit authentication tag.

Provides both confidentiality and integrity. If any bit of the ciphertext is tampered with, decryption will fail.

PBKDF2
Key Derivation

100,000 iterations with SHA-256 and a 128-bit salt.

Derives a cryptographic key from your 6-digit passcode. High iteration count makes brute-force attacks computationally expensive.

SHA-256
Hashing

Salted hashing for passcode verification.

We store a hash of your passcode for verification, but never the passcode itself. This allows us to confirm correctness without knowing the value.

Key Hierarchy

Master Key (memorized)
│
├── Hash (SHA-256 + salt) → Stored in DB for verification
│
└── Derive via PBKDF2 → Master CryptoKey
        │
        └── Encrypts Project Passcodes (for recovery)

Project Passcode (6-digit)
│
├── Hash (SHA-256 + salt) → Stored in DB for verification
│
└── Derive via PBKDF2 → Project CryptoKey
        │
        └── Encrypts all Environment Variables

Threat Model

Protected Against

  • Eavesdropping (encryption at rest + in transit)
  • Server compromise (zero-knowledge design)
  • XSS attacks (CSP + React's escaping)
  • Clickjacking (X-Frame-Options: DENY)
  • CSRF (Convex's token-based auth)
  • IDOR (ownership verification on all resources)
  • SQL Injection (N/A - document database)
  • Unauthorized access (RBAC on all mutations)

Out of Scope

  • ⚠️Client-side keyloggers (user's machine compromised)
  • ⚠️Shoulder surfing (physical access)
  • ⚠️Weak passcodes (6-digit provides ~1M combinations)
  • ⚠️Forgotten master key (no recovery possible by design)

Security Headers

In production, Tijori serves responses with the following security headers:

HeaderValuePurpose
Content-Security-PolicyStrict allowlistPrevent XSS
X-Content-Type-OptionsnosniffPrevent MIME sniffing
X-Frame-OptionsDENYPrevent clickjacking
Referrer-Policystrict-origin-when-cross-originControl referrer leakage
Permissions-Policycamera=(), microphone=(), geolocation=()Disable unused browser APIs

Reporting a Vulnerability

We take security seriously. If you discover a security vulnerability, please follow responsible disclosure:

  • Do NOT open a public GitHub issue for security vulnerabilities.
  • Email security concerns to the project maintainers.
  • Include a description, steps to reproduce, and potential impact.
© 2026 Tijori. Released under AGPL-3.0.