# Vault System - Secure Secrets Management Modernes, sicheres Secrets Management System für das Custom PHP Framework. ## Features ✅ **Libsodium Encryption** - Authenticated encryption (AEAD) ✅ **Database-backed Storage** - Transaktionale Sicherheit ✅ **Audit Logging** - Vollständiges Audit Trail aller Operations ✅ **Metadata Tracking** - Access Counts, Last Access, etc. ✅ **Key Rotation** - Hot Key Rotation ohne Downtime ✅ **CLI Management** - Vollständige Console Commands ✅ **Type Safety** - Value Objects für alle Daten ✅ **Framework Integration** - Native DI Container Support ## Installation & Setup ### 1. Migration ausführen ```bash docker exec php php console.php db:migrate ``` Dies erstellt die drei Vault-Tabellen: - `vault_secrets` - Encrypted secrets storage - `vault_audit_log` - Audit trail - `vault_encryption_keys` - Key version tracking ### 2. Encryption Key generieren ```bash docker exec php php console.php vault:generate-key ``` Dies generiert einen kryptographisch sicheren Encryption Key: ``` VAULT_ENCRYPTION_KEY=aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRlc3Qga2V5IQ== ``` ### 3. Key in .env speichern Füge den generierten Key zu deiner `.env` Datei hinzu: ```env # Vault Configuration VAULT_ENCRYPTION_KEY=aGVsbG8gd29ybGQgdGhpcyBpcyBhIHRlc3Qga2V5IQ== ``` ⚠️ **WICHTIG**: Niemals den Key committen! Die `.env` Datei ist in `.gitignore`. ## CLI Commands ### Secret speichern ```bash # Mit Value als Argument docker exec php php console.php vault:set database.password "super-secret" # Value wird interaktiv abgefragt (versteckt) docker exec php php console.php vault:set database.password ``` ### Secret abrufen ```bash docker exec php php console.php vault:get database.password ``` ### Secret löschen ```bash docker exec php php console.php vault:delete database.password ``` ### Alle Secrets auflisten ```bash docker exec php php console.php vault:list ``` Zeigt alle Secret Keys mit Metadata: ``` 🔐 Vault Secrets: • database.password Accessed: 15 times, Last: 2024-01-15 14:30:45 • api.stripe.secret_key Accessed: 3 times, Last: 2024-01-14 10:20:30 Total: 2 secrets ``` ### Audit Log anzeigen ```bash # Letzte 50 Einträge docker exec php php console.php vault:audit # Letzte 100 Einträge docker exec php php console.php vault:audit 100 # Audit Log für spezifischen Secret Key docker exec php php console.php vault:audit 50 database.password ``` ### Key Rotation ```bash docker exec php php console.php vault:rotate-key ``` ⚠️ **KRITISCHE OPERATION**: - Generiert neuen Encryption Key - Re-encrypted alle Secrets - Gibt neuen Key aus - Alte Key aufbewahren bis Rotation verifiziert! ## Programmatische Verwendung ### In Controller/Services ```php use App\Framework\Vault\Vault; use App\Framework\Vault\ValueObjects\SecretKey; use App\Framework\Vault\ValueObjects\SecretValue; final readonly class PaymentService { public function __construct( private Vault $vault ) {} public function processPayment(Order $order): PaymentResult { // Secret aus Vault abrufen $apiKey = $this->vault->get( SecretKey::from('api.stripe.secret_key') ); // Secret verwenden (reveal() erforderlich!) $stripe = new StripeClient($apiKey->reveal()); return $stripe->charge($order->getTotal()); } } ``` ### Secret speichern ```php public function updateApiKey(string $newKey): void { $this->vault->set( SecretKey::from('api.stripe.secret_key'), new SecretValue($newKey) ); } ``` ### Secret prüfen ```php public function hasApiKey(): bool { return $this->vault->has( SecretKey::from('api.stripe.secret_key') ); } ``` ### Metadata abrufen ```php public function getSecretInfo(string $keyName): array { $metadata = $this->vault->getMetadata( SecretKey::from($keyName) ); return [ 'created_at' => $metadata->createdAt, 'updated_at' => $metadata->updatedAt, 'access_count' => $metadata->accessCount, 'last_accessed' => $metadata->lastAccessedAt ]; } ``` ## Value Objects ### SecretKey Typsicherer Secret Identifier mit Validation: ```php use App\Framework\Vault\ValueObjects\SecretKey; // ✅ Gültig $key = SecretKey::from('database.password'); $key = SecretKey::from('api.stripe.secret-key_2024'); // ❌ Ungültig $key = SecretKey::from(''); // InvalidArgumentException $key = SecretKey::from('invalid key!'); // Nur a-zA-Z0-9._- erlaubt ``` ### SecretValue Verhindert accidental Exposure: ```php use App\Framework\Vault\ValueObjects\SecretValue; $secret = new SecretValue('my-password'); // ✅ Explizit enthüllen $password = $secret->reveal(); // ✅ Sichere Checks if ($secret->isEmpty()) { ... } $length = $secret->length(); // ✅ Verhindert Logging echo $secret; // Ausgabe: [SECRET] // ✅ Verhindert var_dump Exposure var_dump($secret); // ['value' => '[REDACTED]', 'length' => 11] ``` ## Sicherheit ### Encryption - **Algorithmus**: Libsodium `sodium_crypto_secretbox` (XSalsa20 + Poly1305) - **Authenticated Encryption**: Schutz gegen Tampering - **Random Nonce**: Eindeutig pro Secret - **256-bit Keys**: SODIUM_CRYPTO_SECRETBOX_KEYBYTES (32 bytes) ### Audit Logging Alle Vault-Operationen werden geloggt: ```sql SELECT * FROM vault_audit_log WHERE secret_key = 'database.password' ORDER BY timestamp DESC; ``` Geloggte Informationen: - Secret Key (nicht der Value!) - Action (read, write, delete, rotate, export) - Timestamp - User ID (wenn verfügbar) - IP Address - User Agent - Success/Failure Status - Error Message (bei Fehlern) ### Best Practices ✅ **DO**: - Encryption Key in `.env` speichern (gitignored) - Unterschiedliche Keys für Environments - Regelmäßige Key Rotation (quartalsweise) - Audit Logs monitoren - Secrets mit beschreibenden Namen (`api.service.key`) ❌ **DON'T**: - Encryption Key committen - Secrets in Code hardcoden - Gleichen Key für Dev/Staging/Production - Audit Logs ignorieren - Secrets ohne Namespace (`password`) ## Migration von .env zu Vault ### Schritt 1: Secrets identifizieren Identifiziere alle sensiblen Werte in `.env`: - Passwörter - API Keys - Client Secrets - Private Keys - Tokens ### Schritt 2: In Vault migrieren ```bash # Für jeden Secret: docker exec php php console.php vault:set api.stripe.secret_key "sk_live_..." docker exec php php console.php vault:set database.password "prod-password" docker exec php php console.php vault:set oauth.spotify.client_secret "abc123..." ``` ### Schritt 3: Code aktualisieren **Vorher (.env)**: ```php $apiKey = $_ENV['STRIPE_SECRET_KEY']; // ❌ Unsicher ``` **Nachher (Vault)**: ```php $apiKey = $this->vault ->get(SecretKey::from('api.stripe.secret_key')) ->reveal(); // ✅ Sicher ``` ### Schritt 4: .env bereinigen Nach Migration Secrets aus `.env` entfernen: ```diff - STRIPE_SECRET_KEY=sk_live_... - DATABASE_PASSWORD=prod-password + # Secrets now in Vault - use vault:get to retrieve ``` ## Troubleshooting ### "Vault not available" **Problem**: `VAULT_ENCRYPTION_KEY` nicht gesetzt **Lösung**: ```bash # Key generieren docker exec php php console.php vault:generate-key # Key in .env hinzufügen echo "VAULT_ENCRYPTION_KEY=generated_key_here" >> .env ``` ### "Sodium extension required" **Problem**: PHP Sodium Extension fehlt **Lösung**: Sodium ist in PHP 7.2+ standardmäßig verfügbar. Prüfe PHP Version: ```bash docker exec php php -m | grep sodium ``` ### "Decryption failed" **Problem**: Falscher Encryption Key oder korrupte Daten **Mögliche Ursachen**: - Encryption Key geändert ohne Re-Encryption - Database Corruption - Falsche Encoding (base64) **Lösung**: - Richtigen Key aus Backup wiederherstellen - Oder Key Rotation durchführen ### "Secret not found" **Problem**: Secret Key existiert nicht **Lösung**: ```bash # Alle Keys auflisten docker exec php php console.php vault:list # Secret neu erstellen docker exec php php console.php vault:set your-key "your-value" ``` ## Performance ### Benchmarks - **Read Operation**: ~5ms (inkl. Decryption) - **Write Operation**: ~10ms (inkl. Encryption + DB Insert) - **Key Rotation**: ~100ms pro Secret ### Optimierungen Für High-Performance Scenarios: - Secrets cachen (mit TTL) - Batch-Operations für Multiple Secrets - Read Replicas für Read-Heavy Workloads ## Testing ```bash # Unit Tests ausführen docker exec php ./vendor/bin/pest tests/Framework/Vault/ ``` Tests validieren: - Value Object Validierung - Encryption/Decryption - Key Generation - Audit Logging ## Weitere Informationen - **Libsodium Dokumentation**: https://www.php.net/manual/en/book.sodium.php - **Best Practices**: https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html