Concepts
Gestion des secrets
Sources, fournisseurs externes, chiffrement, portée par action et injection sécurisée.
Xbee sépare la configuration partageable des valeurs sensibles. Le fichier
xbee-env.yaml décrit la forme du modèle et les actions ; le fichier
xbee-secret.yaml, placé à côté, fournit les valeurs ou les références permettant de
les récupérer.
Déclarer un secret
La structure de xbee-secret.yaml reprend les chemins du modèle à surcharger :
# xbee-secret.yaml
database:
password: env:DATABASE_PASSWORD
tls:
privateKey: file:secrets/server.keyLe fichier n’est pas destiné au contrôle de version. Xbee l’ajoute au .gitignore et
force ses permissions à 0600.
Quatre formes locales sont acceptées :
| Forme | Résultat |
|---|---|
une-valeur | Valeur littérale |
env:NOM | Contenu de la variable d’environnement NOM |
file:chemin | Contenu du fichier ; un chemin relatif part de xbee-secret.yaml |
literal:env:NOM | Valeur littérale env:NOM, sans résolution |
Les références sont paresseuses : leur valeur n’est récupérée que si l’action en cours utilise le secret. Une variable absente, un fichier inaccessible ou un fournisseur en erreur interrompt l’exécution concernée.
Utiliser un gestionnaire externe
Les credentials d’accès au gestionnaire restent sur la machine qui exécute xbee. Ils ne sont pas copiés dans le modèle, l’enveloppe ou le guest. Xbee appelle la CLI officielle correspondante et utilise son mécanisme d’authentification habituel.
HashiCorp Vault
Prérequis : la commande vault doit être installée et authentifiée, par exemple avec
VAULT_ADDR, VAULT_TOKEN ou la méthode de connexion configurée localement.
Syntaxe :
vault:<chemin-kv>#<champ>Exemple pour lire le champ password de secret/application :
# xbee-secret.yaml
database:
password: vault:secret/application#passwordXbee exécute l’équivalent de :
vault kv get -field=password secret/applicationLe fragment #champ est obligatoire. La version KV et le point de montage restent
gérés par la configuration de la CLI Vault et par le chemin fourni.
AWS Secrets Manager
Prérequis : la commande aws doit être installée. Elle peut utiliser un profil local,
des variables d’environnement, AWS SSO ou une identité de workload disponible sur la
machine contrôleur.
Syntaxe :
aws-sm:<identifiant-ou-ARN>[?region=<région>][#<champ-json>]Secret JSON stocké dans AWS Secrets Manager :
{"username":"app","password":"change-me"}Référence au seul champ password :
# xbee-secret.yaml
database:
username: aws-sm:production/database?region=eu-west-3#username
password: aws-sm:production/database?region=eu-west-3#passwordSans fragment #, xbee retourne la chaîne SecretString complète. Un fragment peut
désigner un chemin JSON imbriqué, par exemple #credentials.password. Les secrets
binaires AWS ne sont pas pris en charge par cette syntaxe.
Scaleway Secret Manager
Prérequis : la commande scw doit être installée et configurée. Elle utilise son
profil ou les variables SCW_ACCESS_KEY, SCW_SECRET_KEY et les valeurs par défaut de
région/projet.
Syntaxe :
scw-sm:<secret-id>[?region=<région>&revision=<version>][#<champ>]Exemple utilisant la dernière version disponible :
# xbee-secret.yaml
database:
password: scw-sm:11111111-1111-1111-1111-111111111111?region=fr-par#passwordExemple épinglé sur la révision 4 :
database:
password: scw-sm:11111111-1111-1111-1111-111111111111?region=fr-par&revision=4#passwordregion est facultatif si le profil Scaleway en définit une. revision vaut latest
par défaut. Le fragment #champ est facultatif pour un secret opaque et permet de
sélectionner un champ d’un secret JSON.
Injecter un secret dans une action
Un secret ne doit pas être interpolé directement dans shell.cmd : il apparaîtrait
potentiellement dans la liste des processus ou dans un diagnostic. Xbee refuse cette
forme :
# Refusé
shell: deploy --token {{ .api.token }}Utilisez secret-env pour une variable temporaire :
shell:
secret-env:
API_TOKEN: "{{ .api.token }}"
cmd:
- deploy --token "$API_TOKEN"Ou secret-file lorsqu’un programme attend un fichier :
shell:
secret-file:
- content: "{{ .tls.privateKey }}"
to: /run/xbee-secrets/server.key
mode: "0400"
cmd:
- server --private-key /run/xbee-secrets/server.keysecret-env utilise un fichier d’environnement temporaire en 0600. secret-file
crée sa cible exclusivement, refuse d’écraser un fichier existant et n’accepte que des
modes réservés au propriétaire. Xbee supprime ces fichiers à la fin de l’action, même
si celle-ci échoue. Une valeur secrète rendue directement dans un template est refusée
pour la même raison.
Cycle de vie interne
Le traitement suit les étapes suivantes :
- Xbee remplace chaque référence de
xbee-secret.yamlpar un jeton opaque. - Avant une action, il détermine les jetons réellement utilisés et ne résout que leurs fournisseurs.
- Il crée une enveloppe propre à cette exécution, chiffrée et authentifiée avec
AES-256-GCM et protégée en
0600. - Une nouvelle clé aléatoire est transmise au guest par l’entrée standard SSH ou Docker. Elle n’est placée ni dans un argument, ni dans une variable d’environnement, ni dans un fichier.
- Le guest déchiffre les valeurs en mémoire, exécute l’action, puis supprime la clé, l’enveloppe et les matérialisations temporaires.
Si l’action dépend de données connues uniquement dans le guest, xbee utilise un repli
conservateur limité au modèle de l’hôte concerné, ou au seul pack init. Ce repli est
signalé dans les logs et n’inclut jamais les secrets d’un autre hôte. Un jeton resté
hors de la portée autorisée bloque l’action.
Les valeurs sont enregistrées dans le mécanisme de masquage centralisé et apparaissent
comme ******** dans les logs xbee. Les jetons sont normalisés dans les hashes : une
rotation de secret ne change pas l’identité d’une image ou d’un pack.
Exemple complet
# xbee-secret.yaml
application:
apiToken: vault:secret/production/api#token
database:
password: aws-sm:production/database?region=eu-west-3#password
tls:
privateKey: scw-sm:11111111-1111-1111-1111-111111111111?region=fr-par# Extrait d'une action du pack
shell:
secret-env:
API_TOKEN: "{{ .application.apiToken }}"
DATABASE_PASSWORD: "{{ .database.password }}"
secret-file:
- content: "{{ .tls.privateKey }}"
to: /run/xbee-secrets/tls.key
mode: "0400"
cmd:
- application migrate
- application start --tls-key /run/xbee-secrets/tls.keySeuls les trois secrets référencés par cette action sont récupérés et transmis. Une
autre valeur présente dans xbee-secret.yaml mais inutilisée ne déclenche aucun appel
à son fournisseur.
Rotation et exploitation
- Une référence externe est relue pour chaque action qui l’utilise ; une rotation est donc visible lors de l’exécution suivante.
- Chaque appel fournisseur est limité à 30 secondes.
- Pour une rotation atomique sur plusieurs champs, préférez un unique objet JSON et épinglez une version lorsque le fournisseur le permet.
- Accordez à l’identité du contrôleur uniquement la permission de lire les chemins nécessaires.
- Évitez d’activer les traces verbeuses des CLI externes : elles sont hors du mécanisme de masquage des logs xbee.
Références externes : Vault KV, AWS Secrets Manager et Scaleway Secret Manager.
Diagnostic
| Symptôme | Vérification |
|---|---|
environment variable ... is not set | Exporter la variable sur la machine contrôleur |
vault secret provider failed | Vérifier vault status, l’authentification et la politique de lecture |
aws secret provider failed | Vérifier aws sts get-caller-identity, la région et secretsmanager:GetSecretValue |
scw secret provider failed | Vérifier scw info, la région, la révision et les permissions IAM |
secret field ... does not exist | Vérifier le fragment #champ et la structure JSON |
action references a secret outside its execution scope | Vérifier que le secret est injecté avec secret-env ou secret-file |