Working with encrypted properties through config server

The config server could be a Spring Boot application running securely or it can be an instance of configService of Spring Cloud Services (SCS) Pivotal tile. The assumption here is secured config server is running, and applications need to use this secured config-server.

Config server uses default strategy for locating property sources is and clones a git repository (at spring.cloud.config.server.git.uri) , and use it to initialize SpringApplication. The application’s Environment is used to enumerate property sources and publish them via a JSON endpoint.

The HTTP service has resources in the form:

/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties

Usually, in secured config server, the remote property sources contain encrypted content (values starting with {cipher}) they will be decrypted before sending to clients over HTTP. The main advantage of this set up is that the property values don’t have to be in plain text when they are "at rest" (e.g. in a git repository). If a value cannot be decrypted it is removed from the property source and an additional property is added with the same key, but prefixed with "invalid." and a value that means "not applicable" (usually ""). This is largely to prevent cipher text being used as a password and accidentally leaking.

Encrypted values in an application.yml file can be wrapped in quotes: spring: datasource: username: dbuser password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'

Encrypted values in a .properties file must not be wrapped in quotes, otherwise the value will not be decrypted: spring.datasource.password: `{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ

Since the config server is supporting encryption and decryption of property values, you can use public repositories as storage for sensitive data like usernames and passwords. Encrypted values are prefixed with the string {cipher} and can be generated by an REST-call to the path ‘/encrypt’, if the server is configured to use a symmetric key or a key pair.

An endpoint to decrypt is also available. Both endpoints accept a path containing placeholders for the name of the application and its current profile: ‘/*/{name}/{profile}’. This is especially useful for controlling cryptography per client. However, before they become useful, you have to configure a cryptographic key which we will do in the next section.

Tip: If you use curl to call the en-/decryption API, it’s better to use the –data-urlencode option (instead of –data/-d), or set the ‘Content-Type’ header explicit to ‘text/plain’. This ensures a correct handling of special characters like ‘+’ in the encrypted values.

The server exposes /encrypt and /decrypt endpoints (on the assumption that these will be secured and only accessed by authorized agents). The SCS Config Server exposes VCAP_VARIABLES so that client application can use those variables to access the properties form config server.

If you want to disable server-side cryptography and handle decryption of property-values locally, you can put the following in your server’s application.properties:

spring.cloud.config.server.encrypt.enabled=false

Config server can be deployed as a multi-application served wide shared configuration service (for production and non-production environment by using the profile annotation). Since all the production passwords are encrypted using the config server /encrypt endpoint, it is not OK to allow developers have direct access to the config server without authentication. Basic HTTP authentication with the config Server and its bootstrap.yml looks like the following:

encrypt: failOnError: false keyStore: location: classpath:config-server.jks alias: config-server password: ******

One should use a different keypair for the config server login credential on the client side (not the server side). Putting the production config server password in bootstrap.yml checked into source control, is probably not the way to go about securing the config server. On the production server you could use an environment variable (SPRINGCLOUDCONFIG_PASSWORD) or use a separate keypair (or encrypt.key) on the client side to encrypt/decrypt the password for config server clients. Client side password should be assigned onto the production config server as env variable so nothing will check into the source control.

Contactez-nous