- .gitignore: Secrets (.env, *.key, *.pem) + Coverage + Temp-Verzeichnisse - .env.example: Template ohne echte Werte, mit Anleitung - scripts/token-gen.mjs: HMAC-Bearer-Token-Generator - package.json: token-gen + build:twa Scripts - docs/SECRETS.md: komplette Anleitung - Lokale Entwicklung (.env) - CI (gitea-Repository-Secrets) - age-Verschluesselung als optionale Schicht - Was NIE tun / was IMMER tun - Incident-Response bei geleaktem Secret Verifiziert: - token-gen erzeugt Token korrekt (stderr: Token gueltig...) - 122/122 Tests gruen - .env.example im Repo, .env ist gitignored
5.7 KiB
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
# 1. Template kopieren
Copy-Item .env.example .env
# 2. .env editieren und echte Werte einsetzen
notepad .env
# Bash:
cp .env.example .env
nano .env
Inhalt (Beispiel)
# 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:
- System-Env-Variablen werden automatisch von Node.js gelesen (
process.env) - PowerShell:
$env:MINIMAX_API_KEY = "sk-..."setzt für die aktuelle Session - Bash:
export MINIMAX_API_KEY=sk-...setzt für die aktuelle Session .envist NICHT automatisch geladen — wenn dunode bin/mindomat.mjsdirekt aufrufst, musst du die Env-Variable vorher setzen
Automatisches Laden (optional)
Wenn du dotenv als dev-Dependency willst:
npm install --save-dev dotenv
Dann in bin/mindomat.mjs:
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:
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:
# 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>
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:
Setup
# 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.ageist im Git, aber verschlüsselt (öffentlich lesbar, aber nicht entschlüsselbar ohnekey.txt)- Funktioniert in CI ohne externe Secret-Stores
key.txtbleibt in deinem lokalen~/.ssh/age/oder in CI-Secret-Storage
Nachteile
- Komplexer als Env-Variablen
key.txtmuss 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.jsonodersrc/hardcoden - ❌
.envins 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
- ✅
.envaus.env.examplelokal erstellen - ✅ Secrets über PowerShell
$env:...oder Bashexport ...setzen - ✅ Für CI: gitea-Repository-Secrets nutzen
- ✅ Vor jedem Commit:
git statusundgit diffprüfen, dass keine Secrets drin sind - ✅ Falls ein Secret geleakt wurde: sofort widerrufen und neu generieren
7. Falls ein Secret geleakt wurde
- Sofort widerrufen im jeweiligen Service (Minimax-Console, gitea, etc.)
- Neuen Key generieren
- Aus Git-History entfernen (mit
git filter-repooder BFG Repo-Cleaner) - Force-Push zum Remote (falls öffentlich: alle Klone sind kompromittiert)
- Alle Verbraucher aktualisieren (CI-Secrets, lokale
.env-Dateien) - Audit-Log prüfen, ob der geleakte Key bereits missbraucht wurde
Im Worst-Case: Vault-Daten neu anlegen, alle Tokens rotieren.