{"id":37017271,"url":"https://github.com/sergiofgonzalez/waterfall-config","last_synced_at":"2026-01-14T01:58:58.015Z","repository":{"id":57722698,"uuid":"102389468","full_name":"sergiofgonzalez/waterfall-config","owner":"sergiofgonzalez","description":"A simplistic configuration library heavily based on Typesafehub Config with some additional opinionated features","archived":false,"fork":false,"pushed_at":"2019-03-21T13:42:30.000Z","size":44,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-23T03:49:35.616Z","etag":null,"topics":["configuration","configuration-file","encrypted-properties","hocon","java","waterfall"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sergiofgonzalez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-09-04T18:15:23.000Z","updated_at":"2019-03-21T13:42:31.000Z","dependencies_parsed_at":"2022-08-28T10:11:31.623Z","dependency_job_id":null,"html_url":"https://github.com/sergiofgonzalez/waterfall-config","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sergiofgonzalez/waterfall-config","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergiofgonzalez%2Fwaterfall-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergiofgonzalez%2Fwaterfall-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergiofgonzalez%2Fwaterfall-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergiofgonzalez%2Fwaterfall-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sergiofgonzalez","download_url":"https://codeload.github.com/sergiofgonzalez/waterfall-config/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sergiofgonzalez%2Fwaterfall-config/sbom","scorecard":{"id":812473,"data":{"date":"2025-08-11","repo":{"name":"github.com/sergiofgonzalez/waterfall-config","commit":"fc3dfa170dfc8eca58bba30afb56ebc9fc8889a8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-2qrg-x229-3v8q","Warn: Project is vulnerable to: GHSA-65fg-84f6-3jq3","Warn: Project is vulnerable to: GHSA-f7vh-qwp3-x37m","Warn: Project is vulnerable to: GHSA-fp5r-v3w9-4333","Warn: Project is vulnerable to: GHSA-w9p3-5cr8-m3jj"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T13:29:46.629Z","repository_id":57722698,"created_at":"2025-08-23T13:29:46.630Z","updated_at":"2025-08-23T13:29:46.630Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408706,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"ssl_error","status_checked_at":"2026-01-14T01:40:32.775Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","configuration-file","encrypted-properties","hocon","java","waterfall"],"created_at":"2026-01-14T01:58:57.263Z","updated_at":"2026-01-14T01:58:58.003Z","avatar_url":"https://github.com/sergiofgonzalez.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Waterfall Config Library for Java [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.sergiofgonzalez/waterfall-config/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.sergiofgonzalez/waterfall-config) [![Build Status](https://travis-ci.org/sergiofgonzalez/waterfall-config.svg?branch=master)](https://travis-ci.org/sergiofgonzalez/waterfall-config) [![codecov](https://codecov.io/gh/sergiofgonzalez/waterfall-config/branch/master/graph/badge.svg)](https://codecov.io/gh/sergiofgonzalez/waterfall-config)\n\u003e a simplified configuration library for the JVM, heavily-based on *typesafehub Config*, with some additional features and strongly opinionated\n\n# New Home Announcement\n\n## Hi!\n\n## The project is now hosted and maintained in the [Accenture Organization](https://github.com/accenture) on GitHub. \n\n## If you want to create an issue/enhacement, or looking to contribute make sure to visit the new home for the library at https://github.com/Accenture/waterfall-config.\n\n## Apologies for any inconveniences!\n![closed-zoo.jpg][1]\n\n  [1]: http://i.imgur.com/UzR3IE4.jpg \"Government shut down, no zoo for you!\"\n\n# wconf()\nUse `wconf()` for configuration properties management in Java project. *wconf* allows for hierarchical (i.e. waterfall) merging of configuration properties with an established precedence between the sources.\n\n## Simple Usage\n\nModify your `pom.xml` to add a dependency for *wconf*:\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.github.sergiofgonzalez\u003c/groupId\u003e\n      \u003cartifactId\u003ewaterfall-config\u003c/artifactId\u003e\n      \u003cversion\u003e1.0.0\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n\nCreate a file `common.conf` under `src/main/resources/config` with the config properties for your application:\n```\nmessage.en: \"Hello to Jason Isaacs!\"\nmessage.es: \"¡Hola a Jason Isaacs!\"\n```\n\nInclude a static import for the `WaterfallConfig` functions and start using your configuration values:\n\n```java\n...\nimport static com.github.sergiofgonzalez.wconf.WaterfallConfig.*;\n...\n\n    System.out.println(wconf().get(\"message.en\"));\n...\n``` \n\n\n## Waterfall and Merge\n*wconf* defines a hierarchy between the different configuration property sources it supports, so that properties found in a source with a higher precedence will overwrite properties found in sources with lower precedence.\n\nThe precedence is established as follows, from lowest to highest:\n+ a file `config/common.conf` packaged in the jar\n+ a file `config/application.conf` packaged in the jar\n+ Java System Properties\n+ OS Environment Variables\n+ A file `application.conf` found outside the jar\n\nFor example, if you have:\n+ a file `config/common.conf` within the jar with the line `best_actor=Jason Isaacs`\n+ a file `config/application.conf` within the jar with the line `best_actor=Riz Ahmed`\n+ an environment variable defined as `best_actor=Idris Elba`\n\ninvoking `wconf().get(\"best_actor\")` will render `\"Idris Elba\"` as result. \n\n*wconf* also supports merging of configuration properties between sources, so that configuration properties sharing a common parent component will be merged.\n\nFor example, if you have:\n+ a file `config/common.conf` with the line `message.greeting=Hello to Jason Isaacs`\n+ a file `config/application.conf` with the line `message.farewell=Enjoy your evening`\n\nboth `message.greeting` and `message.farewell` will be available.\n\n## Customizing Application Configuration Files\nAs stated above, by default, *wconf* will try to find properties in the following files:\n+ A `config/common.conf` within the jar with the common configuration properties\n+ A `config/application.conf` within the jar with application-level properties\n+ An `application.conf` file with application-level specific properties not packaged in the jar \n\nWhile the name for `config/common.conf` cannot be customized *wconf()* allows you to select a custom name for the application configuration by setting the property `application_resource` to a value different from `config/application.conf`.\n\nThe config key `wconf_ext_app_properties_paths` can be used to customize the paths that will be scanned while looking for the application-level specific properties not packaged in the jar. The default for this value is `[ \"./\" ]`. You will typically want to specify such value for your application in `common.conf`:\n```\nwconf_ext_app_properties_paths=[ \"./\", \"/tmp/\", \"/shared-volume/\" ]\n```\n\nbut it can also be specified using environment variables and properties using the syntax:\n```\n-D wconf_ext_app_properties_paths.0=\"./\" \\\n-D wconf_ext_app_properties_paths.1=\"./tmp/\" \\\n-D wconf_ext_app_properties_paths.2=\"./shared-volume/\"\n```\n  \n**Note**\nSetting the value of `wconf_ext_app_properties_paths` in the application-level property file will have **no effect**, as this value is needed in creation time while the application level property source is being discovered.  \n  \n## Syntax for Configuration Files\nThe syntax for configuration files is a JSON superset called *HOCON* that is used by the library doing all the heavy lifting for *wconf* (see [Typesafehub Config](https://github.com/typesafehub/config#user-content-using-hocon-the-json-superset).\n\n*HOCON* allows you to use plain java-style properties if that is what you like:\n```\nfoo1.bar1=foobar11\nfoo1.bar2=foobar12\n\nfoo2.bar1=foobar21\n```\n\nbut I find much more expressive to use explicit grouping:\n```\nmodes {\n  available: [encrypt, decrypt, geniv]\n  active: geniv\n}\n\ngeniv {\n  algorithm: \"AES/CBC/PKCS5Padding\"\n}\n```\n\nYou can find more usage examples in the link above and in the test resources within the project.\n\n## Using Profiles\nAnother opinionated feature of *wconf* is the profile selection. Using grouping of configuration variables and a configuration property named `wconf_active_profile` lets you activate a portion of the complete application configuration properties.\n\n```\nwconf_active_profile: test\n\ndev {\n  foo=bar in dev\n  message=to be used in dev environment\n}\n\ntest {\n  foo=bar in test\n  message=to be used in test environment  \n}\n\nproduction {\n  foo=bar in prod\n  message=to be used in prod environment\n}\n```\n\nAs `wconf_active_profile` is set to test, `wconf().get(foo)` will render `\"bar in test\"` as the result.\n\nNote that when using profiles:\n+ Only the specific section of the `config/application.conf` and `application.conf` will be enabled. Information found in other profiles or outside any profile will not be visible to *wconf*.\n+ You can override values found in the active profile in environment variables and system properties without having to include the profile prefix. That is, the value for `foo` can be overridden defining an environment variable `foo=new value for active profile`.\n+ Profile rules do not affect the information in `config/common.conf`. If you wish to use profiles, plan for having application configuration.\n\nYou can find examples of profile usage in the test section.\n\n## Encrypted Properties\nA recurring requirement for configuration properties is the support of symmetric encryption for sensible data such as datasource passwords.\n\n*wconf* features support for flexible encryption of configuration properties using the Java Cryptography Extension (JCE). Please note that you should be aware of the best practices and recommendations when using this feature, as symmetric encryption is useless is the key is handled carelessly (distributed without proper control or committed to your source code repository).\n\n**Note**\n+ The keystore and key found in the test section is provided for **demonstration purposes** and should **not** be used in applications.\n\nIn order to enable encryption you will need the following:\n1. Create a *JCEKS Key Store* with a secret key\n2. Configure in the common or application level properties the encryption details\n3. Encrypt the sensitive values using the generated Key Store and encryption details and include them as properties\n\n### Creating a JCEKS Key Store and Adding a Secret Key\nA JCEKS Key Store is a Java Key Store that allows you to store secret keys for symmetric encryption (typically AES256). The `keytool` JDK utility lets you generate such a Key Store with a somewhat complicated *spell*:\n\n```bash\n$ keytool -genseckey \\\n-alias wconf-secret-key -keyalg AES -keysize 256 -keypass mykeypasswd \\\n-storetype JCEKS -storepass mystorepasswd -keystore ./wconf-keystore.jceks\n```\n\nThe previous command, generates a *JCEKS Key Store* in a file `./wconf-keystore.jceks` with a Key Store password `mystorepasswd` and saves in it an AES256 secret key you can use for symmetric encryption. The key is assigned the alias `wconf-secret-key` and protects the key access (facepalm) with the password `mykeypasswd`. \n\n### Configuring the Encryption Details in the Configuration\n*wconf* expects the following configuration properties to be defined:\n```\nwconf_encryption {\n  enabled: \u003ctrue|false\u003e\n  algorithm: \u003cthe symmetric algorithm to use, e.g. AES/CBC/PKCS5Padding\u003e\n  key_type: \u003cthe type of the secret key, e.g. AES\u003e\n  iv: \u003cthe initialization vector for the symmetric encryption process\u003e\n  key_store {\n    path: \u003cthe path to the JCEKS key store, to scan the JAR prefix with \"classpath://\", e.g. classpath://config/wconf-keystore.jceks\u003e\n    password: \u003cthe keystore password, e.g. mystorepasswd\u003e\n    key {\n      alias: \u003cthe key alias, e.g.wconf-secret-key\u003e\n      password: \u003cthe password key, e.g. mykeypasswd\u003e\n    }\n  }\n}\n```\n\nNote that this configuration can be included in the common or application level properties (or even merged between both common and application level properties).\nIf using profiles, it is a good practice to use different Key Stores for each profile.\n\nIf you don't know how to generate an initialization vector, please keep reading.\n\n### Encrypting Sensitive Properties\nIn order to specify an encrypted property you have to use the following syntax:\n```\nkey=\"cipher(\u003cencrypted-then-encoded-in-base64-value\u003e)\"\n```\n\nNote that the quotes `\"` are required because byte sequences encoded in Base64 typically include `=`.\n\nFor example:\n```\nfoo=\"cipher(PiWreyV5lSH8rqPP7/08lu67Lmkqsq0HSlNWImBrXUw=)\"\n```\n\nIf you don't know how to generate an *\"encrypted and then encoded in Base64 value\"*, please keep reading.\n\n### Cryptools\n[*Cryptools*](https://github.com/sergiofgonzalez/cryptools) is a simple Java application that can be used to:\n+ Generate an initialization vector for the symmetric encryption process\n+ Encrypt and Decrypt values to be used in *wconf*\n\n\n## Reserved Configuration Property Names\nThe configuration properties used to configure *wconf* are always prepended with `wconf_` and are reserved.\n\nThe current list all these reserved property names and their descriptions:\n\n| Reserved Property Name | Description | Default|\n|------------------------|-------------|--------|\n| wconf_app_properties | identifies the path and filename of the application level configuration file. | config/application.conf |\n| wconf_ext_app_properties_paths | an optional list of paths that will be scanned when looking for the application level configuration file outside the jar | [ \"./\" ] |\n| wconf_active_profile  | identifies the portion of the application level configuration that will be activated | n/a |\n| wconf_encryption.enabled | switches encryption support on and off | false |\n| wconf_encryption.algorithm | the string representing the symmetric algorithm to use, e.g. \"AES/CBC/PKCS5Padding\" | n/a |\n| wconf_encryption.key_type | the string representing the type of symmetric key found in the key store, e.g. \"AES\" | n/a |\n| wconf_encryption.iv | the initialization vector for the symmetric encryption process, encoded in base 64 | n/a |\n| wconf_encryption.key_store.path | the path to the JCEKS key store, which can be a path to a resource within the jar, e.g. config/wconf-keystore.jceks | n/a |\n| wconf_encryption.key_store.password | the key store password, e.g. mystorepasswd | n/a |\n| wconf_encryption.key_store.key.alias | the key alias, that is the string, used to identify the key to use for the symmetric encryption from the ones defined in the key store,  e.g.wconf-secret-key | n/a |\n| wconf_encryption.key_store.key.password | the password key that provides access to the key to use for the symmetric encryption, e.g. mykeypasswd | n/a |\n\nNote that the variables susceptible of being overridden by environment variables do not use `.` as there are operating systems that prevent variables such as `profile.active` from being defined.\n\n## Implementation Details and Recommendations\n*wconf* is defined as an eagerly-loaded singleton that loads and preconfigures the *Typesafehub Config* framework according to a set of predefined choices.\n\n*wconf* is targeted for lightweight, non-container based, read-only, non-refreshable use cases. If your use case allows for an IoC container I recommend you to have a look at [Spring Boot](https://projects.spring.io/spring-boot/). \n\nIf the opinionated choices of *wconf* are not acceptable, feel free to fork and modify the project, or fallback to the awesome framework in which *wconf* relies: [Typesafehub Config](https://github.com/typesafehub/config).\n\n## Tests and Examples\nTests can be found under `src/test/resources` and those serve also as usage examples for both accessing config properties and specifying configuration properties.\n\nThe [Cryptools](https://github.com/sergiofgonzalez/cryptools) also uses *wconf*.\n\nNote:\n+ Encryption feature has only been tested with AES256. Note that to use AES256 encryption you have to enable the JCE Unlimited Strength feature in your JRE/JDK. Failing to enable that feature may raise a `java.security.InvalidKeyException: Illegal key size` exception.\n\n## License\nThe license is MIT, see [LICENSE](./LICENSE) for the details.\n\n## Contributing\nContributions will be gladly accepted, but this section is currently in progress.\nFor general information see [general guidelines for contributing on GitHub](https://guides.github.com/activities/contributing-to-open-source/).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergiofgonzalez%2Fwaterfall-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsergiofgonzalez%2Fwaterfall-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsergiofgonzalez%2Fwaterfall-config/lists"}