crypt.fyi is a zero-knowledge, end-to-end encrypted secret sharing platform that enables users to securely share sensitive information using AES-256 encryption. The system is designed with a "zero-knowledge" architecture, meaning the server never has access to unencrypted data or encryption keys.
This document outlines the system architecture, security measures, and interaction patterns between client and server components of the crypt.fyi system.
crypt.fyi follows a client-server architecture with the following main components:
- Web Client (Browser-based interface)
- Web Server (Static file server)
- API Server
- Data Store (Ephemeral storage)
[Web Client] <--> [Web Server] // Serves static files only
[Web Client] <--> [API Server] <--> [Data Store]
^
|
[Client-side Encryption/Decryption]
The system deliberately separates the web server (serving static files) from the API server for enhanced security:
-
Web Server
- Serves only static files (HTML, CSS, JS)
- Configured to strip URL query parameters and fragments from request logging
- Configured with strict Content Security Policy (CSP)
- Ideally runs on a separate server / hosting platform from API server
-
API Server
- Handles only encrypted data operations
- Never receives or processes URLs containing decryption keys
- Only receives hashed keys for verification
- Operates independently from web server
This separation ensures that even if the web server logs are compromised, the decryption keys (which are part of the URL fragment) remain secure as they are never sent to the API server. The API server only receives the necessary hashed values for verification, maintaining the zero-knowledge architecture.
-
Client-Side Encryption
- AES-256-GCM encryption with PBKDF2 key derivation and random salt and initialization vector (IV)
- Unique encryption key per secret
- All encryption/decryption occurs in the browser
- Optional password protection for layered encryption
- Password is not embedded in the URL and is ideally shared/transmitted to the recipient separately from the unique vault URL
-
Key Management
- Decryption key never transmitted to server
- Optional password protection
- SHA-256 key verification
-
Server Security
- Server only receives and stores encrypted data
- Server cannot decrypt content
- No user accounts or authentication
- No logging of sensitive data
-
Data Security
- Automatic data expiration (TTL)
- Burn after reading option
- Must be implemented using atomic operations
- Must guarantee exactly one successful read when burn is enabled
- Must prevent race conditions in concurrent access scenarios
- No persistent storage
- Secure deletion of data
- CORS protection
- Rate limiting
- Request size limits
- TLS transport encryption
- Strict Content Security Policy (CSP)
- No eval() or unsafe-inline
- Restricted source origins
- Frame ancestors disabled
- Strict MIME type checking
- XSS protection headers
-
Ephemeral Nature
- All data must be temporary
- Configurable Time-To-Live (TTL) per entry
- Automatic expiration and cleanup
-
Concurrency Requirements
- Must support concurrent access
- Must maintain data consistency
- Must provide atomic operations for critical functions
- Especially for burn-after-reading functionality
- For deletion operations
-
Performance Requirements
- Fast read and write operations
- Efficient handling of concurrent requests
- Scalable storage solution
-
Consistency
- Atomic operations where required
- Proper handling of race conditions
- Guaranteed execution order for critical operations
-
Reliability
- Data available until expiration or deletion
- Proper error handling
- Recovery from system failures
-
Creating a Secret
- Generate random encryption key
- Encrypt content with AES-256-GCM
- Optional: Encrypt again with user password
- Generate SHA-256 hash of key+password
- Send encrypted data to server
-
Retrieving a Secret
- Extract key from URL fragment
- Request encrypted data using ID
- Verify key hash
- Decrypt with key (and password if set)
- Optional: Automatic deletion after reading
- Configurable per-IP rate limiting
- Default: Specified in server configuration
- Must be enforced at the API level
- Maximum content size: 50KB
- Enforced at the API level
- 400: Invalid key/password hash
- 404: Secret not found or already burned
- 429: Rate limit exceeded
- 500: Server error
Each error response will have an appropriate error message in the response body.
- Per-IP rate limiting enforced
- Configurable rate limit window and request quota
- Rate limits apply to all API endpoints
- Maximum content size: 50KB
- TTL Constraints:
- Minimum: 1 second
- Maximum: 7 days
- Default: 1 hour
- Mandatory HTTPS for all API endpoints
- Strict Transport Security (HSTS) enforcement
- Modern TLS protocols only
- Content Security Policy (CSP)
- No eval() or unsafe-inline
- Restricted source origins
- Frame ancestors disabled
- Strict MIME type checking
- Cross-Origin Resource Sharing (CORS)
- Strict origin validation
- Limited allowed methods
- Controlled header exposure
- XSS Protection Headers
- Content Type Options
- Referrer Policy
- Request size limits
- Response sanitization
- No sensitive data in logs
- Secure error handling
- File encryption support
- Notification of read receipts
- Deferred time to available w/ read-side email subscription for availability notifications
- IP whitelisting / blacklisting
- Browser extension
This specification is a living document and will be updated as the system evolves.