---
tags: [note, Securite]
type: "note"
nature: documentation # Options : portrait, lieu, info, concept, script, process, tuto, none
ressource: true
univers: PERSO
projects:
  - "[[03_PROJETS/VPS-IA]]"
date: "[[01_JOURNAL/2026/2026-10-14]]"
priority: 10
description: "Coffre pass + GPG + git pour les secrets OpenCode, remplaçant les tokens partagés en clair."
---
# Installation gestionnaire de secrets OpenCode (pass + GPG + git)

## Contexte

Lors d'échanges précédents, des tokens et mots de passe ont été partagés en clair dans les conversations — mauvaise pratique (exposition dans les logs/historique). Décision : mettre en place un **coffre de secrets chiffré, auto-hébergé, en CLI** pour les secrets dédiés à OpenCode (tokens MCP, clés d'API). Les mots de passe personnels restent dans KeePass (fichier **non partagé**).

## Choix retenu

**`pass` (password-store) + GPG + git** — solution open source, ultra légère, 100% CLI :
- Chaque secret = 1 fichier chiffré GPG (ed25519/cv25519)
- Historique & synchro via **git** (remote possible : Forgejo/Gitea auto-hébergé)
- Format ouvert → **migration facile vers gopass** (compatible direct) ou KeePass/Bitwarden/Vaultwarden (scripts d'export)

## Installation réalisée (2026-10-14)

Environnement : utilisateur `opencode` (HOME=/var/lib/opencode), Debian 12, pas de root → install utilisateur.

| Élément | Valeur |
|---|---|
| Binaire `pass` | `~/.local/bin/pass` (v1.7.4, script officiel) + lien `~/.opencode/bin/pass` |
| Shim `tree` | `~/.local/bin/tree` (émulation légère, `tree` absent et pas de root) |
| Clé GPG | ed25519, `C85C2EC80F887A88AB0015DB609911C3EA7D76C5`, `secrets@opencode.local`, sans passphrase, sans expiration |
| Coffre | `~/.password-store/` (perm. 700), git initialisé, identité `OpenCode Secrets <opencode@datagrandest.net>` |
| Sauvegarde | `~/.local/share/opencode-secrets/` + copie clé chiffrée AES-256 poussée dans le dépôt Forgejo `vps-passwords` (`backup-opencode-secrets-key.gpg`) |
| Script | `~/.opencode/bin/opencode-secrets.sh` → `backup` / `restore` |

## Règles d'usage

1. **Jamais de secret en clair dans une conversation** : l'agent référence l'emplacement (`pass show opencode/mcp-github-token`) et injecte via substitution shell :
   ```bash
   pass show opencode/mcp-github-token   # → affiche le secret (usage local)
   # injection directe sans affichage :
   opencode mcp add github --env GITHUB_TOKEN="$(pass show opencode/mcp-github-token)"
   ```
2. Hiérarchie proposée : `opencode/mcp-<service>`, `opencode/api-<service>`, `opencode/sb-token`…
3. `pass generate opencode/mcp-<service> <longueur>` pour générer un secret fort (jamais affiché).

## Migration des secrets existants (2026-10-14)

Secrets qui étaient en clair (config systemd / fichiers), désormais dans le coffre pass :

| Secret | Emplacement précédent | Entrée pass |
|---|---|---|
| Token SilverBullet (`sbt_…`) | `/etc/systemd/…/memory.conf` + `~/.silverbullet-token` | `opencode/sb-token` |
| Clé API Grist | `/etc/systemd/…/memory.conf` | `opencode/grist-api-key` |
| Mot de passe serveur OpenCode | `/etc/systemd/opencode.service` + `service.json` | `opencode/server-password` |

Scripts ajoutés (committés dans `vps-opencode`) :
- `~/.opencode/bin/sb-token.sh` : token SB depuis le coffre (repli `~/.silverbullet-token`)
- `~/.opencode/bin/opencode-secrets-env.sh` : exporte les 3 secrets depuis pass
- `~/.opencode/bin/opencode-serve.sh` : wrapper de lancement du serveur (secrets depuis pass)
- `sync-silverbullet.sh` / `sb-tasks-open.sh` : lisent le token via `sb-token.sh`

Le **refactor systemd** (purger les secrets en clair des unités) est en attente — nécessite root (commandes en fin de note).

## ⚠️ Sécurité & sauvegarde

- Clé GPG **sans passphrase** (choix pragmatique pour scripts headless) → le coffre protège contre l'exposition accidentelle (permissions 700/600), pas contre une compromission totale du serveur. Renforcement possible : `gpg --passwd`.
- **Sauvegarde hors serveur (faite le 2026-10-14)** : clé privée chiffrée **AES-256** (`backup-opencode-secrets-key.gpg`) poussée dans le dépôt Forgejo `vps-passwords`, **phrase de passe stockée dans KeePass (utilisateur)**. Restauration :
  1. Clone `vps-passwords` → récupérer `backup-opencode-secrets-key.gpg` + coffre
  2. `gpg --decrypt backup-opencode-secrets-key.gpg > opencode-secrets.asc` (phrase de passe = KeePass)
  3. `gpg --import opencode-secrets.asc`
  4. Restaurer `~/.password-store`
- Certificat de révocation : `~/.gnupg/openpgp-revocs.d/C85C2EC80F887A88AB0015DB609911C3EA7D76C5.rev`.
- Commandes utiles : `~/.opencode/bin/opencode-secrets.sh backup` / `restore`.

## Refactor systemd — commandes (à exécuter en root)

Objectif : plus aucun secret en clair dans `/etc/systemd/`.

```bash
# 1. Lancer le serveur via le wrapper (injecte les secrets depuis pass)
sudo systemctl edit --full opencode.service
#    → remplacer la ligne Environment="OPENCODE_SERVER_PASSWORD=..." et ExecStart par :
#      ExecStart=/var/lib/opencode/.opencode/bin/opencode-serve.sh

# 2. Purger les tokens de memory.conf (garder les limites mémoire)
sudo nano /etc/systemd/system/opencode.service.d/memory.conf
#    → supprimer les 2 lignes Environment="SB_AUTH_TOKEN=..." et Environment="GRIST_API_KEY=..."

# 3. Recharger + redémarrer
sudo systemctl daemon-reload
sudo systemctl restart opencode.service
sudo systemctl status opencode.service
```

Vérifier ensuite que le serveur répond (port 49374) et que les MCP se connectent.


## Rotation des secrets exposés dans Open Code

**Objectif** : régénérer les 3 secrets (token SB, clé Grist, mot de passe serveur) pour neutraliser les copies en clair encore présentes dans l'historique Open Code (6 sessions + log).

### 1. Régénérer les nouvelles valeurs à la source

Générer une nouvelle valeur **dans chaque application** (interface web) :
- **Grist** → profil/utilisateur → **API Key** (générer une nouvelle clé, révoquer l'ancienne)
- **SilverBullet** → application SilverBullet → nouveau token `sbt_...`
- **Mot de passe serveur OpenCode** → choisir une nouvelle valeur

> Aucune valeur ne doit transiter par une conversation : tout se passe côté applications, puis insertion interactive ci-dessous.

### 2. Insérer les nouvelles valeurs dans le coffre pass (en root)

```sh
# en root, génère la nouvelle valeur puis insère-la en interactif (rien n'est affiché/loggé)
sudo -u opencode /var/lib/opencode/.local/bin/pass insert opencode/sb-token
sudo -u opencode /var/lib/opencode/.local/bin/pass insert opencode/grist-api-key
sudo -u opencode /var/lib/opencode/.local/bin/pass insert opencode/server-password
```

> Pour le **mot de passe serveur**, mettre aussi à jour `~/.config/opencode/service.json` (client CLI) avec la même valeur (sinon le client ne pourra plus se connecter au serveur).

### 3. Redémarrer le service pour prise d'effet

```sh
sudo systemctl restart opencode.service
```

Vérifier : `systemctl is-active opencode.service` puis se reconnecter à l'interface web avec la nouvelle valeur.

### 4. (Optionnel) Nettoyer l'historique

Une fois les nouvelles valeurs actives, les anciennes deviennent inutiles : supprimer les anciennes sessions (`opencode session delete <id>`) et purger le log.

## Suivi

- [x] Remote git Forgejo `vps-passwords` pour la synchro du coffre (poussé)
- [x] Migration des secrets en clair vers le coffre (sb-token, grist-api-key, server-password)
- [x] Skills/agents mis à jour (silverbullet-api + vps-admin) : source du token = coffre
- [x] **Refactor systemd (root)** : secrets purgés des unités, serveur lancé via `opencode-serve.sh` (vérifié le 2026-10-15)
- [ ] **Rotation des secrets exposés dans l'historique OpenCode (DIFFÉRÉE)** : token SB, clé Grist et mot de passe serveur restent inchangés. 6 sessions + log contiennent des fragments en clair (valeurs encore valides). À faire plus tard via `sudo -u opencode pass insert` (jamais en clair dans une conversation).
- [ ] (Option) Passer la clé GPG sous passphrase
