:toc: macro
toc::[]

= Configuration

An application needs to be configurable in order to allow internal setup (like CDI) but also to allow externalized configuration of a deployed package (e.g. integration into runtime environment). We rely on a comprehensive configuration approach following a "convention over configuration" pattern. This guide adds on to this by detailed instructions and best-practices how to deal with configurations.

In general we distinguish the following kinds of configuration that are explained in the following sections:

* xref:internal-application-configuration[Internal Application configuration] maintained by developers
* xref:externalized-configuration[Externalized Environment configuration] maintained by operators
* xref:business-configuration[Externalized Business configuration] maintained by business administrators

== Internal Application Configuration
The application configuration contains all internal settings and wirings of the application (bean wiring, database mappings, etc.) and is maintained by the application developers at development time.

For more detail of link:spring[Spring] stack, see link:spring/guide-spring-configuration#internal-application-configuration[here]

== Externalized Configuration

Externalized configuration is a configuration that is provided separately to a deployment package and can be maintained undisturbed by re-deployments.

=== Environment Configuration

The environment configuration contains configuration parameters (typically port numbers, host names, passwords, logins, timeouts, certificates, etc.) specific for the different environments. These are under the control of the operators responsible for the application.

The environment configuration is maintained in `application.properties` files, defining various properties.
These properties are explained in the corresponding configuration sections of the guides for each topic:

* persistence configuration (for Spring see link:spring/guide-spring-configuration#database-configuration[here], for Quarkus see link:quarkus/guide-quarkus-configuration#database-configuration[here])
* link:guide-service-layer#jax-rs-configuration[service configuration]
* link:guide-logging#configuration[logging guide]

Make sure your properties are thoroughly documented by providing a comment to each property. This inline documentation is most valuable for your operating department.

More about structuring your `application.properties` files can be read link:spring/guide-spring-configuration#application-properties-files[here] for Spring.

For Quarkus, please refer to https://quarkus.io/guides/config-reference[Quarkus Config Reference] for more details.

=== Business Configuration
Often applications do not need business configuration. In case they do it should typically be editable by administrators via the GUI. The business configuration values should therefore be stored in the database in key/value pairs.

Therefore we suggest to create a dedicated table with (at least) the following columns:

* ID
* Property name
* Property type (Boolean, Integer, String)
* Property value
* Description

According to the entries in this table, an administrative GUI may show a generic form to modify business configuration. Boolean values should be shown as checkboxes, integer and string values as text fields. The values should be validated according to their type so an error is raised if you try to save a string in an integer property for example.

We recommend the following base layout for the hierarchical business configuration:

`component.[subcomponent].[subcomponent].propertyname`


== Security
Often you need to have passwords (for databases, third-party services, etc.) as part of your configuration. These are typically environment specific (see above). However, with DevOps and continuous-deployment you might be tempted to commit such configurations into your version-control (e.g. `git`). Doing that with plain text passwords is a severe problem especially for production systems. Never do that! Instead we offer some suggestions how to deal with sensible configurations:

=== Password Encryption
A simple but reasonable approach is to configure the passwords encrypted with a master-password. The master-password should be a strong secret that is specific for each environment. It must never be committed to version-control.

For link:spring[Spring], we use https://github.com/ulisesbocchio/jasypt-spring-boot#jasypt-spring-boot[jasypt-spring-boot]. For more details, see link:spring/guide-spring-configuration#password-encryption[here]

For link:quarkus[Quarkus], see link:quarkus/guide-quarkus-configuration#password-encryption[here]

==== Is this Security by Obscurity?

* Yes, from the point of view to protect the passwords on the target environment this is nothing but security by obscurity. If an attacker somehow got full access to the machine this will only cause him to spend some more time.
* No, if someone only gets the configuration file. So all your developers might have access to the version-control where the config is stored. Others might have access to the software releases that include this configs. But without the master-password that should only be known to specific operators none else can decrypt the password (except with brute-force what will take a very long time, see jasypt for details).
