first commit

This commit is contained in:
2026-01-30 14:02:52 +01:00
commit 0c86217bde
52 changed files with 10219 additions and 0 deletions

140
PROJECT.md Normal file
View File

@@ -0,0 +1,140 @@
# Design Proposal: Zero-Knowledge Secrets Manager
## 1. Architectural Overview
**Philosophy:** "Thick Client, Blind Server."
The system relies on a **Zero-Knowledge Architecture**. The server (Node.js/PostgREST) and the database never see unencrypted secrets; they act solely as a synchronization engine for encrypted blobs. All encryption/decryption occurs on the client device (Tauri/Flutter) using keys that never leave the device.
### High-Level Data Flow
1. **Client:** Derives Master Key from (Password + Salt). Encrypts data locally.
2. **Transport:** Sends encrypted blob (text/bytea) over HTTPS.
3. **Gateway:** Nginx/Traefik handles SSL termination and routing.
4. **Auth:** Node.js verifies identity (SRP-6a) and issues JWT.
5. **Persistence:** PostgREST accepts JWT, enforces Row-Level Security (RLS), and writes blob to PostgreSQL.
---
## 2. Component Design
### A. Database Layer (PostgreSQL v18+)
* **Role:** Storage and Authorization Engine.
* **Logic:** Heavily utilizes Row-Level Security (RLS) policies.
* **Schema Strategy:**
* `users`: Stores `verifier` (SRP-6a) or hashed credentials (Argon2id).
* `secrets`: Stores `encrypted_data` (bytea), `iv`, `auth_tag`, `owner_id`, `type` (manual/rotated).
* `access_policies`: Join table mapping users/groups to secrets.
* **Security:** RLS policies ensure `SELECT * FROM secrets` only returns rows where `auth.uid() IN (access_policies)`.
### B. Backend API (Node.js v24 + PostgREST)
* **Node.js Service:**
* **Auth:** Implements SRP-6a (Secure Remote Password) protocol.
* **Business Logic:** Handling billing, email alerts, secret rotation jobs, and external webhooks.
* **Orchestration:** Manages Redis interactions for ephemeral state.
* **PostgREST:**
* High-performance CRUD layer.
* Directly exposes secure views/tables.
* Consumes JWTs issued by the Node.js service for authorization.
### C. Caching & State (Redis Cluster v8)
* **Image Source:** Official `redis:alpine` (replacing deprecated Bitnami images).
* **Revocation Lists:** Stores revoked JWT JTI claims.
* **Rate Limiting:** Distributed counters to block brute-force attacks.
* **Pub/Sub:** Real-time event bus to trigger client syncs (e.g., "Vault Updated").
### D. Clients (Tauri & Flutter)
* **Desktop (Tauri):**
* **Security:** Encryption logic (AES-256-GCM / XChaCha20-Poly1305) runs in the Rust backend to prevent memory dumping attacks via browser dev tools.
* **Offline:** Encrypted SQLite local replica.
* **Mobile (Flutter):**
* **Storage:** Uses `flutter_secure_storage` for session tokens.
* **Bio-auth:** Integrates FaceID/Fingerprint to unlock the local vault key.
---
## 3. Workflows
### A. Manual Secret Entry (Core Feature)
This is the standard workflow for storing static API keys, passwords, or notes.
1. **User Input:** User enters data (e.g., `API_KEY=12345`) into the client form.
2. **Client Encryption:** The App (Tauri/Flutter) generates a random IV and encrypts the payload using the user's Master Key *in memory*.
3. **Payload Construction:** Client creates a JSON payload: `{"iv": "...", "data": "encrypted_blob...", "type": "manual"}`.
4. **Sync:** Client POSTs the payload to PostgREST.
5. **Storage:** Database stores the blob. The server never sees `12345`.
### B. Automated Rotation (Enhancement)
1. **Trigger:** Cron job in Node.js wakes up.
2. **Execution:** Connects to provider (e.g., AWS), generates new keys.
3. **Encryption:** *Note: This requires a separate "Server-Side Vault" mechanism or Public Key encryption if the server needs to write secrets readable by the user.*
4. **Update:** Updates the `secrets` row with the new encrypted blob.
---
## 4. Cryptography Standards
* **KDF:** Argon2id (memory-hard) for deriving Master Key.
* **Symmetric:** AES-256-GCM or XChaCha20-Poly1305 for vault data.
* **Asymmetric:** RSA-4096 or ECC (Curve25519) for sharing secrets between users.
* **Transport:** TLS 1.3 only.
---
## 5. Infrastructure (Docker Compose Prototype)
*Note: Switched to official Redis images due to Bitnami Docker Hub deprecation.*
```yaml
version: '3.9'
services:
# Load Balancer / SSL Termination
gateway:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
depends_on:
- api
- postgrest
# The Logic Core
api:
image: node:24-alpine
environment:
- DATABASE_URL=postgres://user:pass@db:5432/secrets_db
- REDIS_URL=redis://redis:6379
- JWT_SECRET=${JWT_SECRET}
# The Data Interface
postgrest:
image: postgrest/postgrest:latest
environment:
- PGRST_DB_URI=postgres://user:pass@db:5432/secrets_db
- PGRST_JWT_SECRET=${JWT_SECRET}
- PGRST_DB_SCHEMA=api
- PGRST_DB_ANON_ROLE=web_anon
# The Vault
db:
image: postgres:18
volumes:
- pg_data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=secrets_db
- POSTGRES_PASSWORD=${DB_PASSWORD}
# The High-Speed State (Official Image)
# For a full cluster in dev, you may need a custom entrypoint or sidecar
# to bootstrap the slots. For simplicity here, we use a standalone instance
# that mimics the interface.
redis:
image: redis:alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data