From c167e1be77fd79a344c788fc23aff955c70265d5 Mon Sep 17 00:00:00 2001 From: Stenio Ferreira Date: Fri, 8 Jun 2018 15:20:39 -0500 Subject: [PATCH] Updated PCF example README --- secrets/spring-cloud-vault/pcf/README.md | 148 +++++++++++++++++++++-- 1 file changed, 139 insertions(+), 9 deletions(-) diff --git a/secrets/spring-cloud-vault/pcf/README.md b/secrets/spring-cloud-vault/pcf/README.md index bf542adc..32df6a1e 100644 --- a/secrets/spring-cloud-vault/pcf/README.md +++ b/secrets/spring-cloud-vault/pcf/README.md @@ -1,14 +1,26 @@ -# spring-vault-demo-pcf +# Spring example with Spring Cloud Vault and Cloud Foundry. -This folder will help you deploy the sample app to Pivotal Cloud Foundry PCF. +TODO: Externalize DB url with Spring Config Server in [bootstrap config](src/main/resources/bootstrap.yaml) -## Requirements -- A PCF environment with Vault PCF Service Broker deployed and configured. More information about the service broker can be found [here](https://www.hashicorp.com/blog/cloud-foundry-vault-service-broker) -- A properly configured Vault. Make sure you run this [script](../scripts/vault.sh). You will need to update the DB connection string. -- A properly configured Postgres DB with the "order" table. Make sure you run this [script](../scripts/postgres.sql) -- Docker properly configured in your machine, with access to Docker Hub to push the image. More information [here](https://docs.docker.com/docker-hub/) -- Maven installed in your machine, to generate the jar file. More information [here](https://maven.apache.org/install.html) -- cf client installed in your machine. More information [here](https://docs.cloudfoundry.org/cf-cli/install-go-cli.html) +## Description +App that shows the following functions: +- PCF integration with Vault using service broker +- Reading Vault static secrets on appId generic path +- Reading Vault static secrets on orgId generic path +- Vault dynamic credentials +- Vault transit backend + +This app will upload a Docker image to your Docker hub repository, with a sample java Spring applciation that uses Vault. Then it will deploy this image as a PCF app. + +## Requirements: +- A Vault server configured with transit backend. See [vault config](external/vault_config.sh) +- A Postgres DB secret engine with configured Vault roles. See [vault config](external/vault_config.sh) +- A Postgres DB with the "order" table. See [sql query](external/postgres.sql) +- A PCF env with Vault Service Broker + +Reference: https://github.com/hashicorp/vault-service-broker + +![picture alt](https://github.com/stenio123/spring-vault-demo-cf/blob/master/VaultServiceBrokerPCF.jpg "Reference PCF Vault Service Broker ") ## Deployment - Enter the following environment variables in (deploy.sh)[deploy.sh]: @@ -42,4 +54,122 @@ $ curl -s \ --data '{"secret":"hello-new"}' \ --write-out "%{http_code}" ${VAULT_ADDR}/v1/secret/$PCF_APP_NAME | jq 204 +``` + +## Vault Policy +By default, the PCF Vault Service Broker only mounts the static secrets backend. In order to enable the dynamic db secrets, after you have bound the service broker follow the steps [here](https://github.com/hashicorp/vault-service-broker#granting-access-to-other-paths) to grant the app access to central DB and Transit policies. Below is an example policy. +``` +path "cf/63e3e3a0-31f5-4b28-b38b-6708339df836" { + capabilities = ["list"] +} + +path "cf/63e3e3a0-31f5-4b28-b38b-6708339df836/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +path "cf/a3abff6c-a00a-49d3-bca5-8384a9ec2299" { + capabilities = ["list"] +} + +path "cf/a3abff6c-a00a-49d3-bca5-8384a9ec2299/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +path "cf/32ff778e-0db4-4d24-8629-b316ba71fda4" { + capabilities = ["list"] +} + +path "cf/32ff778e-0db4-4d24-8629-b316ba71fda4/*" { + capabilities = ["read", "list"] +} + +path "transit/decrypt/order" { + capabilities = ["update"] +} + +path "transit/encrypt/order" { + capabilities = ["update"] +} + +path "database/creds/order" { + capabilities = ["read"] +} +``` +If instead you want the service broker to handle these additional backends, you can fork the repository and add paths [here](https://github.com/hashicorp/vault-service-broker/blob/dfe5aaca53aa805e6cd2dd7f703603670594787b/broker.go#L338) + +## Seeding Static Secrets: +This application uses Spring Boot Vault to interact with Vault. For complete documentation follow this [link](http://cloud.spring.io/spring-cloud-static/spring-cloud-vault/2.0.0.M4/) + +To seed secrets: +``` +export VAULT_ADDR=ADDRESS_TO_YOUR_VAULT_SERVER +export VAULT_TOKEN=YOUR_APP_TOKEN +export PCF_ORG_ID=YOUR_PCF_ORG_ID +export PCF_APP_ID=YOUR_PCF_APP_ID + +curl \ + --header "X-Vault-Token: $VAULT_TOKEN" \ + --request POST \ + --data @external/appId.json \ + $VAULT_ADDR/v1/cf/$PCF_APP_ID/secret/cf-spring-vault + +curl \ + --header "X-Vault-Token: $VAULT_TOKEN" \ + --request POST \ + --data @external/orgId.json \ + $VAULT_ADDR/v1/cf/$PCF_ORG_ID/secret/shared +``` + +To read the secrets: +``` +http://cf-spring-vault-busy-roan.apps.pcf-environment.spacelyspacesprockets.info/api/orders/app_secret + +http://cf-spring-vault-busy-roan.apps.pcf-environment.spacelyspacesprockets.info/api/orders/org_secret +``` + +## Dynamic DB Credentials and Transit Backend: +Once deployed, the following API endpoints will be available: + +POST: +* The post function will create an order with customer and product info +* The application is securely introduced to Vault via the broker +* The application uses dynamic DB credentials retrieved by Spring Cloud Vault +* The application uses the Vault transit backend to encrypt customer name +* The encrypted order is persisted to the DB. + +Example call: +``` +curl -k -X POST https://cf-spring-vault.apps.ll.pcf.com/api/orders -H 'content-type: application/json' -d '{"customerName": "lance", "productName": "vault-ent"}' | jq +``` +Example response: +``` +{ + "id": 59, + "customerName": "lance", + "productName": "vault-ent", + "orderDate": 1520878732443 +} +``` + +* The get function will return all customer order info +* The application is securely introduced to Vault via the broker +* The application uses dynamic DB credentials retrieved by Spring Cloud Vault +* The application decrypts all customer records +* The decrypted orders are returned in the API. + +Example call: +``` +curl -k https://cf-spring-vault.apps.ll.pcf.com/api/orders | jq +``` + +Example response: +``` +[ + { + "id": 58, + "customerName": "lance", + "productName": "vault-ent", + "orderDate": 1520878677996 + } +] ``` \ No newline at end of file