security: runbook cles API en dur + rotation BIFROST_API_KEY dsh-vps
This commit is contained in:
@@ -0,0 +1,54 @@
|
|||||||
|
# Cles API en dur dans un repo Gitea nouvellement cree — incident et fix
|
||||||
|
|
||||||
|
**Instance auteur** : hermes-nyora (detection) + Claude (remediation)
|
||||||
|
**Date** : 2026-08-24
|
||||||
|
**Tags** : securite, git, secrets, dsh-vps, bifrost
|
||||||
|
**Statut** : clos pour BIFROST_API_KEY, ouvert pour OPENCODE_DIRECT_API_KEY (action Nabil)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Ce qui s'est passe
|
||||||
|
|
||||||
|
Lors de l'initialisation du depot `bolbol/dsh-vps` (commit initial, mission bridge MCP DSH), `entrypoint.sh` a ete commite avec deux secrets reels en fallback shell :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BIFROST_API_KEY: ${BIFROST_API_KEY:-sk-bf-3727af3c-c4e9-43f5-a6b1-08beb1dae9d4}
|
||||||
|
OPENCODE_DIRECT_API_KEY: ${OPENCODE_DIRECT_API_KEY:-sk-DWbZ2mr6UvFnWH8P6ZhsUjc6LJXtvJSY8mdYdSOueyGSwFn6LZRjUNzuazc5nGkK}
|
||||||
|
```
|
||||||
|
|
||||||
|
Le meme fichier gerait deja `CONTEXT_HUB_API_KEY` correctement (sourcee depuis `$DSH_HOME/.env`, jamais en dur) — le pattern correct existait a cote du pattern fautif, dans le meme fichier.
|
||||||
|
|
||||||
|
Aggravant : le depot avait ete cree en **visibilite publique** sur le Gitea interne (`private: false`) — decouvert en verifiant, pas suppose.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Detection
|
||||||
|
|
||||||
|
hermes-nyora a relu `entrypoint.sh` sur `main` avant de valider une procedure et a trouve les deux cles en clair — reflexe de verification avant action, pas une alerte automatique.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Remediation appliquee
|
||||||
|
|
||||||
|
1. Repo passe en prive immediatement (`PATCH /api/v1/repos/bolbol/dsh-vps` avec `private: true`).
|
||||||
|
2. `BIFROST_API_KEY` (`vk-dsh-vps` dans `governance_virtual_keys` de Bifrost) rotee directement en base (`config.db`, backup avant modif, `value` + `value_hash` — SHA-256 du plaintext, verifie contre une cle existante avant d'ecrire). Ancienne valeur invalidee immediatement.
|
||||||
|
3. `$DSH_HOME/.env` et `.credentials.yaml` sur le conteneur dsh-vps mis a jour avec la nouvelle valeur, conteneur redemarre (`docker compose restart`, pas `up -d`), fonctionnement verifie par un vrai appel `chat/completions` reussi.
|
||||||
|
4. `entrypoint.sh` corrige (en parallele par Gemini) : `${VAR:-secret}` -> `${VAR:?variable manquante}`, echec explicite au lieu d'un defaut dangereux.
|
||||||
|
|
||||||
|
`OPENCODE_DIRECT_API_KEY` reste en l'etat — c'est en realite `BIFROST_OPENCODE_KEY`, la cle maitresse OpenCode.ai partagee par tout Bifrost, pas une cle scopee comme `BIFROST_API_KEY`. Rotation hors de portee de Claude (compte SaaS externe), necessite Nabil.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Piege identifie a generaliser
|
||||||
|
|
||||||
|
Un fichier peut contenir a la fois le bon pattern (`.env` source, jamais en dur) et le mauvais pattern (fallback litteral) **dans le meme script** — la presence d'un exemple correct ne garantit pas que tout le fichier suit la meme discipline. Toujours grep `sk-\|API_KEY.*:-\|_KEY.*=.*[A-Za-z0-9]\{20,\}` sur tout fichier avant un premier commit dans un nouveau depot.
|
||||||
|
|
||||||
|
Verifier la visibilite (`private`) d'un depot des sa creation, jamais supposer qu'un depot interne est prive par defaut.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reste a faire (Nabil)
|
||||||
|
|
||||||
|
- Rotation de `BIFROST_OPENCODE_KEY` sur le dashboard OpenCode.ai, puis mise a jour dans `hermes-platform/.env` et `$DSH_HOME/.env` de dsh-vps.
|
||||||
|
- Decision : garder `agent-default-model: opencode-direct/ox-alpha-free` (modele gratuit temporaire hors Bifrost, necessite la cle maitresse) ou basculer dsh-vps sur un modele Bifrost-only (`deepseek-v4-flash` via `vk-dsh-vps`, deja fonctionnel, deja scope).
|
||||||
|
- L'historique git du commit initial contient toujours les deux cles en clair — residuel tant que la seconde n'est pas rotee, meme depot prive.
|
||||||
Reference in New Issue
Block a user