Las variables de entorno son valores dinámicos que se pasan a una aplicación al iniciarse para configurar su comportamiento sin modificar el código. Permiten separar las configuraciones de desarrollo, pruebas y producción. Según Twelve-Factor App, 2025, la configuración debe almacenarse en variables de entorno, no en el código. Las variables de entorno garantizan una gestión segura de claves API, URL del backend y flags de funcionalidad.
Puntos Clave
Las variables de entorno son pares clave-valor accesibles para el proceso de la aplicación a través de la API del sistema operativo. Se pasan al proceso cuando se crea y existen solo durante su ejecución. A diferencia de los parámetros de configuración incrustados en el código fuente, las variables de entorno no requieren recompilación para cambiar sus valores. Este es un principio fundamental de Twelve-Factor App que garantiza una separación clara entre el código y la configuración.
En el desarrollo móvil, las variables de entorno resuelven el problema de las diferentes configuraciones para los entornos: el desarrollador usa un servidor local, el tester usa staging y los usuarios usan producción. En lugar de almacenar tres URL del backend en el código con sentencias condicionales if-else, el desarrollador pasa una URL a través de una variable de entorno en tiempo de compilación. Esto simplifica el código y elimina el riesgo de usar accidentalmente el servidor de producción en un entorno de pruebas.
La principal ventaja es la seguridad: los datos sensibles no terminan en el repositorio de código. Las claves API, secretos de Firebase, tokens de acceso al backend y certificados se cargan mediante CI/CD directamente en el entorno de compilación. Si un atacante obtiene acceso al repositorio de código, no encontrará secretos allí, ya que se almacenan en almacenes protegidos del sistema CI y se pasan solo en la etapa de compilación del archivo binario.
Los proyectos móviles tienen al menos tres entornos: development, staging y production. Cada entorno requiere su propio conjunto de configuraciones: URL del servidor, nombre del paquete, esquema de firma y certificados de notificaciones push. Sin variables de entorno, el desarrollador tiene que cambiar manualmente la configuración antes de cada compilación, lo que provoca errores: una clave de producción olvidada en una compilación de prueba puede enviar notificaciones a usuarios reales o consumir una API de pago.
Las variables de entorno permiten cambiar de backend sin modificar el código: basta con cambiar el valor en la variable API_BASE_URL. Los flags de funcionalidad se gestionan mediante variables como FEATURE_CHAT_ENABLED=true, lo que permite activar nuevas funciones en staging sin afectar a producción. Cada entorno tiene su propio archivo .env que se carga en tiempo de compilación.
class AppConfig {
static final String apiBaseUrl =
const String.fromEnvironment('API_BASE_URL',
defaultValue: 'http://localhost:8080');
}
Las claves hardcodeadas son una vulnerabilidad común en las aplicaciones móviles. Un atacante descompila el APK o IPA con herramientas como jadx o Hopper y extrae los secretos del archivo binario. Incluso la ofuscación no protege los literales de cadena — se encuentran fácilmente en el código después de la descompilación. Las variables de entorno resuelven este problema pasando las claves en tiempo de compilación mediante CI/CD, donde se enmascaran en los registros.
object Config {
val apiKey: String =
System.getenv("API_KEY") ?: throw
IllegalStateException("API_KEY not set")
}
Las variables de entorno se integran con los pipelines de compilación: GitHub Actions, GitLab CI, Bitrise y CircleCI admiten variables secretas que no se muestran en los registros. En tiempo de compilación, el CI sustituye los valores adecuados según la rama o etiqueta: para la rama develop se usa staging, para la etiqueta v* se usa producción. Esto automatiza el proceso y elimina el factor humano, garantizando que cada compilación reciba el conjunto correcto de configuración.
El archivo .env es una forma estándar de almacenar variables de entorno en formato CLAVE=VALOR. No se incluye en el repositorio; en su lugar, se agrega .env.example con una plantilla de todas las variables y valores vacíos. Cada desarrollador crea su propio archivo .env con configuraciones locales sin afectar las configuraciones de otros miembros del equipo. Se utilizan archivos separados para diferentes entornos: .env.dev, .env.stage, .env.prod.
# .env.example — plantilla para desarrolladores
API_BASE_URL=http://localhost:8080
FEATURE_CHAT_ENABLED=true
SENTRY_DSN=
Para proyectos móviles, existen bibliotecas especializadas para trabajar con archivos .env:
Los ajustes de ramificación en CI/CD permiten sustituir diferentes archivos .env: .env.dev para servidores de prueba, .env.stage para prelanzamiento y .env.prod para publicación en tiendas de aplicaciones. Los archivos con secretos se cargan desde un almacén seguro (Vault, AWS Secrets Manager) y no se almacenan en el repositorio. Esto garantiza que incluso si el sistema de control de versiones se ve comprometido, los secretos permanecen protegidos.
El ecosistema iOS utiliza archivos xcconfig para gestionar variables a nivel de compilación. Se adjuntan a los esquemas de Xcode y permiten sobrescribir valores para las configuraciones Debug y Release. Los archivos xcconfig admiten herencia: se puede crear un archivo base con configuraciones comunes y archivos específicos para cada entorno.
Los archivos xcconfig almacenan variables en formato CLAVE = VALOR y se adjuntan a un esquema de compilación en Xcode a través de los ajustes de Configuration. Las variables de xcconfig están disponibles en Info.plist mediante la sintaxis $(NOMBRE_VARIABLE), lo que permite diferentes identificadores de paquete y nombres de aplicación para diferentes esquemas. Para una identificación rápida del entorno, se añade el sufijo Dev o Staging al nombre de la aplicación.
# Config/Dev.xcconfig — configuración de desarrollo
API_BASE_URL = http://localhost:3000
BUNDLE_ID_SUFFIX = .dev
APP_DISPLAY_NAME = MyApp Dev
Para el acceso en tiempo de ejecución a las variables en iOS, se utiliza el archivo Configuration.swift, que lee los valores de Info.plist mediante Bundle.main.object(forInfoDictionaryKey:). Este enfoque garantiza que las variables se definen en tiempo de compilación y están disponibles para la aplicación inmediatamente después del inicio. Los valores se leen una vez durante la inicialización del módulo y se almacenan en caché para un acceso rápido durante todo el ciclo de vida de la aplicación.
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 admite variables de entorno a través de BuildConfig — una clase generada automáticamente cuyos campos se definen en el archivo build.gradle del módulo. BuildConfig se crea en tiempo de compilación para cada flavor y tipo de compilación por separado. Esto permite tener diferentes valores para debug y release sin usar operadores condicionales en el código, mejorando el rendimiento y la seguridad.
Los campos de BuildConfig se establecen mediante buildConfigField en defaultConfig o en buildTypes específicos. Se crea un buildType o productFlavor separado para cada entorno. Esto garantiza una estricta separación de configuraciones: debug usa un servidor local, release usa producción. Los campos de BuildConfig están tipificados estáticamente, lo que elimina errores al acceder a ellos en el código.
// 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\""
}
}
}
El archivo gradle.properties en la raíz del proyecto almacena variables globales de Gradle. Están disponibles en todos los módulos mediante la sintaxis $nombreVariable y se utilizan para especificar versiones de dependencias, flags de compilación y claves API. A diferencia de BuildConfig, gradle.properties funciona solo en la etapa de configuración de Gradle, no en tiempo de ejecución de la aplicación. Por lo tanto, las contraseñas y claves API especificadas en gradle.properties no son visibles en el código descompilado, ya que solo se utilizan para generar BuildConfig en tiempo de compilación.
# gradle.properties
SENTRY_DSN=https://key@sentry.io/project
MAPS_API_KEY=AIzaSy...
Para la transferencia segura de secretos en proyectos Android, se recomienda usar local.properties (excluido del VCS) o cargar valores desde variables CI/CD en build.gradle mediante System.getenv(). Esto garantiza que las claves no terminen en el repositorio. Al publicar en Google Play Console, asegúrese de que todas las claves de depuración se reemplacen por versiones de producción mediante diferentes buildTypes o productFlavors con los valores correspondientes de BuildConfig.
Preguntas Frecuentes
Sí, Flutter admite variables de entorno a través del paquete flutter_dotenv para acceso en tiempo de ejecución o mediante canales nativos para variables de plataforma. Dart también tiene el constructor String.fromEnvironment para pasar valores en tiempo de compilación mediante --dart-define, que es el método preferido para proyectos Flutter.
BuildConfig es una clase Java con campos tipificados generada en tiempo de compilación para cada buildType y flavor. gradle.properties es un archivo de texto con pares clave-valor accesible para todos los módulos de Gradle en la etapa de configuración de compilación. BuildConfig funciona en tiempo de ejecución de la aplicación, gradle.properties — solo en scripts de Gradle.
Agregue .env al archivo .gitignore de su repositorio. En el repositorio solo incluya .env.example con valores vacíos y una descripción de cada variable. Para CI/CD, use secretos cifrados en la configuración de GitHub Actions, GitLab CI o Bitrise, que se enmascaran en los registros y no están disponibles para lectura después de completar la compilación.
La mayoría de los sistemas CI admiten variables de entorno secretas. En GitHub Actions son Secrets, en GitLab CI — CI/CD Variables, en Bitrise — Secrets. En tiempo de compilación, se pasan al script de compilación mediante process.env o System.getenv(). Las variables secretas no se muestran en los registros de compilación y no están disponibles en forks del repositorio.
Los feature flags son variables booleanas que controlan la activación o desactivación de funcionalidades sin recompilar el código. Ejemplo: FEATURE_NEW_PAYMENT=true activa un nuevo sistema de pago en staging para pruebas. En producción, el mismo flag está en false hasta que el backend esté completamente desplegado. Esto permite implementar cambios de forma segura e incremental y revertirlos si hay problemas.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también