Skip to content

Conversation

@johnycho
Copy link
Contributor

This commit introduces FileResolvingEnvironmentRepository, a decorator that intercepts property values starting with the {file} prefix. It reads the referenced file from the local file system, encodes the content to Base64, and replaces the original property value.

Key changes:

  • Implemented FileResolvingEnvironmentRepository to wrap existing repositories.
  • Ensured thread safety and immutability by creating new PropertySource instances instead of modifying existing maps.
  • Added FileResolvingEnvironmentRepositoryConfiguration for auto-configuration.
  • Added unit tests covering logic verification and immutable map handling.

Fixes gh-2441

@ryanjbaxter
Copy link
Contributor

Thanks for the PR.

This is something that we would have to consider merging into our next minor release as a new feature. We won't begin that work until the July timeframe.

Please check the build failure and fix any errors.

I also think that this environment repository should be disabled by default since it has the potential to expose file content.

We would also need documentation on how this feature works.

@johnycho
Copy link
Contributor Author

johnycho commented Jan 16, 2026

Thanks for the review and the detailed feedback! @ryanjbaxter

I completely understand the timeline regarding the next minor release in July.

I have just pushed the updates addressing your comments:

  1. Security: The feature is now disabled by default. Users must explicitly enable it via spring.cloud.config.server.file-resolving.enabled=true.
  2. Tests: Added FileResolvingEnvironmentRepositoryConfigurationTests to verify the auto-configuration logic and ensure the feature remains disabled by default.
  3. Documentation: Added a section to environment-repository.adoc explaining usage and security warnings.
  4. Build: Fixed the Checkstyle errors and verified the build passes locally.

Please let me know if there is anything else needed.

@ryanjbaxter
Copy link
Contributor

I am wondering if it would be useful to be able to reference another file in the environment repository. For example the keystore could reside in the git repo and you might want to reference that file rather than a file in the filesystem of the config server.

@johnycho
Copy link
Contributor Author

johnycho commented Jan 17, 2026

Thank you for the feedback. @ryanjbaxter

I see the point about referencing a separate Git repo, but in practice keeping artifacts in the same environment repo can be safer when configs and keystores must evolve together.

Splitting into another repo adds a version-coupling problem (which config revision matches which keystore revision), which can become another operational risk.

This PR is not trying to dictate repo structure, but to eliminate server-local file deployment as a dependency and improve reproducibility. Multi-repo support sounds like a good follow-up, but likely belongs in a separate issue/PR.

@ryanjbaxter
Copy link
Contributor

You are misunderstanding what I am suggesting I think...

Say you have this in application.yml within a git repo configured as an environment repsitory for the config server:

keystoreFile='{file}'/path/to/keystore.jks

My understanding of the current functionality is that path/to/keystore.jks is a path to a file residing on the config server.

What I think would be another common use case would be a path relative to application.yml within the git repo itself the config server is using. For example:

keystoreFile='{file}' ./path/in/gitrepo/keystore.jks

@johnycho
Copy link
Contributor Author

johnycho commented Jan 17, 2026

Thank you for the clarification. @ryanjbaxter

Just to confirm — would it be acceptable to extend the current {file} resolution so that it can also handle paths relative to the environment Git repository, rather than only files on the Config Server’s local filesystem?

For example, allowing something like

keystoreFile: "{file}./path/in/gitrepo/keystore.jks"

to resolve within the repository.

@ryanjbaxter
Copy link
Contributor

That is what I am suggesting.

One thing to keep in mind is that not all EnvironmetRepositories have files, for example JDBC

@johnycho
Copy link
Contributor Author

Thanks @ryanjbaxter for the suggestion!

I have updated the PR to support relative paths pointing to files within the configuration repository (e.g., Git).

Key Changes:

  1. SearchPathLocator Implementation: The FileResolvingEnvironmentRepository now implements SearchPathLocator. It delegates getLocations() calls to the underlying repository to find where the configuration files are stored locally.
  2. Relative Path Logic: If a property value starts with {file}./, it now iterates through the locations provided by the repository to find the file.
    • Example: key: {file}./certs/my-key.jks will look for certs/my-key.jks inside the cloned Git repo.
  3. Graceful Fallback: If the underlying repository does not support search paths (e.g., JDBC), or if the file is not found, the property remains unchanged and a warning log is recorded.
  4. Documentation: Updated environment-repository.adoc to explain both absolute and relative path usage.
  5. Tests: Added comprehensive tests covering relative path resolution and interface delegation.

I believe this covers the use case you mentioned!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automatically resolve File to base64 encoded value in configuration.

3 participants