EnvOverrideResolver

Post-deserialization resolver that overrides data class field values with environment variables when the field is annotated with @Env.

Priority order (highest wins):

  1. Environment variable (via System.getenv) -- if the variable is set and non-null.

  2. YAML value -- the value already deserialized into the instance.

  3. Kotlin default -- the compile-time default declared in the data class constructor.

This design allows operators to override configuration at deploy time without modifying the YAML file, which is essential for secrets (database passwords, API tokens) that should never be committed to version control.

Security note: Environment variable values are read via System.getenv and converted to the target type without sanitisation. Sensitive values should use SecretString so that they are masked in logs and toString() output.

The resolver operates recursively: nested data classes are walked so that @Env annotations at any depth are honoured.

Example:

data class Database(
val host: String = "localhost",
@Env("DB_PASSWORD") val password: String = ""
)
data class AppConfig(val database: Database = Database())

// After deserialization from YAML:
val config = EnvOverrideResolver.resolve(deserialized, AppConfig::class)
// If DB_PASSWORD=hunter2 is set in the environment, config.database.password == "hunter2"

Since

1.0

See also

Functions

Link copied to clipboard
fun <T : Any> resolve(instance: T, klass: KClass<T>): T

Creates a new instance of T where any field annotated with @Env is replaced by the corresponding environment variable value, if set.