Skip to main content

Secrets avec SOPS

Comment Tale chiffre les clés de fournisseurs sur disque avec SOPS et age, les trois modes de stockage et le walk complet de rotation de clé.

3 min read

Tale stocke les clés API des fournisseurs dans des fichiers providers/*.secrets.json sur disque. Le mode par défaut après tale init chiffre ces fichiers avec SOPS en utilisant une clé age ; un mode alternatif lit plusieurs clés depuis un fichier (le chemin de rotation) ; un troisième mode garde les fichiers en clair au mode 0600 pour les environnements où le disque est chiffré au repos et où la rotation est gérée en externe. Cette page est le walkthrough opérateur des trois modes et du chemin de rotation sûr.

Les variables d'env qui pilotent les modes sont SOPS_AGE_KEY et SOPS_AGE_KEY_FILE — leurs lignes de référence vivent dans Référence des variables d'environnement. Cette page est la version plus longue.

Les trois modes

ModeVariables d'envQuand utiliser
Clé age inlineSOPS_AGE_KEY=AGE-SECRET-KEY-1...Défaut après tale init. Hôte unique, clé unique.
Fichier de clésSOPS_AGE_KEY_FILE=/path/to/keysRequis pour la rotation. Une clé age par ligne, commentaires #.
Clair à 0600Les deux non définisDisque chiffré au repos, ou outillage externe écrit les fichiers.

Le conteneur plateforme choisit le mode au boot. La forme inline est la plus simple ; la forme fichier est la seule qui supporte plusieurs lecteurs (ce qui rend la rotation possible sans downtime) ; la forme en clair saute SOPS entièrement et fait confiance au système de fichiers.

Mode chiffré au premier boot

tale init génère une paire de clés age et écrit la moitié privée dans SOPS_AGE_KEY de ton .env. Les fichiers de secret de fournisseur écrits via Paramètres > Fournisseurs sont chiffrés à la sauvegarde :

bash
# Inspecte — le fichier est du JSON SOPS-chiffré, pas la clé API en clair
cat providers/openai.secrets.json
# {
#   "apiKey": "ENC[AES256_GCM,data:...,iv:...,tag:...]",
#   "sops": { ... }
# }

Le déchiffrement se passe in-process quand le conteneur plateforme lit le fichier. La clé age ne quitte jamais la mémoire du conteneur plateforme.

Faire tourner la clé age

La rotation est le seul chemin que la forme inline ne couvre pas — seul SOPS_AGE_KEY_FILE te laisse accepter du ciphertext lisible par l'ancienne et la nouvelle clé pendant le cutover. Le walk :

bash
# 1. Génère une nouvelle clé age
age-keygen -o /etc/tale/age-keys.txt

# 2. Ajoute la nouvelle clé comme deuxième ligne dans le fichier
echo "AGE-SECRET-KEY-1NEW..." >> /etc/tale/age-keys.txt

# 3. Pointe .env sur le fichier et redémarre le conteneur plateforme
sed -i 's|^SOPS_AGE_KEY=.*|# SOPS_AGE_KEY=|' .env
sed -i 's|^# SOPS_AGE_KEY_FILE=.*|SOPS_AGE_KEY_FILE=/etc/tale/age-keys.txt|' .env
docker compose restart tale-platform tale-convex

Maintenant l'ancienne et la nouvelle clé peuvent déchiffrer les fichiers existants. Re-sauvegarde la clé API de chaque fournisseur sous Paramètres > Fournisseurs — chaque sauvegarde produit du ciphertext lisible par les deux clés. Une fois que chaque fournisseur a été re-sauvegardé (la colonne Dernière rotation dans le tableau des fournisseurs te dit lesquels tiennent encore l'ancien ciphertext), retire l'ancienne clé du fichier :

bash
# 4. Drop la ligne de l'ancienne clé et redémarre à nouveau
sed -i '/^AGE-SECRET-KEY-1OLD/d' /etc/tale/age-keys.txt
docker compose restart tale-platform tale-convex

L'ordre est porteur : ne retire jamais l'ancienne clé avant que chaque fichier soit re-chiffré, sinon le conteneur plateforme échouera à lire les fichiers encore-anciens au prochain déchiffrement.

Basculer en clair

Quand le disque hôte est chiffré au repos (LUKS, chiffrement AWS EBS, GCP CSEK) et que tu ne veux pas d'une deuxième couche de gestion de clés, le mode en clair est l'option supportée. Commente SOPS_AGE_KEY et SOPS_AGE_KEY_FILE, redémarre et re-sauvegarde chaque fournisseur — les fichiers sont maintenant du JSON au mode 0600.

Le modèle de risque change : un dump de système de fichiers leaké est maintenant un dump de credentials leaké. Choisis ce mode seulement quand le chiffrement de disque est réel (pas une case à cocher) et audite l'histoire de backup de l'hôte pour confirmer qu'aucun snapshot en clair n'échappe.

Stores de secret externes

Pour Vault, les mounts de Kubernetes Secret, ou systemd LoadCredential, le pattern supporté est : écris les fichiers *.secrets.json en clair depuis le store externe et fais tourner Tale en mode clair. Ne sauvegarde pas de clés de fournisseur via l'UI dans ce setup — l'UI écraserait le mount.

Où cela s'inscrit

Cette page est le guide opérateur complet de la couche SOPS ; les lignes de référence de variables d'env sont dans Référence des variables d'environnement, et le format des fichiers fournisseur lui-même dans Fournisseurs. Si une clé est leakée, la rotation est le même walk ci-dessus exécuté en urgence.

© 2026 Tale by Ruler GmbH — ISO 27001 & SOC 2 certified.

Tale is MIT licensed — free to use, modify, and distribute.