# Secrets und Credentials Diese Anleitung erklärt, wie du sensible Daten (API-Keys, Tokens, Passwörter) in Mind-o-Mat handhabst, ohne sie jemals in Git zu committen. ## Überblick Mind-o-Mat nutzt drei Arten von Secrets: | Secret | Wo gespeichert | Wer sieht es | |---|---|---| | **Minimax API-Key** | `.env` (lokal) / CI-Secret | nur Tool-Code zur Laufzeit | | **Notes-API Token** | `.env` (lokal) / CI-Secret | Browser + Tool | | **gitea-Credentials** | `git credential helper` / SSH-Key | nur `git push` | **Grundregel:** Secrets kommen in **`.env`** (gitignored) oder in **CI-Secrets** (verschlüsselt), niemals ins Repo. ## 1. Lokale Entwicklung: `.env`-Datei ### Einrichten ```powershell # 1. Template kopieren Copy-Item .env.example .env # 2. .env editieren und echte Werte einsetzen notepad .env ``` ```bash # Bash: cp .env.example .env nano .env ``` ### Inhalt (Beispiel) ```dotenv # Minimax API-Key (aus Minimax-Console) MINIMAX_API_KEY=sk-abc123... # Notes-API Auth (fuer Production-Deployment, optional) NOTES_API_TOKEN=my-secret-for-hmac NOTES_API_ALLOWED_ORIGINS=https://my-vault.example.com # Vault-Pfad (optional) MINDOMAT_VAULT_PATH=C:\GitHub\Mein-Vault ``` ### Wie der Code die Werte liest Das Tool nutzt **keine** `.env`-Loader-Library direkt. Stattdessen: 1. **System-Env-Variablen** werden automatisch von Node.js gelesen (`process.env`) 2. **PowerShell:** `$env:MINIMAX_API_KEY = "sk-..."` setzt für die aktuelle Session 3. **Bash:** `export MINIMAX_API_KEY=sk-...` setzt für die aktuelle Session 4. **`.env` ist NICHT automatisch geladen** — wenn du `node bin/mindomat.mjs` direkt aufrufst, musst du die Env-Variable vorher setzen ### Automatisches Laden (optional) Wenn du `dotenv` als dev-Dependency willst: ```bash npm install --save-dev dotenv ``` Dann in `bin/mindomat.mjs`: ```javascript import 'dotenv/config'; // ... rest ``` Aber das ist **nicht** nötig für die Standard-Verwendung. PowerShell-User rufen ohnehin direkt auf. ## 2. CI (gitea-Actions): Repository-Secrets In deiner gitea-Instanz: **Repository → Settings → Secrets → New Secret** Füge hinzu: | Name | Wert | |---|---| | `MINIMAX_API_KEY` | dein API-Key | | `NOTES_API_TOKEN` | dein HMAC-Secret | | `NOTES_API_ALLOWED_ORIGINS` | z. B. `https://vault.example.com` | In `.gitea/workflows/ci.yml`: ```yaml jobs: test: env: MINIMAX_API_KEY: ${{ secrets.MINIMAX_API_KEY }} ``` Die Secrets sind in CI verschlüsselt und werden zur Laufzeit als Env-Variablen bereitgestellt. ## 3. Notes-API Bearer-Token generieren Wenn du die Notes-API mit Auth nutzt, brauchst du Bearer-Tokens: ```powershell # 1. Secret setzen $env:NOTES_API_TOKEN = "my-secret" # 2. Token generieren npm run token-gen # Output: 1725523000000.4a7b2c1d... (Beispiel) # 3. Token in der Webapp nutzen # In .env: NOTES_API_TOKEN=my-secret # Beim Browser-Request: Authorization: Bearer ``` Token ist 1 Stunde gültig (Timestamp-basiert). Für längere Gültigkeit `timestamp` durch ein Ablauf-Datum ersetzen. ## 4. Optional: `age`-Verschlüsselung für CI Wenn du Secrets **verschlüsselt im Repo** speichern willst (z. B. für lokale CI ohne externe Secret-Store), nutze [`age`](https://github.com/FiloSottile/age): ### Setup ```bash # 1. age installieren # Windows: scoop install age # macOS: brew install age # Linux: apt install age # 2. Schluesselpaar generieren age-keygen -o key.txt # privater Schluessel (NICHT in Git!) mkdir -p .age age-keygen -y key.txt > .age/recipients.pub # oeffentlicher Schluessel (in Git) # 3. Secret verschluesseln $env:MINIMAX_API_KEY = "sk-abc123..." node -e " const { execSync } = require('node:child_process'); const value = process.env.MINIMAX_API_KEY; execSync('echo ' + value + ' | age -R .age/recipients.pub -o secrets.age', { stdio: 'inherit' }); " # 4. secrets.age committen (verschluesselt, sicher) git add secrets.age git commit -m "Add encrypted Minimax API key" # 5. Zur Laufzeit entschluesseln age -d -i key.txt secrets.age # in CI mit Secret-Storage fuer key.txt ``` ### Vorteile - `secrets.age` ist im Git, aber verschlüsselt (öffentlich lesbar, aber nicht entschlüsselbar ohne `key.txt`) - Funktioniert in CI ohne externe Secret-Stores - `key.txt` bleibt in deinem lokalen `~/.ssh/age/` oder in CI-Secret-Storage ### Nachteile - Komplexer als Env-Variablen - `key.txt` muss separat gesichert werden (sonst sind die Secrets verloren) **Empfehlung:** Nutze `age` NUR, wenn du Secrets im Repo versionieren willst (z. B. für Demo-Setups). Für Production-CI sind gitea-Repository-Secrets einfacher. ## 5. Was du NIEMALS tun solltest - ❌ API-Key direkt in `package.json` oder `src/` hardcoden - ❌ `.env` ins Git committen (ist in `.gitignore`, aber prüfe!) - ❌ Secrets in Commit-Messages oder PR-Beschreibungen erwähnen - ❌ Secrets in Screenshots oder Logs zeigen - ❌ Secrets in JSON-Dateien oder Markdown-Dateien im Repo ## 6. Was du TUN solltest - ✅ `.env` aus `.env.example` lokal erstellen - ✅ Secrets über PowerShell `$env:...` oder Bash `export ...` setzen - ✅ Für CI: gitea-Repository-Secrets nutzen - ✅ Vor jedem Commit: `git status` und `git diff` prüfen, dass keine Secrets drin sind - ✅ Falls ein Secret geleakt wurde: **sofort widerrufen** und neu generieren ## 7. Falls ein Secret geleakt wurde 1. **Sofort widerrufen** im jeweiligen Service (Minimax-Console, gitea, etc.) 2. **Neuen Key generieren** 3. **Aus Git-History entfernen** (mit `git filter-repo` oder BFG Repo-Cleaner) 4. **Force-Push** zum Remote (falls öffentlich: alle Klone sind kompromittiert) 5. **Alle Verbraucher aktualisieren** (CI-Secrets, lokale `.env`-Dateien) 6. **Audit-Log prüfen**, ob der geleakte Key bereits missbraucht wurde Im Worst-Case: Vault-Daten neu anlegen, alle Tokens rotieren.