Files
nas-runbooks/hermes-nyora/dsh-vps-secrets-en-dur-incident.md
T

3.4 KiB

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 :

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.