New to KubeVault? Please start here.
Vault Policy Management
You can easily manage the Vault policies in Kubernetes native way using the KubeVault operator. The operator also provides functionality to create auth method roles that bind policies.
You should be familiar with the following CRD:
To keep things isolated, we are going to use a separate namespace called demo
throughout this tutorial.
$ kubectl create ns demo
namespace/demo created
Before you begin
Install KubeVault operator in your cluster following the steps here.
Deploy the Vault server or configure an existing one.
Now, you have the AppBinding that holds the connection information of the Vault server.
$ kubectl get appbinding -n demo vault -o yaml
apiVersion: appcatalog.appscode.com/v1alpha1
kind: AppBinding
metadata:
labels:
app: vault
vault_cluster: vault
name: vault
namespace: demo
spec:
clientConfig:
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1RENDQWFDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFOTVFzd0NRWURWUVFERXdKallUQWUKRncweE9URXhNRGN3TXpVNE1qZGFGdzB5T1RFeE1EUXdNelU0TWpkYU1BMHhDekFKQmdOVkJBTVRBbU5oTUlJQgpJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdVFaUWZNU1pZek13djUzQjlKcmJlZkc0ClREYmtuaERGamZNMmJrdU90ak83cElFdG5ZSzRrVEdDRkRGd1RlTUNoczhiNFBQcGN5YzBZZ3BSdFFYMW9VTGUKdTFCOE0ralBtMXdhYys4S0JGR3BJdjVpS2dzMjI1MWczTThoY0lqK0ZFQ3hMVTN1bHZDazlUSXlJYzNLSGlDcwpFUmg2VXA2V1hxSVJYb3loNlViWmFrd2tsUTd5SGdUY0ZQMzNzNlBVVXVZaFNtUTJBNmxPU2NPSFRaVytHVDNrCjdPSzUxQ3g5RUptcjdZY1J2N3RiNXI0bGYycy81ZGg0SnYwS2UySkNCUExoK0dBeVh2cHlMd1dmc0w3cWduZ28KZSt0SXVadXFsSENwWDN1eERILzBncGRtK0NHTkN0aUlZUzdGOEFQODlsVVdrc2JOcVdKL1RnTlIrYmp6WHdJRApBUUFCb3lNd0lUQU9CZ05WSFE4QkFmOEVCQU1DQXFRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHCjl3MEJBUXNGQUFPQ0FRRUFGb0QvMGtZSHk5OW96MU9xSEVOOC9UVjVXM0dIN1lZSUdqVHZ5Mmc2NFpsajNDbjQKdHdlejd3VGhtMGllazFSR1VXM3luNzg2cEswZVFqYWM3OWZpUG5iTEx0WkRVTzFkSVM5Rnp1MmFiNmpITEpxYQpteUswcHJ1NGNDbmtZTmtOdWhKclQwSkl4Rjc5cXBEanlhSjVuOUxXbDFQZmZwZDZrUW5vdjZrNGtQL2JoTXhECk9oWVBvaVcydkZxSEI4NCtPVHhLbHRkWnNwTkR3bEh1NjZ6a1c0Z0xiRVBnTWUzN1p3NUFISWZld2hqWG93VHYKNVZpZnZYUjVreVNZTTdCMHlqcnpzUzNvK1ZGdS9wMzdmWThwaHMwZzdCWjd3TlhCcWJBT010K2s0Vy9CU0xUagpOelB2STB0SGFCTklnRFdHbm1waEIxN1BpQnBPc1Y2RHdiOVRYdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
service:
name: vault
port: 8200
scheme: HTTPS
parameters:
apiVersion: config.kubevault.com/v1alpha1
kind: VaultServerConfiguration
path: kubernetes
vaultRole: vault-policy-controller
kubernetes:
serviceAccountName: vault
tokenReviewerServiceAccountName: vault-k8s-token-reviewer
usePodServiceAccountForCSIDriver: true
VaultPolicy
Using VaultPolicy, you can create, update and delete policy in Vault. In this tutorial, we are going to create read-only-policy
in demo
namespace with the permissions to read and list Vault policies.
apiVersion: policy.kubevault.com/v1alpha1
kind: VaultPolicy
metadata:
name: read-only-policy
namespace: demo
spec:
vaultRef:
name: vault
policyDocument: |
path "sys/policy" {
capabilities = ["list"]
}
path "sys/policy/*" {
capabilities = ["read"]
}
Now, we are going to create VaultPolicy.
$ kubectl apply -f docs/examples/guides/policy-management/read-only-policy.yaml
vaultpolicy.policy.kubevault.com/read-only-policy created
Check whether the VaultPolicy is successful.
$ kubectl get vaultpolicy -n demo
NAME PHASE AGE
read-only-policy Success 15s
Check whether the policy is created in the Vault server. To resolve the naming conflict, name of policy in Vault will follow this format: k8s.{clusterName}.{metadata.namespace}.{metadata.name}
. In this case, it is k8s.-.demo.read-only-policy
.
Don’t have Vault CLI? Enable Vault CLI from here.
$ vault list sys/policy
Keys
----
k8s.-.demo.read-only-policy
... ...
$ vault read sys/policy/k8s.-.demo.read-only-policy
Key Value
--- -----
name k8s.-.demo.read-only-policy
rules path "sys/policy" {
capabilities = ["list"]
}
path "sys/policy/*" {
capabilities = ["read"]
}
If we delete VaultPolicy read-only-policy
, then the respective Vault policy will also be deleted from Vault.
$ kubectl delete vaultpolicies/read-only-policy -n demo
vaultpolicy.policy.kubevault.com "read-only-policy" deleted
Check whether the policy is deleted in Vault.
$ vault read sys/policy/k8s.-.demo.read-only-policy
No value found at sys/policy/k8s.-.demo.read-only-policy
$ vault list sys/policy
Keys
----
default
k8s.-.demo.vault-auth-method-controller
root
vault-policy-controller
VaultPolicyBinding
Using VaultPolicyBinding, you can create an auth method role that binds the Vault policies to users or service accounts.
Currently supported auth methods for creating role:
In this tutorial, we are going to create a policy-reader-role
VaultPolicyBinding in demo
namespace.
Create a service account in the demo namespace:
$ kubectl create serviceaccount -n demo demo-sa
serviceaccount/demo-sa created
Get JWT token of the demo-sa
service account:
$ kubectl get secret -n demo demo-sa-token-jz7x5 -o jsonpath="{.data.token}" | base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZW1vIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlbW8tc2EtdG9rZW4tano3eDUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVtby1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQxMGE4M2ViLWJhMDMtNDY1OS1iOTVjLTlmM2Y3ODdmZTM0OCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZW1vOmRlbW8tc2EifQ.w2H7cUXxAjeY4ZGJYVuTK8XrhpCXZeqUPQhFAyTndWhcevXOJFnK7jtyceYWaN0zy6TkBxHeAzVQdyLaFrNgecUKTzCZGaWHAoXlJOMY4Q49mHzEf3iGOBM7m1ckTTP9ABcOsVjD7OvlKslse_NnMDxVtuiughtMcrIhK5pbngQbJRpGkHaiOjgzIpHR3ybLmak7a24CXif0ZAqZd_y5l7bKi8eLr2Sidgq1R1sOMtOpnrj7qQCownw_KRrSPqhSCVSmaNDEYeqA9Jbw-JWVb3SW-FodjTPJsKj_qv791dZZE910CMBcsuJMPuAvNlX0cpOqO-7cdJzNG5y7IoYiSA
apiVersion: policy.kubevault.com/v1alpha1
kind: VaultPolicyBinding
metadata:
name: policy-reader-role
namespace: demo
spec:
vaultRef:
name: vault
policies:
- ref: read-only-policy
subjectRef:
kubernetes:
serviceAccountNames:
- "demo-sa"
serviceAccountNamespaces:
- "demo"
Here, a Kubernetes auth method role will be created that binds the read-only-policy
policy to the service account demo-sa
in demo
namespace.
Let’s create read-only-policy
by using VaultPolicy:
$ kubectl apply -f docs/examples/guides/policy-management/demo-policy.yaml
vaultpolicy.policy.kubevault.com/read-only-policy created
Check status:
$ kubectl get vaultpolicy -n demo
NAME PHASE AGE
read-only-policy Success 15s
Now, we are going to create VaultPolicyBinding policy-reader-role
.
$ kubectl apply -f docs/examples/guides/policy-management/policy-reader-role.yaml
vaultpolicybinding.policy.kubevault.com/policy-reader-role created
Check whether the policy-reader-role
is successful.
$ kubectl get vaultpolicybinding -n demo
NAME PHASE AGE
policy-reader-role Success 11s
Don’t have Vault CLI? Download and configure it as described here.
Check whether the Kubernetes auth role is created in Vault. To resolve the naming conflict,name of the role in Vault will follow this format: k8s.{clusterName}.{metadata.namespace}.{metadata.name}
. In this case, it is k8s.-.demo.policy-reader-role
.
$ vault list auth/kubernetes/role
Keys
----
k8s.-.demo.policy-reader-role
k8s.-.demo.vault-auth-method-controller
vault-policy-controller
$ vault read auth/kubernetes/role/k8s.-.demo.policy-reader-role
Key Value
--- -----
bound_service_account_names [demo-sa]
bound_service_account_namespaces [demo]
policies [k8s.-.demo.read-only-policy]
token_bound_cidrs []
token_explicit_max_ttl 0s
token_max_ttl 0s
token_no_default_policy false
token_num_uses 0
token_period 0s
token_policies [k8s.-.demo.read-only-policy]
token_ttl 0s
token_type default
Now, we are going to perform authentication to the Vault using demo-sa
’s JWT token. In response to successful authentication, the Vault will provide us a token that will have permissions of the read-only-policy
policy.
$ vault write auth/kubernetes/login \
role=k8s.-.demo.policy-reader-role \
jwt=eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZW1vIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlbW8tc2EtdG9rZW4tano3eDUiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVtby1zYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQxMGE4M2ViLWJhMDMtNDY1OS1iOTVjLTlmM2Y3ODdmZTM0OCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZW1vOmRlbW8tc2EifQ.w2H7cUXxAjeY4ZGJYVuTK8XrhpCXZeqUPQhFAyTndWhcevXOJFnK7jtyceYWaN0zy6TkBxHeAzVQdyLaFrNgecUKTzCZGaWHAoXlJOMY4Q49mHzEf3iGOBM7m1ckTTP9ABcOsVjD7OvlKslse_NnMDxVtuiughtMcrIhK5pbngQbJRpGkHaiOjgzIpHR3ybLmak7a24CXif0ZAqZd_y5l7bKi8eLr2Sidgq1R1sOMtOpnrj7qQCownw_KRrSPqhSCVSmaNDEYeqA9Jbw-JWVb3SW-FodjTPJsKj_qv791dZZE910CMBcsuJMPuAvNlX0cpOqO-7cdJzNG5y7IoYiSA
Key Value
--- -----
token s.0of6p1q8SrcN3OscDaBlmWuI
token_accessor lvddBe41uXe0DK5xGoaPKsN7
token_duration 768h
token_renewable true
token_policies ["default" "k8s.-.demo.read-only-policy"]
identity_policies []
policies ["default" "k8s.-.demo.read-only-policy"]
token_meta_role k8s.-.demo.policy-reader-role
token_meta_service_account_name demo-sa
token_meta_service_account_namespace demo
token_meta_service_account_secret_name demo-sa-token-jz7x5
token_meta_service_account_uid 410a83eb-ba03-4659-b95c-9f3f787fe348
Grab the token and export it as env to check its behavior:
$ export VAULT_TOKEN=s.0of6p1q8SrcN3OscDaBlmWuI
$ vault list sys/policy
Keys
----
default
k8s.-.demo.read-only-policy
k8s.-.demo.vault-auth-method-controller
root
vault-policy-controller
$ vault read sys/policy/k8s.-.demo.read-only-policy
Key Value
--- -----
name k8s.-.demo.read-only-policy
rules path "sys/policy" {
capabilities = ["list"]
}
path "sys/policy/*" {
capabilities = ["read"]
}
$ vault delete sys/policy/k8s.-.demo.read-only-policy
Error deleting sys/policy/k8s.-.demo.read-only-policy: Error making API request.
URL: DELETE https://127.0.0.1:8200/v1/sys/policy/k8s.-.demo.read-only-policy
Code: 403. Errors:
* 1 error occurred:
* permission denied
$ vault list auth/kubernetes/role
Error listing auth/kubernetes/role/: Error making API request.
URL: GET https://127.0.0.1:8200/v1/auth/kubernetes/role?list=true
Code: 403. Errors:
* 1 error occurred:
* permission denied
Here, we can see that we don’t have the permission to do anything but list and read the policies. So, the VaultPolicy read-only-policy
and the VaultPolicyBinding policy-reader-role
are working perfectly.
If we delete VaultPolicyBinding, then the respective role will be deleted from Vault.
$ kubectl delete vaultpolicybinding policy-reader-role -n demo
vaultpolicybinding.policy.kubevault.com "policy-reader-role" deleted
Check whether the role is deleted from Vault.
$ vault read auth/kubernetes/role/k8s.-.demo.policy-reader-role
No value found at auth/kubernetes/role/k8s.-.demo.policy-reader-role
$ vault list auth/kubernetes/role
Keys
----
k8s.-.demo.vault-auth-method-controller
vault-policy-controller