Manage distributed configuration and secrets with Spring Cloud and Vault

Andreas Falk

Friday 19th May, 2017

Andreas Falk

http://www.novatec-gmbh.de

andreas.falk@novatec-gmbh.de

@NT_AQE, @andifalk

Agenda

A6: Sensitive Data Exposure

https://github.com/OWASP/Top10

Typical sensitive data

Passwords

Database credentials

OAuth2 client secrets

Encryption keys

Sensitive user data

Credit card numbers

Application Properties

Database access credentials


                        spring.datasource.url=jdbc:postgresql://localhost/test
                        spring.datasource.username=root
                        spring.datasource.password=mysupersecretpassword
                    

Spring Cloud Config

https://cloud.spring.io/spring-cloud-config

Spring Cloud Config

https://cloud.spring.io/spring-cloud-config

Externalized configuration in a distributed system

HTTP, resource-based API

Supports property file and YAML formats

Encrypt and decrypt property values

Gradle Dependencies


                            ext {
                                springCloudVersion = 'Dalston.RELEASE'
                            }

                            dependencies {
                                compile('org.springframework.cloud:
                                            spring-cloud-config-server')
                            }

                            dependencyManagement {
                                imports {
                                    mavenBom "org.springframework.cloud:
                                            spring-cloud-dependencies:${springCloudVersion}"
                                }
                            }
                        

Spring Cloud Config Server

Just one additional annotation


                            @EnableConfigServer
                            @SpringBootApplication
                            public class ConfigServerApplication {

                                public static void main(String[] args) {
                                    SpringApplication.run(
                                        ConfigServerApplication.class, args);
                                }
                            }
                        

Spring Cloud Config Server

Configuration


                            spring.cloud.config.server.git.uri=
                                https://github.com/andifalk/cloud-config-repository
                            server.port=8888
                            security.basic.enabled=true
                            security.user.name=admin
                            security.user.password=secret
                        

Spring Cloud Config

Encryption and Decryption

https://cloud.spring.io/spring-cloud-static/Dalston.RELEASE/#_security

Spring Cloud Config Server

Symmetric Key Configuration


                            encrypt.key=MyVerySecureEncryptionKey
                        

Spring Cloud Config Server

Asymmetric Key Configuration


                            encrypt.key-store.location=classpath:configserver.jks
                            encrypt.key-store.alias=configserver
                            encrypt.key-store.password=secret
                            encrypt.key-store.secret=secret
                        

Spring Cloud Config Server

Encrypting data


                            $ curl -u admin:secret -d test http://localhost:8888/encrypt

                            AQAx/RH8tiJj9V43l4dwAxhh0bXGPYa2UjRGOM8s5z2EmCXWRU5DLPzxGptF08nEo
                            kE+BfZPm4A3vco3volhWdYQcCAFguX+6LOvoxewv5AyfkIt1E0bTc7sa4wSSeBGG4
                            SZ1K/nkto4e6jH+5tktLiPpXoABzvy3YsAgXZ6j5zUM320cWEd4QBSoB0mYP5Kfsq
                            EFbFEUBm2wMyUSFB4/NXn5apn8KZ2c2WTAj/jZlrg/jI4Sz094zDzRaM+iZuqHjaU
                            xVng+3dTsz9DQ9rhfWFllmrtUyoKwgNWLuegV6neDsHGdz7F1bucvJ2CzEZb3tp76
                            K2RrP0m9KPesTZMtbUH2/g9uUDORh/95P1s+dRt0QznwlXshtnb8Hu3i7GdkmA=
                        

Spring Cloud Config Server

Decrypting data


                            $ curl localhost:8888/decrypt -u admin:secret -d AQAx/RH8tiJj9V43l4
                            dwAxhh0bXGPYa2UjRGOM8s5z2EmCXWRU5DLPzxGptF08nEokE+BfZPm4A3vco3vol
                            hWdYQcCAFguX+6LOvoxewv5AyfkIt1E0bTc7sa4wSSeBGG4SZ1K/nkto4e6jH+5tk
                            tLiPpXoABzvy3YsAgXZ6j5zUM320cWEd4QBSoB0mYP5KfsqEFbFEUBm2wMyUSFB4/
                            NXn5apn8KZ2c2WTAj/jZlrg/jI4Sz094zDzRaM+iZuqHjaUxVng+3dTsz9DQ9rhfW
                            FllmrtUyoKwgNWLuegV6neDsHGdz7F1bucvJ2CzEZb3tp76K2RrP0m9KPesTZMtbU
                            H2/g9uUDORh/95P1s+dRt0QznwlXshtnb8Hu3i7GdkmA=

                            test
                        

Spring Cloud Config Server

Encrypted sensitive property values


                            secretkey={cipher}AQBcFzU3gDVVdj0P2uX/60LzeFqQi8Bo2sCTOiiMSe+w
                                Yq4f0smM8HES0TKesr8Nms+EqgV5t9Rld7PGALjVUAAfHjAf6WS1yYz3K+
                                NvXrgu8umjOyRDxfKBh5OH2jvYX+EiKv/JgwDeUg3TXnTnsheh3Mim0dSu
                                fkojbBlWxO8HsfW5z1qG9tLSlHnWvtcpIGLdRAUwfcKw+/1SViuYxwi/p9
                                H+J/SOomr4hjjnCuaFITa0zfQc4XTLOrGxW64dhghDvCgu3BxMe0TRaBci
                                Ugkqka4zgBmzge0kw7r82b84GELmDGpjDp7HRUB+cVHqzZXuQzQB9vCjq1
                                xI19e6ZQm62DkOxaqtafGxqw+VmyFl1+XYEs1k2lWkiUMVyJyiixI=
                        

Demo

Vault

Key Management

https://www.vaultproject.io/

Secret Storage

Key Revocation

Key Rolling

Audit Logs

Secret Storage

Encryption (AES cypher)

Dynamic Secrets

Access control policies

Lease time (automatic revocation)

Audit Logs

Not active by default

Sensitive data hashed (HMAC-SHA256)

Targets: File, Syslog, Socket


                            ...
                            ,"path":"secret/hello","data":null,"remote_address":"127.0.0.1"
                            ,"wrap_ttl":0,"headers":{}},"response":{"secret":{"lease_id":""}
                            ,"data":{"value":"hmac-sha256:213d0d2572fe27ffd0cd2d97cf009c2d0
                                2e97b5af3f81b9af41f593982ffae8c"}},"error":""}
                        

Authentication

Token (default)

AppId

AppRole

TLS client certificate

AWS, GitHub, ...

Rotate, Repair, Repave

Justin Smith (Pivotal)

Secret Backends

Getting dynamic credentials (with lease time)

AWS

Consul

MongoDB

Databases (MySQL, PostgreSQL, Cassandra)

RabbitMQ, and many more...

Start vault server


                            $ vault server -config=./memory.conf
                        

memory.conf


                            storage "inmem" {
                            }
                            listener "tcp" {
                                address     = "127.0.0.1:8200"
                                tls_disable = 1
                            }
                            disable_mlock = true
                        

Initialize vault server


                            $ vault init -key-shares=5 -key-threshold=2

                            Unseal Key 1: v236b4yJQDnaJ3EmkOhycZTcxTJfMbNeILqxWfRpzGn0
                            Unseal Key 2: g1tV/d4vp7VVbOu93aHrHZt41xE5YtX7yYBsFMIXGHCf
                            Unseal Key 3: rAI5FwrVF8XFUD7BOtTer9bL4A39HxHhnXQo85uSyphf
                            Unseal Key 4: kDSWhVhz8ElKG6Rad51Hw9lv8i6bTHdEdE71vq3sHoE0
                            Unseal Key 5: 4KUY7CS+UBi5lxlwpCRY+sWXdPFDp68rX2F6bTxT0nHF
                            Initial Root Token: 68a80410-e315-fc39-d1ad-9864e169a47f

                            Please securely distribute the above keys. When the vault is
                            re-sealed, restarted, or stopped, you must provide at least 2
                            of these keys to unseal it again.

                            Vault does not store the master key. Without at least 2 keys,
                            your vault will remain permanently sealed.
                        

Unseal vault server


                            $ vault unseal v236b4yJQDnaJ3EmkOhycZTcxTJfMbNeILqxWfRpzGn0

                            Sealed: true
                            Key Shares: 5
                            Key Threshold: 2
                            Unseal Progress: 1
                            Unseal Nonce: 3a7f80b8-9aa4-2338-8a0a-0295331962d7

                            $ vault unseal rAI5FwrVF8XFUD7BOtTer9bL4A39HxHhnXQo85uSyphf
                            Sealed: false
                            Key Shares: 5
                            Key Threshold: 2
                            Unseal Progress: 0
                            Unseal Nonce:
                        

Authenticate with vault server


                            $ vault auth 68a80410-e315-fc39-d1ad-9864e169a47f

                            Successfully authenticated! You are now logged in.
                            token: 68a80410-e315-fc39-d1ad-9864e169a47f
                            token_duration: 0
                            token_policies: [root]
                        

Write and read secrets


                            $ vault write secret/mysecret hello=world

                            Success! Data written to: secret/mysecret

                            $ vault read secret/mysecret

                            Key             	Value
                            ---             	-----
                            refresh_interval	768h0m0s
                            hello           	world
                        

Demo

Spring Cloud Vault

https://cloud.spring.io/spring-cloud-vault

Gradle Dependencies


                            ext {
                                springCloudVersion = 'Dalston.RELEASE'
                            }

                            dependencies {
                                compile('org.springframework.cloud:
                                            spring-cloud-starter-vault-config')
                            }

                            dependencyManagement {
                                imports {
                                    mavenBom "org.springframework.cloud:
                                            spring-cloud-dependencies:${springCloudVersion}"
                                }
                            }
                        

Secret data mapping

bootstrap.properties


                            spring.cloud.vault.generic.application-name =
                                    application1,additional/keys
                            #spring.cloud.vault.application-name = ...
                            #spring.application.name = ...
                        

Mapped secret paths in vault


                            /secret/application1
                            /secret/application1/myprofile
                            /secret/additional/keys
                            /secret/application
                            /secret/application/myprofile
                        

Demo

Rotate Database Credentials

bootstrap.yml


                            spring.cloud.vault:
                                postgresql:
                                    enabled: true
                                    role: readonly
                                    backend: postgresql
                                    username-property: spring.datasource.username
                                    password-property: spring.datasource.username
                        

Spring Cloud Config Vault Environment Repository

application.properties (Config Server)


                            spring.profiles.active=vault
                            spring.cloud.config.server.vault.host=127.0.0.1
                            spring.cloud.config.server.vault.port=8200
                            spring.cloud.config.server.vault.scheme=https
                        

bootstrap.properties (Client)


                            spring.cloud.config.token = YourVaultToken
                        

Target Achieved?

References

All images used are from Pixabay and are published under Creative Commons CC0 license.

All used logos are trademarks of corresponding companies

Q&A

http://www.novatec-gmbh.de
http://blog.novatec-gmbh.de

andreas.falk@novatec-gmbh.de

@NT_AQE, @andifalk