Pivotal + VMware: Transforming how more of the world builds software

Encrypt/Decrypt keys using Spring Cloud Config Server

Spring Cloud Services packages Spring Cloud projects like Config Server, Hystrix Dashboard and Eureka into a set of Cloud Foundry marketplace items that can be provisioned easily by a developer.

The Spring Cloud Services Config Server externalizes configuration information of an application and serves out this configuration using a REST based interface. It has the ability to store and serve encrypted configuration values and this recipe will go into the details of how to provision and test this feature.

Pre-requisite

There are a few pre-requisites that need to be in place before the config server instance can be created:

  1. Ensure that there is a git repository holding the property files as described here.
  2. Ensure that deployment keys have been assigned to the repo. If the repo is github based, then the keys can be generated using the following command
ssh-keygen -t rsa -b 2048 -C "test@test.com" -f gitkeys -N ''

the generated gitkeys.pub can be placed as a deployment key in github

Provisioning a SCS Config Server with encrypt keys

If the intent is to let config server handle both storing of encrypted values and serving out decrypted values, then there are two potential ways in which config server instance can handle this:

  1. Using symmetric key
  2. Using asymmetric keys

Approach 1 - Using Symmetric Key

  1. Create a configuration file for SCS Config server instance with encrypt.key set to a secret text based key: The git.privateKey here is the private key corresponding to the git deploy key specified in the Pre-requisite section. The privateKey has the newlines replaced with \n json { "git": { "uri": "ssh://git@github.com/someuser/sample-config.git", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAycu6z3mh0froKoRkEYgsGAbYq6te3Yn7T9XAgQfWju7tKL10\nHyrQj1FC92Z35MViOyk5FPh/fHVIQgAg2y/dyKXPzEKFbiXPRHWWi8Zdez3ADzxQ\nCrym3G6fR3bxMWdi73FtYQBrExG/uaj6Z+2g8xMLR08pDtwaH6iQb27wgmmbvvO5\nWPjZ...bbf3\n-----END RSA PRIVATE KEY-----" }, "encrypt": { "key": "samplekey" } }

  2. Create the config server instance: bash cf create-service p-config-server standard config-server -c config-server.json

Approach 2 - Using Asymmetric Key

  1. Generate a Keypair using the following command: bash openssl genrsa -out privkey.pem 1024 cat privkey.pem | tr -d '\n' > nonewline_server_rsa.key

  2. Use the content of nonewline_server_rsa.key file to generate a config-server.json file with content like this. Note All the newlines have been removed from the private key of the encrypt.key, only this form of key works for this field: json { "git": { "uri": "ssh://git@github.com/someuser/sample-config.git", "privateKey": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAycu6z3mh0froKoRkEYgsGAbYq6te3Yn7T9XAgQfWju7tKL10\nHyrQj1FC...K3V5GHbbf3\n-----END RSA PRIVATE KEY-----" }, "encrypt": { "key": "-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDoMbFRys1BuBayW5mmYoN6HrXff/J2s8dijn80u5Qf6eR39n6B+424d49IDM9ErQw9JcGZnXiIxW4QU6JwECQBu6kZ/TgxyJqS1Y14Je9wIXlpiU++MMCzNT3iTI3BlBP5Gmu4M1uvexUte41K7XzimKg8UyXUV2c9DWznrdXfcCQQCpdbRJ29/dt3QkrP9t3TbvkV5ITBKJxf/gRlJagN0YNyRKSQL8cMUDVcQxpXUbfCsPAsQ/9lZ5SjSfJJVjiIQE-----END RSA PRIVATE KEY-----" } }

  3. Create the config server instance: bash cf create-service p-config-server standard config-server -c config-server.json

Handy Scripts to work with the config server instance

SCS Config server works with 2 different set of credentials, an Application credential generated at the point of binding to the service to retrieve properties of an application and a user credential of a user in the space where the service is created to call the /encrypt endpoint.

Retrieve the properties of an app called myapp

  1. Create a temporary credential for the service using create-service-key command: bash cf create-service-key config-server config-server-key

  2. Grab and store the credential into a config-server-key.json file: bash cf service-key config-server config-server-key | tail -n 6 > config-server-key.json

  3. Get the properties of myapp in default profile

#!/bin/bash
# Get details form config-server-key.json file
access_token_uri=$(cat config-server-key.json | jq -r ".access_token_uri")
client_id=$(cat config-server-key.json | jq -r ".client_id")
client_secret=$(cat config-server-key.json | jq -r ".client_secret")
uri=$(cat config-server-key.json | jq -r ".uri")

# Get the token using apps client credentials
TOKEN=$(curl -k $access_token_uri -u $client_id:$client_secret -d grant_type=client_credentials 2>/dev/null | jq -r .access_token)
# OR with httpie
# TOKEN=$(http --body --form POST ${access_token_uri} grant_type=client_credentials --auth $client_id:$client_secret | jq -r .access_token)

# Get the properties of myapp, in default profile
curl -k -H "Authorization: bearer $TOKEN" $uri/myapp/default

Encrypt properties

A handy script to encrypt properties looks like this:

#!/bin/bash
toencrypt=${1}

CF_TOKEN=$(cf oauth-token)

curl -X POST -k -H "Authorization: $CF_TOKEN" $uri/encrypt -d $toencrypt
Contact us