Spring application.yml

Spring Boot services commonly use application.yml, application-prod.yml, profile-specific files, and external configuration. These patterns are valid, but production secrets committed to a repository must be treated as exposed.

When to use this guide

  • DB passwords, tokens, or signing keys are written directly in application.yml or application-prod.yml.
  • Spring Boot uses profile-specific configuration.
  • You need to choose between ${ENV_VAR} references and a mounted configuration file.
  • Spring configuration is supplied externally through Kubernetes, VMs, or secure file delivery.

Examples

Pattern A: Inject values through ${ENV_VAR}

This is a simple option when the environment supports injection of environment variables.

When to choose this pattern

  • There are relatively few secrets and they can be supplied as environment variables.
  • Your deployment system supports this as a standard mechanism.
  • You want to retain profiles while providing secret values externally.

Before

yaml
spring:
  datasource:
    url: jdbc:postgresql://prod-db.internal:5432/app
    username: app_user
    password: super-secret-password

jwt:
  secret: hardcoded-jwt-secret

After

yaml
spring:
  datasource:
    url: ${DB_URL}
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}

jwt:
  secret: ${JWT_SECRET}
Spring code example
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.constraints.NotBlank;

@Validated
@ConfigurationProperties(prefix = "jwt")
public class JwtProperties {

    @NotBlank
    private String secret;

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }
}

This is an excerpt for a Spring Boot environment using Jakarta Validation. Add the validation dependency and register the class through @ConfigurationPropertiesScan or @EnableConfigurationProperties. Stop startup if required values are missing or empty.

Pattern B: Inject a mounted application.yml

If operations require an application.yml or application-prod.yml file, supply the production file at runtime through a path such as /config/application.yml or /etc/app/application.yml.

When to choose this pattern

  • You need to retain the profile-specific file structure.
  • An external configuration path is part of your operational standard.
  • Kubernetes Secret volumes, Vault Agent, or secure file delivery are available.

File to keep in the repository

yaml
spring:
  datasource:
    url: jdbc:postgresql://prod-db.internal:5432/app
    username: app_user
    password: "<runtime-provided>"

jwt:
  secret: "<runtime-provided>"

Example runtime paths

text
/config/application.yml
/etc/app/application.yml

Spring configuration example

Use spring.config.import or Spring Boot's standard external configuration locations. Supply the actual secret at runtime instead of storing it in the repository.

yaml
spring:
  config:
    import: file:/etc/app/application.yml

This file is required, so the import does not use optional:. Do not commit production application.yml or application-prod.yml files to Git.

Developer tasks

  • Remove actual secret values from application.yml and application-prod.yml.
  • Choose environment references or external file loading to suit the service.
  • Configure @ConfigurationProperties or the existing loader to fail closed when required values are missing.
  • Check that logs, exceptions, debug output, and Actuator endpoints do not expose secrets.

Infrastructure and platform tasks

  • Configure environment-variable injection for the environment-based pattern.
  • Standardize the Secret volume, secure file delivery, or external file path for the file-based pattern.
  • Prevent actual secrets from being stored in Helm values, Docker images, or ConfigMaps.
  • Document restart or reload steps for secret rotation.

Verification

  • Check that production files such as application-prod.yml are absent from the repository.
  • Confirm that ${ENV_VAR} values or mounted files are supplied in the deployed environment.
  • Check /actuator/env, debug logs, and exception responses for secret exposure.
  • Confirm that startup fails when a required secret is missing.

Common mistakes

  • Committing application-prod.yml to the repository
  • Storing secrets directly in Helm values
  • Baking production configuration into a Docker image
  • Exposing values through /actuator/env, debug logs, or exception stacks
  • Using empty defaults that allow startup without required secrets

Example instructions for the owner

  • “Remove actual secrets from Spring Boot configuration and replace them with ${ENV_VAR} references or externally supplied runtime files.”
  • “Even if you need application-prod.yml, do not commit it. Supply it at runtime through a path such as /config/application.yml or /etc/app/application.yml.”
  • “Make @ConfigurationProperties or the existing loader fail immediately when a required secret is missing, and check /actuator/env and debug logs for exposure.”

Related documentation