Security Model
The security of this system is built on a robust cryptographic flow that ensures data confidentiality and enforces access control at every step. Even with full database and server access, an unauthorized party cannot read document content.
Cryptographic Flow
Here is a breakdown of the key cryptographic operations.
??? info "1. User Creation & Key Generation
When a new user is created, the server generates their cryptographic identity. The user's private key is immediately encrypted with a strong, unique passphrase that is returned to the user only once."
graph TD
subgraph Server-Side Process
A[Start: User Registration Request] --> B(Generate RSA-2048 Key Pair);
B --> C{Public Key & Private Key};
A --> D(Generate Secure Passphrase);
C --> F(Encrypt Private Key with Hashed Passphrase);
D --> F;
C --> G[Store Public Key in DB];
F --> H[Store Encrypted Private Key in DB];
end
subgraph Response to User
I[Return User Profile & One-Time Passphrase];
end
H --> I;
??? info "2. User Authentication
The user's passphrase is never stored on the server. It is used only once during the login process to unlock a short-lived JWT, which is then used for all subsequent authenticated requests."
sequenceDiagram
participant User
participant API Server
User->>API Server: POST /token (username, passphrase)
activate API Server
API Server->>API Server: Hash provided passphrase
API Server->>API Server: Attempt to decrypt user's private key in-memory
alt Credentials are valid
API Server->>API Server: Generate short-lived JWT
API Server-->>User: Return JWT Token
else Credentials are invalid
API Server-->>User: Return 401 Unauthorized
end
deactivate API Server
??? info "3. Document Upload & Encryption
When a document is uploaded, it is encrypted with a brand new, single-use key (DEK). This DEK is then encrypted for the owner and each designated recipient using their respective public keys."
graph TD
subgraph Client
A[User uploads file and list of recipients]
end
subgraph Server
B(Generate unique Document Encryption Key - DEK)
C(Encrypt Document with DEK using AES-GCM)
D{"For each recipient (including owner)..."}
E(Fetch Recipient's Public Key from DB)
F(Encrypt DEK with Recipient's Public Key)
G[Store Encrypted DEK in SharedKeyRegistry]
end
subgraph Storage
H((Store Encrypted Document))
end
A --> B;
B --> C;
C --> H;
A --> D;
D --> E;
E --> F;
F --> G;
??? info "4. Document Access & Decryption
To access a document, the server uses the user's credentials (from the JWT) to decrypt their private key in memory, which is then used to decrypt the document's specific DEK. This DEK is finally used to decrypt the document itself, which is streamed back to the user."
sequenceDiagram
participant User
participant API Server
participant Database
participant Storage
User->>API Server: GET /documents/{doc_id} (with JWT)
activate API Server
API Server->>API Server: 1. Validate JWT & get User ID
API Server->>Database: 2. Fetch User's Encrypted Private Key
Database-->>API Server: Returns Encrypted Private Key
note right of API Server: User's passphrase was used at login to create a key for this decryption, held in memory.
API Server->>API Server: 3. Decrypt User's Private Key in-memory
API Server->>Database: 4. Fetch the Encrypted DEK for this User & Document
Database-->>API Server: Returns Encrypted DEK
API Server->>API Server: 5. Decrypt DEK with User's Private Key
API Server->>Storage: 6. Fetch Encrypted Document
Storage-->>API Server: Returns Encrypted Document
API Server->>API Server: 7. Decrypt Document with DEK
API Server-->>User: 8. Stream decrypted document content
deactivate API Server
Access Control Matrix
| Role | Upload | Share | Revoke | Delete | Read Own | Read Shared |
|---|---|---|---|---|---|---|
| Owner | ✅ | ✅ | ✅ | ✅ | ✅ | N/A |
| Shared User | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |
Security Guarantees
- Confidentiality: Documents at rest are unreadable without authorization, even to system admins.
- Access Control: Permissions are enforced cryptographically, not just via application logic.
- No Passphrase in Transit: After initial login, only short-lived JWTs are transmitted.