Spring config server with vault token doesnt respect the acl defined in vault - hashicorp-vault

I have spring config server and vault as backend. i created a token in vault with an acl policy . when i use the token in spring.cloud.config.token it doesnt respect the acl
My sping config client has this boot strap properties
spring:
application:
name: app1
cloud:
config:
uri: https://config-server-ur:port
token: token-associated-to-acl-policy
i created an acl policy by name "app1" which allows only the "app1" to be read by the token in vault.
path "secret/app1" {
capabilities = ["read", "list"]
}
./vault token create -display-name="app1" -policy="app1"
i used the token generated in my client and it doesnt work.
when i changed the acl policy to below, it works
path "secret/*" {
capabilities = ["read", "list"]
}
However, when i access the vault directly with X-Vault-token it works perfectly as expected

I found the solution, Set spring.cloud.config.server.vault.defaultKey to empty, like this in config-server bootstrap.yml
spring.profiles.active=git, vault
spring.cloud.config.server.git.uri=properties-git-repo-url
spring.cloud.config.server.git.username=user
spring.cloud.config.server.git.password=password
spring.cloud.config.server.git.searchPaths=/{application}/xyz
spring.cloud.config.server.git.force-pull=true
spring.cloud.config.server.git.timeout=10
spring.cloud.config.server.git.order=2
spring.cloud.config.server.vault.host=vault-hostname
spring.cloud.config.server.vault.port=8200
spring.cloud.config.server.vault.scheme=https
spring.cloud.config.server.vault.backend=secret
spring.cloud.config.server.vault.defaultKey=
spring.cloud.config.server.vault.profileSeparator=/
spring.cloud.config.server.vault.skipSslValidation=true
spring.cloud.config.server.vault.order=1
spring.cloud.config.server.vault.kvVersion=1
by default spring.cloud.config.server.vault.defaultKey= is set to "application".

Related

Want to integrate argo server with keycloak

I tried in incognito as wellbut same issue exists.
Currently I have added in server-deployment.yaml
args: - server - --auth-mode - sso
And in values.yaml
sso:
# #SSO configuration when SSO is specified as a server auth mode.
# #All the values are requied. SSO is activated by adding --auth-mode=sso
# #to the server command line.
#
# #The root URL of the OIDC identity provider.
issuer: http://<keycloak_ip>/auth/realms/demo
# #Name of a secret and a key in it to retrieve the app OIDC client ID from.
clientId:
name: argo
key: client-id
# #Name of a secret and a key in it to retrieve the app OIDC client secret from.
clientSecret:
name: "argo-server-sso"
key: client-secret
# # The OIDC redirect URL. Should be in the form /oauth2/callback.
redirectUrl: http:///argo/oauth2/callback
And in keycloak ui , I have created client and client credentials.
kubectl create secret generic "argo-server-sso" --from-literal=client-secret=9a9c60ba-647d-480c-b6fa-82c19caad26a
kubectl create secret generic "argo" --from-literal=client-id=argo
After hitting the argo server url,manually I need to click on login option but after that keycloak page appears and then again a popup will come "Failed to login:Unauthorized"
Server logs:
kubectl logs argo-server-5c7f8c5cbb-9fcqk
time="2021-01-20T12:06:26.876Z" level=info authModes="[sso]" baseHRef=/ managedNamespace= namespace=default secure=false
time="2021-01-20T12:06:26.877Z" level=warning msg="You are running in insecure mode. Learn how to enable transport layer security: https://argoproj.github.io/argo/tls/"
time="2021-01-20T12:06:26.877Z" level=info msg="config map" name=argo-workflow-controller-configmap
time="2021-01-20T12:06:28.318Z" level=info msg="SSO configuration" clientId="{{argo} client-id }" issuer="http://10.xx.xx.xx:xxxx/auth/realms/demo" redirectUrl="http://xx/argo/oauth2/callback"
time="2021-01-20T12:06:28.318Z" level=info msg="SSO enabled"
time="2021-01-20T12:06:28.322Z" level=info msg="Starting Argo Server" instanceID= version=v2.12.2
time="2021-01-20T12:06:28.322Z" level=info msg="Creating event controller" operationQueueSize=16 workerCount=4
time="2021-01-20T12:06:28.323Z" level=info msg="Argo Server started successfully on http://localhost:2746"
time="2021-01-20T12:07:21.990Z" level=info msg="finished unary call with code Unauthenticated" error="rpc error: code = Unauthenticated desc = token not valid for running mode" grpc.code=Unauthenticated grpc.method=GetVersion grpc.service=info.InfoService grpc.start_time="2021-01-20T12:07:21Z" grpc.time_ms=0.379 span.kind=server system=grpc
time="2021-01-20T12:07:22.009Z" level=info msg="finished unary call with code Unauthenticated" error="rpc error: code = Unauthenticated desc = token not valid for running mode" grpc.code=Unauthenticated grpc.method=ListWorkflowTemplates grpc.service=workflowtemplate.WorkflowTemplateService grpc.start_time="2021-01-20T12:07:22Z" grpc.time_ms=0.075 span.kind=server system=grpc
I integrated ArgoCD with Keycloak successfully.
You have 1 clear/visible issue: Yaml indentation is wrong
make sure you keep the right indentation as per default values in helm chart :
https://github.com/argoproj/argo-helm/blob/1aea2c41798972ff0077108f926bb9095f3f9deb/charts/argo/values.yaml#L255-L283
Accordingly, your values should be:
( assuming your argo is serving with hostname workflows.company.com )
server:
extraArgs:
- --auth-mode=sso
sso:
issuer: http://<keycloak_ip>/auth/realms/demo
clientId:
name: argo
key: client-id
clientSecret:
name: "argo-server-sso"
key: client-secret
redirectUrl: https://workflows.company.com/argo/oauth2/callback
From keycloak side now, & under your client, make sure you fill-in the Valid Redirect URL as per your ingress hostname :

vault templating paths in policies results in permission denied

I'm trying to create a policy that allows for users to access a portion of the secret hierarchy based on their usernames. Rather than having a different policy for each user, I want to have one templated policy. I think this should work, but I keep getting permission denied errors. If I remove the templating and just hard-code the username in the policy path, secret retrieval works just fine, so it doesn't seem like it's any other part of the policy definition.
This is all with Vault 1.3.1, against a dev server, but the problem first came up on a non-dev server, with GCP/GCE authentication and database secrets, so it doesn't seem to be specific to any of those things, either.
Enable username/password authentication, and create a user that points to a new policy (to be defined later).
$ vault auth enable userpass
Success! Enabled userpass auth method at: userpass/
$ vault write auth/userpass/users/duvall policies=default,p2 password=duvall
Success! Data written to: auth/userpass/users/duvall
Login as this user and take a look at the token metadata.
$ vault login -method userpass username=duvall password=duvall
$ vault token lookup
Key Value
--- -----
accessor 9ga3alRqZ6E3aSCEBNFWJY1X
creation_time 1581468214
creation_ttl 768h
display_name userpass-duvall
entity_id 7513dc68-785b-d151-0efb-71315fc026dc
expire_time 2020-03-15T00:43:34.707416501Z
explicit_max_ttl 0s
id s.YZRQ3uclh2rg2H7gh3qH84P3
issue_time 2020-02-12T00:43:34.707423899Z
meta map[username:duvall]
num_uses 0
orphan true
path auth/userpass/login/duvall
policies [default p2]
renewable true
ttl 767h50m35s
type service
Create the aforementioned policy with a path templated based on the metadata key username.
$ export VAULT_TOKEN=root
$ echo 'path "secret/data/role-secrets/{{identity.entity.metadata.username}}/*" {capabilities = ["read"]}' | vault policy write p2 -
Success! Uploaded policy: p2
Create a secret that matches the path in the policy.
$ vault kv put secret/role-secrets/duvall/s1 foo=bar
Key Value
--- -----
created_time 2020-02-12T00:44:36.509412834Z
deletion_time n/a
destroyed false
version 1
As the user, reading the secret results in failure.
$ export VAULT_TOKEN=s.YZRQ3uclh2rg2H7gh3qH84P3
$ vault kv get secret/role-secrets/duvall/s1
Error making API request.
URL: GET http://127.0.0.1:8200/v1/sys/internal/ui/mounts/secret/role-secrets/duvall/s1
Code: 403. Errors:
* preflight capability check returned 403, please ensure client's policies grant access to path "secret/role-secrets/duvall/s1/"
Rewrite the policy to remove the templating.
$ export VAULT_TOKEN=root
$ echo 'path "secret/data/role-secrets/duvall/*" {capabilities = ["read"]}' | vault policy write p2 -
Success! Uploaded policy: p2
This time, reading the secret succeeds.
$ export VAULT_TOKEN=s.YZRQ3uclh2rg2H7gh3qH84P3
$ vault kv get secret/role-secrets/duvall/s1
====== Metadata ======
Key Value
--- -----
created_time 2020-02-12T00:44:36.509412834Z
deletion_time n/a
destroyed false
version 1
=== Data ===
Key Value
--- -----
foo bar
I'm not sure how relevant this is, but ... adding a metadata list capability to the policy changes the read error from a "preflight capability check" to a more normal "permission denied".
$ echo 'path "secret/metadata/*" {capabilities = ["list"]}\npath "secret/data/role-secrets/{{identity.entity.metadata.username}}/*" {capabilities = ["read"]}' | VAULT_TOKEN=root vault policy write p2 -
Success! Uploaded policy: p2
$ vault kv get secret/role-secrets/duvall/s1
Error reading secret/data/role-secrets/duvall/s1: Error making API request.
URL: GET http://127.0.0.1:8200/v1/secret/data/role-secrets/duvall/s1
Code: 403. Errors:
* 1 error occurred:
* permission denied
You are missing a point that if you want to give access of secrets/database/rdb/ then you have to give read and list capabilities for path secrets, databse, rdb.
Now if you have multiple secrets stored in secrets/ path that you don't want to share then you have to give deny for that paths.

Permission denied on `vault kv put ...`

I'm trying to perform a simple use case of creating a user and writing a kv secret using Vault v1.1.2:
First I do some initial setup after starting the server in production mode:
vault operator unseal <unseal key>
vault operator unseal <unseal key>
vault operator unseal <unseal key>
export VAULT_ROOT_TOKEN=<token>
Next, I do some setup, including creating a policy:
vault -version
vault login $VAULT_ROOT_TOKEN
vault auth enable userpass
vault secrets enable -version=2 -path=secret kv
vault policy write my-policy -<<EOF
path "secret/*" {
capabilities = ["create", "update"]
}
path "secret/foo" {
capabilities = ["read"]
}
path "secret/data/*" {
capabilities = ["create", "update"]
}
path "secret/data/foo" {
capabilities = ["read"]
}
EOF
vault token create -policy=my-policy
I then create a user:
vault write auth/userpass/users/chris \
password=password \
policies=my-policy,default
vault login -method=userpass username=chris password=password
Which returns:
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.
Key Value
--- -----
token ...
token_accessor ...
token_duration 10h
token_renewable true
token_policies ["default" "my-policy"]
identity_policies []
policies ["default" "my-policy"]
token_meta_username chris
Next, I try writing a kv secret:
vault kv put secret/foo my-value=s3cr3t
However, the error I get is:
Error writing data to secret/data/foo: Error making API request.
URL: PUT http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:
* 1 error occurred:
* permission denied
What am I missing?
Ok, it was my policy. I changed path "secret/data/foo" to the following and it works ok.
path "secret/data/foo" {
capabilities = ["create", "read", "update", "delete"]
}

How can I access a Vault secret using a token created from a policy?

I'm running Hashicorp Vault v1.1.0 locally in a docker container in developer mode. I exec into the container to use the cli, and I cannot complete a basic proof of concept with a policy and token which allow me to access only one secret.
Below is a transcript of the actions I've taken using v2 of the secrets engine. What am I doing wrong here?
/ # VAULT_TOKEN=myroot vault kv enable-versioning secret/
Success! Tuned the secrets engine at: secret/
/ # VAULT_TOKEN=myroot vault kv put secret/message value=mypassword
Key Value
--- -----
created_time 2019-04-11T20:23:25.0149145Z
deletion_time n/a
destroyed false
version 5
/ # cat p.hcl
path "secret/message" {
capabilities = ["read"]
}
/ # VAULT_TOKEN=myroot vault policy write message-readonly p.hcl
Success! Uploaded policy: message-readonly
/ # VAULT_TOKEN=myroot vault token create -policy="message-readonly"
Key Value
--- -----
token s.hZNCq7Q5plwA4XjcGAcsd5tg
token_accessor vpcxkGMbDBswfJPTGzzfY4he
token_duration 768h
token_renewable true
token_policies ["default" "message-readonly"]
identity_policies []
policies ["default" "message-readonly"]
/ # VAULT_TOKEN=s.hZNCq7Q5plwA4XjcGAcsd5tg vault kv get secret/message
Error reading secret/data/message: Error making API request.
URL: GET http://127.0.0.1:1234/v1/secret/data/message
Code: 403. Errors:
* 1 error occurred:
* permission denied
/ #
When you craft a policy for version 2 of the KV backend you need to specify the API paths, not the logical paths that "vault kv" uses. Your policy should look like this:
path "secret/data/message" {
capabilities = ["read"]
}
There's a bunch of other quirks you need to be aware of when crafting KV2 policies. See https://www.vaultproject.io/docs/secrets/kv/kv-v2.html for more information.

Spring Cloud Vault With k2 v2 - How to Avoid 403 at Startup?

Problem
Does anyone know how to configure bootstrap.yml to tell Spring Cloud Vault to go to the correct path for k2 v2 and not try other paths first?
Details
I can successfully connect to my Vault, running k2 v2, but Spring Cloud will always try to connect to paths in the vault that don't exist, throwing a 403 on startup.
Status 403 Forbidden [secret/application]: permission denied; nested exception is org.springframework.web.client.HttpClientErrorException$Forbidden: 403 Forbidden
The above path, secret/application, doesn't exist because k2 v2 puts data in the path. For example: secret/data/application.
This isn't a show-stopper because Spring Cloud Vault does check other paths, including the correct one that has the data item in the path, but the fact a meaningless 403 is thrown during startup is like a splinter in my mind.
Ultimately, it does try the correct k2 v2 path
2019-03-18 12:22:46.611 INFO 77685 --- [ restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource {name='vault', propertySources=[LeaseAwareVaultPropertySource {name='secret/data/my-app'}
My configuration
spring.cloud.vault:
kv:
enabled: true
backend: secret
profile-separator: '/'
default-context: my-app
application-name: my-app
host: localhost
port: 8200
scheme: http
authentication: TOKEN
token: my-crazy-long-token-string
Thanks for your help!
Add the following lines in your bootstrap.yml, this disables the generic backend
spring.cloud.vault:
generic:
enabled: false
for more information https://cloud.spring.io/spring-cloud-vault/reference/html/#vault.config.backends.generic
In addition to the accepted answer it's important to turn off (or just remove) fail-fast option:
spring.cloud.vault:
fail-fast: false
spring.cloud.vault.generic.enabled is deprecated in spring-cloud 3.0.0, but the 403 error is still there. To disable the warning (by telling spring to use the exact context), this is what I used:
spring:
config:
import: vault://
application:
name: my-application
cloud:
vault:
host: localhost
scheme: http
authentication: TOKEN
token: my-crazy-long-token-string
kv:
default-context: my-application
Other configs were set to default (such as port = 8200, backend = secret, etc.)