This how my bootstrap.yml looks like.
spring:
cloud:
config:
uri: http://xxxx.com
username: ****
password: ****
vault:
host: vault-server
port: 8200
scheme: http
authentication: token
token: ${VAULT_ROOT_TOKEN}
application:
name: service-name
management:
security:
enabled: false
Application is starting when I configure secret as a ENV variable in Deployment Config – OSE, as below.
name: VAULT_ROOT_TOKEN
value: *********
But Configuring secret as a ENV variable and fetching the value from OSE secret is not working.
name: VAULT_ROOT_TOKEN
valueFrom:
secretKeyRef:
name: vault-token
key: roottoken
Error that I am getting is
org.springframework.vault.VaultException: Status 400 secret/service-name/default: 400 Bad Request: missing required Host header
Surprise in this scenario, ENV variable is working within the container/POD but somehow it is not able to fetch during the bootstrap procedure.
env | grep TOKEN
VAULT_ROOT_TOKEN=********
My secret configuration in OSE
oc describe secret vault-token
Name: vault-token
Namespace: ****
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
roottoken: 37 bytes
What is missing in my deployment-config or secrets in OSE? How to configure to fetch secret as ENV variable and inject in the bootstrap.yml file?
NOTE : I can't move Vault configuration out of bootstrap.yml.
Openshift Enterprise info:
Version:
OpenShift Master:v3.2.1.31
Kubernetes Master:v1.2.0-36-g4a3f9c5
Finally I was able to achieve this. This is what I have done
Provide the token as an arugument:
java $JAVA_OPTS -jar -Dspring.cloud.vault.token=${SPRING_CLOUD_VAULT_TOKEN} service-name.jar
This is how my configuration looks like:
Deployment Config:
- name: SPRING_CLOUD_VAULT_TOKEN
valueFrom:
secretKeyRef:
name: vault-token
key: roottoken
Bootstrap file:
spring:
cloud:
config:
uri: http://xxxx.com
username: ****
password: ****
vault:
host: vault-server
port: 8200
scheme: http
authentication: token
token: ${SPRING_CLOUD_VAULT_TOKEN}
application:
name: service-name
management:
security:
enabled: false
Thanks for my colleagues who has provided the inputs.
Related
I'm trying to read secret values using spring vault. All the properties for client application is stored in github and spring config server is used to access the properties. When I add the vault configuration to client application bootstrap.yml as below, the values are read properly.
bootstrap.yml
spring:
application:
name: client-app
cloud:
config:
uri: http://config-server:8080
vault:
enabled: true
authentication: APPROLE
app-role:
role-id: 12345
secret-id: 12345
role: pres-read
app-role-path: approle
connection-timeout: 5000
read-timeout: 15000
kv:
enabled: true
backend: secrets
application-name: client-app
uri: https://vault/
application.yml in config server
spring:
cloud:
config:
server:
git :
uri: https://github/repo.git
username: abc
password: pass
refreshRate: 300
Based on https://docs.spring.io/spring-cloud-vault/docs/current/reference/html/config-data.html#vault.configdata , it should be possible to load the vault config from properties yml in github. But if i move the above vault config to my client-app.yml in github, the properties are not read from the vault. How do I achieve this?
I am trying to define a livenessProbe by passing the value of httpheader as secret. but I am getting un-authorized 401.
- name: mycontainer
image: myimage
env:
- name: MY_SECRET
valueFrom:
secretKeyRef:
name: actuatortoken
key: token
livenessProbe:
httpGet:
path: /test/actuator/health
port: 9001
httpHeaders:
- name: Authorization
value: $MY_SECRET
My secret as follows:
apiVersion: v1
kind: Secret
metadata:
name: actuatortoken
type: Opaque
stringData:
token: Bearer <token>
If I pass the same with actual value as below... it works as expected
- name: mycontainer
image: myimage
livenessProbe:
httpGet:
path: /test/actuator/health
port: 9001
httpHeaders:
- name: Authorization
value: Bearer <token>
Any help is highly appreciated.
What you have will put the literal string $MY_SECRET as the Authorization header which won't work.
You don't want to put the actual value of the secret in your Pod/Deployment/whatever YAML since you don't want plaintext credentials in there.
3 options I can think of:
a) change your app to not require authentication for the /test/actuator/health endpoint;
b) change your app to not require authentication when the requested host is 127.0.0.1 and update the probe configuration to use that as the host;
c) switch from an HTTP probe to a command probe and write the curl/wget command yourself
Answer is being posted as Community wiki as it's from Amit Kumar Gupta comments.
In local machine, I ran Vault server with default policy and wrote the following key value.
vault write secret/my-application username=Test
bootstrap.yml (Working)
spring:
application:
name: my-application
cloud:
vault:
authentication: TOKEN
token: sometoken
host: localhost
port: 8200
scheme: http
#uri: http://localhost:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
I was able to fetch the value using Spring Cloud Vault i.e. when I use default mount (secret). But If I hit the QA server with the custom mount(group) I am getting the following error.
org.springframework.vault.VaultException: Status 403 secret/group/grouptype/groupname/DB: permission denied
(Not sure why secret is prefixed)
bootstrap.yml (Not working)
spring:
application:
name: group/grouptype/groupname/DB
cloud:
vault:
authentication: TOKEN
token: sometoken
host: 10.20.30.40
port: 8200
scheme: http
#uri: http://10.20.30.40:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
But if I hit the API from POSTMAN it is working as expected.
GET
http://10.20.30.40:8200/v1/group/grouptype/groupname/DB
Header:
X-Vault-Token:sometoken
How to make custom proxy work with Spring boot application. How to exclude secret from the context
For a custom mount, we have to add generic
spring:
application:
name: grouptype/groupname/DB
cloud:
vault:
authentication: TOKEN
token: sometoken
generic:
enabled: true
backend: group
default-conext: grouptype/groupname/DB
host: 10.20.30.40
port: 8200
scheme: http
#uri: http://10.20.30.40:8200
connection-timeout: 5000
read-timeout: 15000
config:
order: -10
Here "group" is the mount name
I cannot Create properties as I get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'configClient': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'user.role' in value "${user.role}"
I am following this tutorial:
http://www.baeldung.com/spring-cloud-configuration
I am using
#Value("${user.role}")
and
#Value("${user.role:}")
does not fetch any information.
I have the same issue that you when I tried the tutorial. It seems the client can't achieve the server to resolve the property 'user.role', in my case, the error was the wrong property:
spring.application.name: config-client
You can check the configurations of the server, If you can access your github repo with configs. With server running, like this:
curl http://root:s3cr3t#localhost:9090/config-client/development/master [13:26:43]
{"name":"config-client","profiles":["development"],"label":"master","version":"80d048de5faa3314429a1fce1645917786da28d6","state":null,"propertySources":[{"name":"https://gitlab.com/marcosnasp/spring-config-baeldung-tutorial.git/config-client-development.properties","source":{"user.role":"Developer"}}]}%
I used the the yml config for both, and a different port for the server 9090, the client port by default, since I have not configured in application.properties is the 8080, client and server, at looks like:
the client config:
bootstrap.yml
spring:
application:
name: config-client
profiles:
active: development
cloud:
config:
uri: http://localhost:9090
username: root
password: s3cr3t
fail-fast: true
the server config:
bootstrap.yml
spring:
application:
name: delivery-config-server
encrypt:
key-store:
location: classpath:/config-server.jks
password: my-s70r3-s3cr3t
alias: config-server-key
secret: my-k34-s3cr3t
application.yml:
server:
port: 9090
spring:
cloud:
config:
server:
git:
uri: https://gitlab.com/marcosnasp/spring-config-baeldung-tutorial.git
timeout: 10
clone-on-start: true
security:
user:
name: root
password: s3cr3t
I have configured a Spring Cloud Config server to force BASIC authentication and here is my application.yml file:
# Config Repo:
spring:
cloud:
config:
server:
git:
uri: file:///${HOME}/microservices_config_repo
# Show sensitive information for endpoints:
endpoints:
sensitive: true
# Security for endpoints:
management:
security:
enabled: true
security:
user:
name: user1
password: changeme
My issue I am having is that when I start the server up as:
mvn spring-boot:run
The server endpoints FORCE BASIC Authentication.
But when I start the Application.main() method, BASIC Authentication is enabled, but NOT enforced.
Meaning I can access configuration on:
http://localhost:8888/client-config
and
http://user1:changeme#localhost:8888/client-config
Can anyone help me understand why this is occuring and how to enforce BASIC Authentication while running the Application.main(), and not just through the Maven spring-boot plugin?
Note, when I use maven to package the app into a jar, then run the generated jar, BASIC Authentication is enforced, but still not through the IDE running just the Application.main directly.
Maybe the format the oy Yaml for example to me seems works like this:
server:
port:9999
spring:
application:
name: config-server-sample
cloud:
config:
name: ${spring.application.name}
fail-fast: true
server:
git:
uri: url
username: xx
password: zz
default-label: master
basedir: '${user.home}/${spring.application.name}/default'
timeout: 10
clone-on-start: true
force-pull: true
security:
basic:
enabled: true
path: /**
ignored: /health**,/info**,/metrics**,/trace**
user:
name: admin
password: tupassword