Omgevingsvariabelen zijn dynamische waarden die bij het opstarten aan de applicatie worden doorgegeven om het gedrag in te stellen zonder code te wijzigen. Ze maken het mogelijk om configuraties voor ontwikkeling, testen en productie te scheiden. Volgens Twelve-Factor App, 2025 moet configuratie worden opgeslagen in omgevingsvariabelen, niet in code. Omgevingsvariabelen zorgen voor veilig beheer van API-sleutels, backend-URL's en functievlaggen.
Belangrijkste punten
Omgevingsvariabelen zijn een sleutel-waarde paar dat via de API van het besturingssysteem toegankelijk is voor het applicatieproces. Ze worden aan het proces doorgegeven bij het aanmaken en bestaan alleen tijdens de uitvoering ervan. In tegenstelling tot configuratieparameters die in de broncode zijn ingebouwd, vereisen omgevingsvariabelen geen hercompilatie om waarden te wijzigen. Dit is een fundamenteel principe van Twelve-Factor App dat zorgt voor een duidelijke scheiding tussen code en configuratie.
In mobiele ontwikkeling lossen omgevingsvariabelen het probleem van verschillende configuraties voor omgevingen op: de ontwikkelaar gebruikt een lokale server, de tester gebruikt staging, gebruikers gebruiken productie. In plaats van drie backend-URL's in code op te slaan met if-else voorwaardelijke operatoren, geeft de ontwikkelaar één URL door via een omgevingsvariabele tijdens de build. Dit vereenvoudigt de code en elimineert het risico van onbedoeld gebruik van de productieserver in een testomgeving.
Het belangrijkste voordeel is veiligheid: gevoelige gegevens komen niet in de coderepository terecht. API-sleutels, Firebase-geheimen, backend-toegangstokens en certificaten worden via CI/CD rechtstreeks in de buildomgeving geladen. Als een aanvaller toegang krijgt tot de coderepository, vindt hij daar geen geheimen, omdat ze worden opgeslagen in beveiligde opslagplaatsen van het CI-systeem en alleen worden doorgegeven tijdens de build van het binaire bestand.
Mobiele projecten hebben minstens drie omgevingen: development, staging en productie. Elke omgeving vereist zijn eigen set configuraties: server-URL, pakketnaam, handtekeningenschema en pushmeldingcertificaten. Zonder omgevingsvariabelen moet de ontwikkelaar handmatig de configuratie wijzigen voor elke build, wat leidt tot fouten: een vergeten productiesleutel in een testbuild kan het verzenden van meldingen naar echte gebruikers of het verbruik van een betaalde API veroorzaken.
Omgevingsvariabelen maken het mogelijk om van backend te wisselen zonder code te wijzigen: het volstaat om de waarde in de variabele API_BASE_URL te vervangen. Functievlaggen (feature flags) worden beheerd via variabelen zoals FEATURE_CHAT_ENABLED=true, waardoor nieuwe functionaliteiten in staging kunnen worden ingeschakeld zonder invloed op productie. Voor elke omgeving wordt een eigen .env-bestand gemaakt dat tijdens de build wordt geladen.
class AppConfig {
static final String apiBaseUrl =
const String.fromEnvironment('API_BASE_URL',
defaultValue: 'http://localhost:8080');
}
Hardgecodeerde sleutels zijn een veelvoorkomende kwetsbaarheid in mobiele applicaties. Een aanvaller decompileert APK of IPA met tools zoals jadx of Hopper en haalt geheimen uit het binaire bestand. Zelfs obfuscatie beschermt stringliterals niet — ze worden gemakkelijk gevonden in code na decompilatie. Omgevingsvariabelen lossen dit probleem op door sleutels tijdens de build via CI/CD door te geven, waar ze worden gemaskeerd in logs.
object Config {
val apiKey: String =
System.getenv("API_KEY") ?: throw
IllegalStateException("API_KEY not set")
}
Omgevingsvariabelen integreren met build-pipelines: GitHub Actions, GitLab CI, Bitrise en CircleCI ondersteunen geheime variabelen die niet worden weergegeven in logs. Tijdens de build voegt CI de juiste waarden in op basis van de branch of tag: voor de develop-branch wordt staging gebruikt, voor de v*-tag wordt productie gebruikt. Dit automatiseert het proces en elimineert menselijke fouten, waardoor elke build de juiste configuratieset krijgt.
Het .env-bestand is de standaardmanier om omgevingsvariabelen op te slaan in KEY=VALUE-formaat. Het wordt niet in de repository opgenomen; in plaats daarvan wordt .env.example met een sjabloon van alle variabelen en lege waarden aan de repository toegevoegd. Elke ontwikkelaar maakt zijn eigen .env-bestand met lokale instellingen, zonder de configuratie van andere teamleden te beïnvloeden. Voor verschillende omgevingen worden aparte bestanden gebruikt: .env.dev, .env.stage, .env.prod.
# .env.example — sjabloon voor ontwikkelaars
API_BASE_URL=http://localhost:8080
FEATURE_CHAT_ENABLED=true
SENTRY_DSN=
Voor mobiele projecten zijn er gespecialiseerde bibliotheken voor het werken met .env-bestanden:
Branch-instellingen in CI/CD maken het mogelijk om verschillende .env-bestanden in te voegen: .env.dev voor testservers, .env.stage voor pre-release en .env.prod voor publicatie in app-winkels. Bestanden met geheimen worden geladen uit een beveiligde opslag (Vault, AWS Secrets Manager) en niet opgeslagen in de repository. Dit garandeert dat zelfs bij compromittering van het versiebeheersysteem de geheimen beschermd blijven.
Het iOS-ecosysteem gebruikt xcconfig-bestanden voor het beheren van variabelen op build-niveau. Ze worden gekoppeld aan Xcode-schema's en maken het mogelijk waarden te overschrijven voor Debug- en Release-configuraties. xcconfig-bestanden ondersteunen overerving: er kan een basisbestand met gemeenschappelijke instellingen en specifieke bestanden voor elke omgeving worden gemaakt.
xcconfig-bestanden slaan variabelen op in KEY = VALUE-formaat en worden via Configuration-instellingen aan het build-schema in Xcode gekoppeld. Variabelen uit xcconfig zijn toegankelijk in Info.plist via de syntaxis $(VARIABLE_NAME), wat het gebruik van verschillende bundelidentificaties en app-namen voor verschillende schema's mogelijk maakt. Voor snelle identificatie van de omgeving wordt een Dev- of Staging-suffix aan de app-naam toegevoegd.
# Config/Dev.xcconfig — ontwikkelconfiguratie
API_BASE_URL = http://localhost:3000
BUNDLE_ID_SUFFIX = .dev
APP_DISPLAY_NAME = MyApp Dev
Voor runtime-toegang tot variabelen in iOS wordt het Configuration.swift-bestand gebruikt, dat waarden uit Info.plist leest via Bundle.main.object(forInfoDictionaryKey:). Deze aanpak garandeert dat variabelen tijdens de build worden bepaald en direct na het opstarten beschikbaar zijn voor de applicatie. Waarden worden eenmalig gelezen bij initialisatie van de module en gecached voor snelle toegang tijdens de levenscyclus van de applicatie.
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 ondersteunt omgevingsvariabelen via BuildConfig — een automatisch gegenereerde klasse waarvan de velden worden gedefinieerd in het build.gradle-bestand van de module. BuildConfig wordt tijdens compilatie gemaakt voor elke flavor en build-type afzonderlijk. Dit maakt verschillende waarden mogelijk voor debug en release zonder voorwaardelijke operatoren in code, wat de prestaties en veiligheid verhoogt.
BuildConfig-velden worden ingesteld via buildConfigField in defaultConfig of in specifieke buildTypes. Voor elke omgeving wordt een aparte buildType of productFlavor gemaakt. Dit zorgt voor strikte isolatie van configuraties: debug gebruikt de lokale server, release gebruikt productie. BuildConfig-velden zijn statisch getypeerd, wat fouten bij het aanroepen in code elimineert.
// 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\""
}
}
}
Het gradle.properties-bestand in de projectroot slaat globale Gradle-variabelen op. Ze zijn toegankelijk in alle modules via de syntaxis $variableName en worden gebruikt voor het specificeren van dependency-versies, build-vlaggen en API-sleutels. In tegenstelling tot BuildConfig werkt gradle.properties alleen tijdens de Gradle-configuratiefase, niet in de runtime van de applicatie. Daarom zijn wachtwoorden en API-sleutels in gradle.properties niet zichtbaar in gedecompileerde code, omdat ze alleen worden gebruikt voor het genereren van BuildConfig tijdens compilatie.
# gradle.properties
SENTRY_DSN=https://key@sentry.io/project
MAPS_API_KEY=AIzaSy...
Voor het veilig doorgeven van geheimen in Android-projecten wordt aanbevolen local.properties (uitgesloten van VCS) te gebruiken of waarden uit CI/CD-variabelen in build.gradle te laden via System.getenv(). Dit garandeert dat sleutels niet in de repository terechtkomen. Bij publicatie in de Google Play Console, zorg ervoor dat alle debug-sleutels zijn vervangen door productieversies via verschillende buildTypes of productFlavors met bijbehorende BuildConfig-waarden.
Veelgestelde vragen
Ja, Flutter ondersteunt omgevingsvariabelen via het flutter_dotenv-pakket voor runtime-toegang of via native kanalen voor platformvariabelen. In Dart is ook de constructor String.fromEnvironment beschikbaar voor het doorgeven van waarden tijdens compilatie via --dart-define, wat de voorkeursmethode is voor Flutter-projecten.
BuildConfig is een Java-klasse met getypeerde velden, gegenereerd tijdens compilatie voor elke buildType en flavor. gradle.properties is een tekstbestand met sleutel-waardeparen, toegankelijk voor alle Gradle-modules tijdens de build-configuratiefase. BuildConfig werkt in de runtime van de applicatie, gradle.properties — alleen in Gradle-scripts.
Voeg .env toe aan het .gitignore-bestand van uw repository. Commit alleen .env.example met lege waarden en een beschrijving van elke variabele naar de repository. Gebruik voor CI/CD versleutelde geheimen in de instellingen van GitHub Actions, GitLab CI of Bitrise, die worden gemaskeerd in logs en niet leesbaar zijn na voltooiing van de build.
De meeste CI-systemen ondersteunen geheime omgevingsvariabelen. In GitHub Actions zijn dit Secrets, in GitLab CI — CI/CD Variables, in Bitrise — Secrets. Tijdens de build worden ze doorgegeven aan het buildscript via process.env of System.getenv(). Geheime variabelen worden niet weergegeven in buildlogs en zijn niet beschikbaar in forks van de repository.
Feature flags zijn booleaanse variabelen die het in- of uitschakelen van functionaliteit regelen zonder hercompilatie van code. Voorbeeld: FEATURE_NEW_PAYMENT=true schakelt het nieuwe betaalsysteem in staging in voor testen. In productie staat dezelfde vlag op false tot volledige implementatie van de backend. Dit maakt veilige gefaseerde implementatie van wijzigingen mogelijk en terugdraaien bij problemen.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook