Docs/ Sécurité/ Gestion des secrets

Gestion des secrets

Stockez et gérez les valeurs de configuration sensibles avec le chiffrement AES-256-GCM, un accès délimité et une rotation sans interruption.

Comment sh0 chiffre les secrets

Tous les secrets (variables d'environnement marquées comme sensibles) sont chiffrés au repos dans la base de données SQLite de sh0 avec le chiffrement authentifié AES-256-GCM, propulsé par la bibliothèque de cryptographie ring.

Le flux de chiffrement :

  1. Une clé de chiffrement unique de 256 bits est générée lors de l'installation de sh0 et stockée dans le répertoire de configuration du serveur.
  2. Chaque valeur de secret est chiffrée avec un nonce unique (aléatoire 96 bits), garantissant que des valeurs identiques produisent des chiffrements différents.
  3. Le tag d'authentification (GCM) garantit que les secrets ne peuvent pas être altérés sans détection.
  4. Les secrets ne sont déchiffrés en mémoire que lorsqu'ils sont injectés dans les conteneurs au démarrage.
Note
Les valeurs des secrets ne sont jamais journalisées, jamais incluses dans les réponses API (seul le nom de la clé est retourné) et jamais visibles dans le tableau de bord après la création. Vous pouvez écraser un secret mais ne pouvez pas lire sa valeur actuelle.

Ajout de secrets via le tableau de bord

La façon la plus courante de gérer les secrets est via le panneau Variables d'environnement du tableau de bord.

  1. Accédez à votre application et ouvrez Paramètres → Variables d'environnement.
  2. Cliquez sur Ajouter une variable.
  3. Saisissez le nom de la variable (par ex., DATABASE_URL).
  4. Saisissez la valeur.
  5. Activez Secret pour chiffrer la valeur (activé par défaut pour les schémas courants comme _KEY, _SECRET, _PASSWORD, _TOKEN).
  6. Cliquez sur Enregistrer.
Panneau des variables d'environnement avec le formulaire d'ajout de variable

Via l'API :

Terminal
curl -X POST https://your-server:9000/api/apps/my-app/env \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "DATABASE_URL",
    "value": "postgres://user:pass@db:5432/mydb",
    "is_secret": true
  }'
Tip
Les modifications des variables d'environnement nécessitent un redéploiement pour prendre effet. sh0 vous proposera de redéployer après l'enregistrement des modifications, ou vous pouvez les appliquer manuellement.

Import en masse depuis un fichier .env

Si vous avez un fichier .env existant, vous pouvez importer toutes les variables en une fois.

  1. Dans le panneau Variables d'environnement, cliquez sur Import en masse.
  2. Collez le contenu de votre fichier .env ou uploadez-le directement.
  3. sh0 analyse le fichier et affiche un aperçu de toutes les variables.
  4. Vérifiez, marquez les valeurs sensibles comme secrets et cliquez sur Importer.
Boîte de dialogue d'import en masse montrant le contenu du fichier .env analysé

L'analyseur prend en charge la syntaxe .env standard :

.env
# Database
DATABASE_URL=postgres://user:pass@db:5432/mydb
REDIS_URL=redis://redis:6379

# API Keys
STRIPE_SECRET_KEY=sk_live_abc123
SENDGRID_API_KEY=SG.xyz789

# App Config
NODE_ENV=production
PORT=3000
Warning
L'import en masse écrasera les variables existantes portant le même nom. Les variables non présentes dans le fichier d'import ne sont pas modifiées.

Portée des secrets

Les secrets peuvent être délimités à deux niveaux, vous donnant le contrôle sur quels conteneurs ont accès à quelles valeurs.

Secrets au niveau du stack

Les secrets au niveau du stack sont partagés entre tous les services d'un stack. C'est idéal pour la configuration partagée comme les identifiants de base de données dont plusieurs services ont besoin.

Variables d'environnement au niveau du stack partagées entre tous les services

Définissez un secret au niveau du stack depuis Paramètres du stack → Variables d'environnement, ou via l'API :

Terminal
curl -X POST https://your-server:9000/api/stacks/my-stack/env \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "key": "DATABASE_URL",
    "value": "postgres://user:pass@db:5432/mydb",
    "is_secret": true
  }'

Secrets au niveau de l'application

Les secrets au niveau de l'application sont spécifiques à un seul service. Ils ont priorité sur les secrets au niveau du stack portant le même nom, vous permettant de remplacer les valeurs partagées pour des services individuels.

Note
Ordre de priorité : Les variables au niveau de l'application remplacent les variables au niveau du stack. Si les deux définissent DATABASE_URL, la valeur au niveau de l'application est utilisée pour ce service spécifique.

Rotation des secrets

La rotation d'un secret signifie mettre à jour sa valeur et redéployer les conteneurs affectés. sh0 rend ce processus transparent :

  1. Mettez à jour la valeur du secret dans le tableau de bord ou via l'API.
  2. sh0 déclenche un déploiement blue-green avec la nouvelle valeur.
  3. Les anciens conteneurs continuent de servir le trafic jusqu'à ce que les nouveaux soient sains.
  4. Une fois sains, le trafic bascule vers les nouveaux conteneurs sans interruption.
Terminal
curl -X PUT https://your-server:9000/api/apps/my-app/env/STRIPE_SECRET_KEY \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "value": "sk_live_new_key_456",
    "redeploy": true
  }'
Rotation de secret avec déploiement blue-green en cours
Tip
Pour la rotation du mot de passe de base de données, mettez d'abord à jour le mot de passe dans la base de données, puis mettez à jour le secret dans sh0 et redéployez. Cet ordre évite les échecs de connexion pendant la transition.

Accès aux secrets dans les conteneurs

Les secrets sont injectés dans les conteneurs en tant que variables d'environnement standard. Votre application y accède de la même manière qu'à n'importe quelle variable d'environnement :

Node.js
const dbUrl = process.env.DATABASE_URL;
const stripeKey = process.env.STRIPE_SECRET_KEY;
Python
import os
db_url = os.environ["DATABASE_URL"]
stripe_key = os.environ["STRIPE_SECRET_KEY"]
Rust
let db_url = std::env::var("DATABASE_URL")?;
let stripe_key = std::env::var("STRIPE_SECRET_KEY")?;

Les secrets sont définis au démarrage du conteneur et restent disponibles pendant toute la durée de vie du conteneur. Ils ne sont pas écrits sur le disque à l'intérieur du conteneur.

Danger
Ne journalisez jamais les variables d'environnement et ne les incluez jamais dans les rapports d'erreur. Bien que sh0 protège les secrets au repos et en transit, votre code applicatif doit également les gérer de manière responsable.