Les variables d'environnement sont des valeurs dynamiques transmises à une application au démarrage pour configurer son comportement sans modifier le code. Elles permettent de séparer les configurations de développement, de test et de production. Selon Twelve-Factor App, 2025, la configuration doit être stockée dans des variables d'environnement, pas dans le code. Les variables d'environnement assurent une gestion sécurisée des clés API, de l'URL du backend et des indicateurs de fonctionnalités.
Points clés
Les variables d'environnement sont des paires clé-valeur accessibles au processus de l'application via l'API du système d'exploitation. Elles sont transmises au processus lors de sa création et n'existent que pendant son exécution. Contrairement aux paramètres de configuration intégrés dans le code source, les variables d'environnement ne nécessitent pas de recompilation pour modifier les valeurs. C'est un principe fondamental de Twelve-Factor App qui garantit une séparation claire entre le code et la configuration.
Dans le développement mobile, les variables d'environnement résolvent le problème des différentes configurations pour les environnements : le développeur utilise un serveur local, le testeur utilise staging et les utilisateurs utilisent la production. Au lieu de stocker trois URL backend dans le code avec des instructions conditionnelles if-else, le développeur transmet une URL via une variable d'environnement au moment de la compilation. Cela simplifie le code et élimine le risque d'utiliser accidentellement le serveur de production dans un environnement de test.
Le principal avantage est la sécurité : les données sensibles ne se retrouvent pas dans le dépôt de code. Les clés API, les secrets Firebase, les jetons d'accès au backend et les certificats sont chargés via CI/CD directement dans l'environnement de compilation. Si un attaquant accède au dépôt de code, il n'y trouvera pas de secrets, car ils sont stockés dans des stockages protégés du système CI et ne sont transmis qu'à l'étape de compilation du fichier binaire.
Les projets mobiles ont au moins trois environnements : développement, staging et production. Chaque environnement nécessite son propre ensemble de configurations : URL du serveur, nom du paquet, schéma de signature et certificats de notifications push. Sans variables d'environnement, le développeur doit modifier manuellement la configuration avant chaque compilation, ce qui entraîne des erreurs : une clé de production oubliée dans une compilation de test peut envoyer des notifications à des utilisateurs réels ou consommer une API payante.
Les variables d'environnement permettent de changer de backend sans modifier le code : il suffit de changer la valeur dans la variable API_BASE_URL. Les indicateurs de fonctionnalités sont gérés via des variables comme FEATURE_CHAT_ENABLED=true, ce qui permet d'activer de nouvelles fonctionnalités dans staging sans affecter la production. Chaque environnement a son propre fichier .env qui est chargé au moment de la compilation.
class AppConfig {
static final String apiBaseUrl =
const String.fromEnvironment('API_BASE_URL',
defaultValue: 'http://localhost:8080');
}
Les clés codées en dur sont une vulnérabilité courante dans les applications mobiles. Un attaquant décompile l'APK ou l'IPA à l'aide d'outils comme jadx ou Hopper et extrait les secrets du fichier binaire. Même l'obfuscation ne protège pas les littéraux de chaîne — ils se trouvent facilement dans le code après la décompilation. Les variables d'environnement résolvent ce problème en transmettant les clés au moment de la compilation via CI/CD, où elles sont masquées dans les journaux.
object Config {
val apiKey: String =
System.getenv("API_KEY") ?: throw
IllegalStateException("API_KEY not set")
}
Les variables d'environnement s'intègrent aux pipelines de compilation : GitHub Actions, GitLab CI, Bitrise et CircleCI prennent en charge les variables secrètes qui ne sont pas affichées dans les journaux. Au moment de la compilation, le CI substitue les valeurs appropriées en fonction de la branche ou de l'étiquette : pour la branche develop, staging est utilisé ; pour l'étiquette v*, la production est utilisée. Cela automatise le processus et élimine le facteur humain, garantissant que chaque compilation reçoit le bon ensemble de configuration.
Le fichier .env est un moyen standard de stocker les variables d'environnement au format KEY=VALUE. Il n'est pas inclus dans le dépôt ; à la place, .env.example est ajouté avec un modèle de toutes les variables et des valeurs vides. Chaque développeur crée son propre fichier .env avec des paramètres locaux sans affecter les configurations des autres membres de l'équipe. Des fichiers séparés sont utilisés pour différents environnements : .env.dev, .env.stage, .env.prod.
# .env.example — modèle pour les développeurs
API_BASE_URL=http://localhost:8080
FEATURE_CHAT_ENABLED=true
SENTRY_DSN=
Pour les projets mobiles, il existe des bibliothèques spécialisées pour travailler avec les fichiers .env :
Les paramètres de branchement dans CI/CD permettent de substituer différents fichiers .env : .env.dev pour les serveurs de test, .env.stage pour la pré-version et .env.prod pour la publication dans les magasins d'applications. Les fichiers contenant des secrets sont chargés depuis un stockage sécurisé (Vault, AWS Secrets Manager) et ne sont pas stockés dans le dépôt. Cela garantit que même si le système de contrôle de version est compromis, les secrets restent protégés.
L'écosystème iOS utilise des fichiers xcconfig pour gérer les variables au niveau de la compilation. Ils sont attachés aux schémas Xcode et permettent de remplacer les valeurs pour les configurations Debug et Release. Les fichiers xcconfig prennent en charge l'héritage : vous pouvez créer un fichier de base avec des paramètres communs et des fichiers spécifiques pour chaque environnement.
Les fichiers xcconfig stockent les variables au format KEY = VALUE et sont attachés à un schéma de compilation dans Xcode via les paramètres de Configuration. Les variables du xcconfig sont disponibles dans Info.plist via la syntaxe $(NOM_VARIABLE), ce qui permet différents identifiants de bundle et noms d'application pour différents schémas. Pour une identification rapide de l'environnement, le suffixe Dev ou Staging est ajouté au nom de l'application.
# Config/Dev.xcconfig — configuration de développement
API_BASE_URL = http://localhost:3000
BUNDLE_ID_SUFFIX = .dev
APP_DISPLAY_NAME = MyApp Dev
Pour l'accès au moment de l'exécution aux variables dans iOS, le fichier Configuration.swift est utilisé, qui lit les valeurs depuis Info.plist via Bundle.main.object(forInfoDictionaryKey:). Cette approche garantit que les variables sont définies au moment de la compilation et sont disponibles pour l'application immédiatement après le lancement. Les valeurs sont lues une fois lors de l'initialisation du module et mises en cache pour un accès rapide pendant tout le cycle de vie de l'application.
enum AppEnvironment {
static var apiBaseURL: URL {
guard let urlString = Bundle.main
.object(forInfoDictionaryKey: "API_BASE_URL"),
let url = URL(string: urlString as! String)
else { fatalError("API_BASE_URL is not configured") }
return url
}
static var isChatEnabled: Bool {
Bundle.main.object(
forInfoDictionaryKey: "FEATURE_CHAT_ENABLED"
) as? Bool ?? false
}
}
Android prend en charge les variables d'environnement via BuildConfig — une classe générée automatiquement dont les champs sont définis dans le fichier build.gradle du module. BuildConfig est créé au moment de la compilation pour chaque flavor et type de compilation séparément. Cela permet d'avoir des valeurs différentes pour debug et release sans utiliser d'opérateurs conditionnels dans le code, améliorant ainsi les performances et la sécurité.
Les champs BuildConfig sont définis via buildConfigField dans defaultConfig ou dans des buildTypes spécifiques. Un buildType ou productFlavor séparé est créé pour chaque environnement. Cela garantit un isolement strict de la configuration : debug utilise un serveur local, release utilise la production. Les champs BuildConfig sont statiquement typés, ce qui élimine les erreurs lors de leur accès dans le code.
// build.gradle (Module: app)
android {
defaultConfig {
buildConfigField "String", "API_BASE_URL",
"\"http://localhost:8080\""
}
buildTypes {
debug {
buildConfigField "String", "API_BASE_URL",
"\"http://dev.api.itsectr.com\""
}
release {
buildConfigField "String", "API_BASE_URL",
"\"https://api.itsectr.com\""
}
}
}
Le fichier gradle.properties à la racine du projet stocke les variables globales de Gradle. Elles sont disponibles dans tous les modules via la syntaxe $variableName et sont utilisées pour spécifier les versions des dépendances, les indicateurs de compilation et les clés API. Contrairement à BuildConfig, gradle.properties fonctionne uniquement à l'étape de configuration de Gradle, pas au moment de l'exécution de l'application. Par conséquent, les mots de passe et les clés API spécifiés dans gradle.properties ne sont pas visibles dans le code décompilé, car ils sont uniquement utilisés pour générer BuildConfig au moment de la compilation.
# gradle.properties
SENTRY_DSN=https://key@sentry.io/project
MAPS_API_KEY=AIzaSy...
Pour le transfert sécurisé des secrets dans les projets Android, il est recommandé d'utiliser local.properties (exclu du VCS) ou de charger les valeurs depuis les variables CI/CD dans build.gradle via System.getenv(). Cela garantit que les clés ne se retrouvent pas dans le dépôt. Lors de la publication sur Google Play Console, assurez-vous que toutes les clés de débogage sont remplacées par des versions de production via différents buildTypes ou productFlavors avec les valeurs BuildConfig correspondantes.
Questions fréquentes
Oui, Flutter prend en charge les variables d'environnement via le paquet flutter_dotenv pour l'accès au moment de l'exécution ou via des canaux natifs pour les variables de plateforme. Dart dispose également du constructeur String.fromEnvironment pour transmettre des valeurs au moment de la compilation via --dart-define, ce qui est la méthode préférée pour les projets Flutter.
BuildConfig est une classe Java avec des champs typés générée au moment de la compilation pour chaque buildType et flavor. gradle.properties est un fichier texte avec des paires clé-valeur accessible à tous les modules Gradle à l'étape de configuration de la compilation. BuildConfig fonctionne au moment de l'exécution de l'application, gradle.properties — uniquement dans les scripts Gradle.
Ajoutez .env au fichier .gitignore de votre dépôt. Dans le dépôt, incluez uniquement .env.example avec des valeurs vides et une description de chaque variable. Pour CI/CD, utilisez des secrets chiffrés dans les paramètres de GitHub Actions, GitLab CI ou Bitrise, qui sont masqués dans les journaux et indisponibles pour la lecture après la fin de la compilation.
La plupart des systèmes CI prennent en charge les variables d'environnement secrètes. Dans GitHub Actions, ce sont les Secrets, dans GitLab CI — les Variables CI/CD, dans Bitrise — les Secrets. Au moment de la compilation, elles sont transmises au script de compilation via process.env ou System.getenv(). Les variables secrètes ne sont pas affichées dans les journaux de compilation et ne sont pas disponibles dans les forks du dépôt.
Les indicateurs de fonctionnalités sont des variables booléennes qui contrôlent l'activation ou la désactivation de fonctionnalités sans recompiler le code. Exemple : FEATURE_NEW_PAYMENT=true active un nouveau système de paiement dans staging pour les tests. En production, le même indicateur est défini sur false jusqu'à ce que le backend soit complètement déployé. Cela permet de déployer les changements de manière incrémentielle et sécurisée et de les annuler en cas de problème.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi