56 lines
3.7 KiB
Markdown
56 lines
3.7 KiB
Markdown
# DSH VPS — Rotation des cles API et incident « API key is invalid »
|
|
|
|
**Instance auteur** : hermes-nyora
|
|
**Date** : 2026-08-25
|
|
**Tags** : dsh, vps-contabo, docker, secrets, rotation, bifrost, opencode
|
|
**Statut** : clos — rotation complete, revocation confirmee, tour UI web verifie au vert
|
|
|
|
---
|
|
|
|
## Contexte
|
|
|
|
Rotation des deux cles du dsh-vps (VK Bifrost `sk-bf-37***` + cle OpenCode Zen `sk-DWb***`) apres double exposition : passage par canal de chat (Telegram) ET commit initial du depot `bolbol/dsh-vps` (22a18ae) embarquant les valeurs reelles en fallback heredoc de `entrypoint.sh` et en dur dans `docker-compose.yml`.
|
|
|
|
Rotation executee par Nabil via script local (saisie `read -s`, valeurs jamais passees par un canal) : ecriture atomique de `$DSH_HOME/.credentials.yaml` (volume `dsh_vps_home`) + `.env` projet.
|
|
|
|
## L'incident (25/08)
|
|
|
|
Apres rotation : « This turn failed — API key is invalid » dans l'UI web DSH, alors que tous les fichiers de configuration semblaient a jour.
|
|
|
|
Diagnostic structure (mission Gemini, cadrage hermes-nyora, 3 hypotheses a discriminer) :
|
|
|
|
| Hypothese | Test | Verdict |
|
|
|---|---|---|
|
|
| H1 session navigateur perimee | sonde headless echouait aussi (401 AuthError) | eliminee |
|
|
| H2 process demarre avant la rotation | StartedAt conteneur < rotation, ENV conteneur = anciennes cles | confirnee partielle |
|
|
| H3 residus de configuration | cles revoquees EN DUR dans `docker-compose.yml` hote + `entrypoint.sh` | cause racine |
|
|
|
|
**Piege de verification central** : le depot Gitea montrait les valeurs tronquees (`sk-bf-...e9d4`, sanitisation manuelle lors du commit) mais le fichier REEL sur l'hote portait les cles completes. Les preuves du premier rapport portaient sur le repo, le runtime lisait l'hote.
|
|
|
|
## Fix final
|
|
|
|
1. Cles externalisees dans `/home/dsh-agent/dsh-vps/.env` (chmod 600, couvert par `*.env` du .gitignore), injection via `env_file:` (commit 7cdda5d).
|
|
2. Fallbacks interdits : `${VAR:-sk-reelle}` remplace par `${VAR:?variable manquante}` partout (commit 7cdf4c1) — le scaffold echoue bruyamment plutot que de demarrer avec une vieille valeur.
|
|
3. `docker compose up -d --build` (recreation, pas restart), prefixes ENV du conteneur verifies alignes sur `.env`.
|
|
4. `verify-dsh.sh` durci : `process.exit` explicite sur les tests node http sinon un test echoue peut passer vert (commit e9ef336).
|
|
5. Revocation des anciennes cles : admin Bifrost (VK) + dashboard OpenCode — confirmee par Nabil.
|
|
6. Validation finale : session UI web NEUVE, tour reel reussi (le symptome initial reproduit au vert).
|
|
|
|
## Ce qui ne fonctionne PAS
|
|
|
|
| Tentative | Resultat | Raison |
|
|
|---|---|---|
|
|
| `docker compose restart` apres changement de cles | anciennes vars conservees | restart ne relit NI le `.env` NI le compose |
|
|
| Sanitiser uniquement rapports/preuves | secrets vivants dans les fichiers scaffoldes | lire INTEGRALEMENT chaque fichier qui entre en Git |
|
|
| Diagnostiquer depuis des curls externes seuls | ne voit pas ce que le process charge | comparer StartedAt vs horodatages config + printenv DANS le conteneur |
|
|
|
|
## Regle fleet-wide associee
|
|
|
|
Posee dans context-hub (scope infra, cle `secrets_rule`, relue en live le 25/08) : aucune valeur de cle/secret en clair dans un message, rapport ou mail. Depot obligatoire dans `/volume1/docker/.secrets-staging/<projet>.env` (hors git), reference par chemin uniquement. Reproduite dans l'`AGENTS.md` du workspace DSH (mecanisme natif `dsh-agent-instructions`).
|
|
|
|
## References
|
|
|
|
- Depots : `bolbol/dsh-vps` (22a18ae → 43c5dec), `bolbol/context-hub` (e7f78f8, lecon coding-bp-0001)
|
|
- Script de rotation : `workspace/scripts/rotate-dsh-keys.sh` (hermes-nyora)
|
|
- Garde-fou rejouable : `.agents/verify-dsh.sh` (5 tests : pnpm, plugin, MCP authentifie, isolation 403, nettoyage skill mort)
|