Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom metadata to Vault from ServiceAccount annotations #85

Closed
Tracked by #226
mrknmc opened this issue Mar 26, 2020 · 14 comments · Fixed by #226
Closed
Tracked by #226

Add custom metadata to Vault from ServiceAccount annotations #85

mrknmc opened this issue Mar 26, 2020 · 14 comments · Fixed by #226

Comments

@mrknmc
Copy link

mrknmc commented Mar 26, 2020

We would like to create policy rules that use custom entity/alias metadata and have this metadata be supplied from Kubernetes annotations on the ServiceAccount.

The way I envision this working is, if you have a ServiceAccount with annotations such as:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-account
  namespace: default
  annotations:
    # could have different form
    vault.hashicorp.com/auth-metadata/metadata-key: example-value

Then the auth plugin adds following metadata to the entity/alias:

metadata-key: example-value

We could then create a templated policy document (in Terraform) such as:

data "vault_policy_document" "tokens_write_document" {
  path         = "root/{{identity.entity.aliases.<mount-accessor>.metadata.<metadata-key>}}/*"
  capabilities = ["write", "list", "read"]
}

And with this policy in place, the ServiceAccount would have access to any secret under:

/root/example-value/*

Currently, we would have to manually edit entity/alias metadata to achieve this at which point we might as well create per-service-account policies which we would really like to avoid doing.

What are your thoughts on this? I would gladly submit a PR.

I'm thinking what would be necessary is to make an extra request to get the annotations for a given service account, parse them, and pass them to Vault in this code block: https://github.com/hashicorp/vault-plugin-auth-kubernetes/blob/master/path_login.go#L112-L133. Extra RBAC permissions would be required for the JWT reviewer service account too.

@sfynx
Copy link

sfynx commented Jul 27, 2020

Yeah, I would very much appreciate to have this feature, it sounds like a logical thing to have actually seeing how you can annotate everything in Kubernetes anyway. This would enable us to organize our secrets and their access control based on an existing k8s structure.

In my case I would like to define a secret as root/<cluster name>/<application name>/<application environment>/somesecret, so that these paths are human-readable for people to access. Right now I would have to abuse the existing namespace or service account name / token fields for that or do it manually like you said.

@andrea-armstrong
Copy link

I also have a use case for this feature as we're using the Kubernetes auth method and would like to take advantage of templated policies being defined ahead of time using a structured path that would require more metadata than just service_account_name and service_account_namespace.

@sfynx
Copy link

sfynx commented Apr 2, 2021

Would still want this. Right now I'm creating a role and policy for each end user that needs to access part of the path, but it is a pain to manage.

@mooneye14
Copy link

I also have a need for this. 1700 policies and counting

@amjanoni
Copy link

+1 for this feature.
I'm using PKI with Allowed Domains Template option with AppRoles but with Kubernetes, I can't inject metadata

@NorthFuture
Copy link

+1 for this feature. it's a pain to edit manually entities

@ebdekock
Copy link

+1 for this, would give us amazing flexibility with templated policies

@danielrubin1989
Copy link

+1 Same situation in my environment, this will save a lot of manual work and make ACL Template super strong

dovys pushed a commit to monzo/vault-plugin-auth-kubernetes that referenced this issue Feb 1, 2022
Addresses hashicorp#85
We are introducing another roundtrip to the Kubernetes API to lookup the service account itself and read annotations prefixed with 'vault.hashicorp.com/auth-metadata/'.
This will enable us to template Vault policies based on arbitrary service attributes, like fully qualified service name.
dovys pushed a commit to monzo/vault-plugin-auth-kubernetes that referenced this issue Feb 1, 2022
Addresses hashicorp#85

We took Mark's proposed design and added support for defining annotations on service accounts that can later on be used in policy templating.

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-account
  namespace: default
  annotations:
    vault.hashicorp.com/auth-metadata/service-role: example-value
```

Should allow us to use in policies as so
```
{{identity.entity.aliases.${vault_auth_backend.kubernetes.accessor}.metadata.service_role}}
```

The change is behind a config flag called `enable_custom_metadata_from_annotations` so it should not affect any of the existing integrations.
In order to enable the flag users will have to update the clusterrole and allow Vault to read service accounts. If this change is accepted we'll open PRs to update various docs, terraform providers, etc.
This will al so introduce another roundtrip to the Kubernetes API, however we are using a pooled tcp client so hopefully not too many new open connections.
@chongyangshi
Copy link

As linked above, we at Monzo have started a PR implementing the feature discussed here.

Note that Kubernetes does not allow more than one level of / in annotation names, therefore the proposed vault.hashicorp.com/auth-metadata/metadata-key was reformatted as auth-metadata.vault.hashicorp.com/metadata-key in our implementation.

@gkid
Copy link

gkid commented Feb 25, 2022

Just cam across this thread today. I would also love to have this feature of course. But in the meantime - for anyone that's interested - I can show you how I manage hundreds of services with just 1 policy. The policy is does not need to be updated for any new service. This can be achieved by using ACL Policy Path Templating. So all of my hundreds of services are managed with just this policy:
path "secret/data/services/{{identity.entity.aliases.auth_kubernetes_d325ac65.metadata.service_account_namespace}}/{{identity.entity.aliases.auth_kubernetes_d325ac65.metadata.service_account_name}}/*" { capabilities = ["read", "list"] }
If anyone is interested, I can share more details. We have also created a small job which automatically updates the kubernetes token accessor, so that this policy is valid even if the k8s engine or the vault cluster is replaced.

@chongyangshi
Copy link

chongyangshi commented Feb 25, 2022

Thanks for sharing @gkid and I'm glad this workaround worked for you in this use-case. Unfortunately for PKI signing paths rather than secret storage paths, just the service_account_namespace and service_account_name information are not always sufficient to provide all the information required in a service-specific certificate in a service mesh, for example.

@NorthFuture
Copy link

news on this?

chongyangshi pushed a commit to monzo/vault-plugin-auth-kubernetes that referenced this issue Apr 26, 2022
Addresses hashicorp#85

We took Mark's proposed design and added support for defining annotations on service accounts that can later on be used in policy templating.

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-account
  namespace: default
  annotations:
    vault.hashicorp.com/auth-metadata/service-role: example-value
```

Should allow us to use in policies as so
```
{{identity.entity.aliases.${vault_auth_backend.kubernetes.accessor}.metadata.service_role}}
```

The change is behind a config flag called `enable_custom_metadata_from_annotations` so it should not affect any of the existing integrations.
In order to enable the flag users will have to update the clusterrole and allow Vault to read service accounts. If this change is accepted we'll open PRs to update various docs, terraform providers, etc.
This will al so introduce another roundtrip to the Kubernetes API, however we are using a pooled tcp client so hopefully not too many new open connections.
chongyangshi pushed a commit to monzo/vault-plugin-auth-kubernetes that referenced this issue Apr 26, 2022
Addresses hashicorp#85

We took Mark's proposed design and added support for defining annotations on service accounts that can later on be used in policy templating.

```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-account
  namespace: default
  annotations:
    vault.hashicorp.com/auth-metadata/service-role: example-value
```

Should allow us to use in policies as so
```
{{identity.entity.aliases.${vault_auth_backend.kubernetes.accessor}.metadata.service_role}}
```

The change is behind a config flag called `enable_custom_metadata_from_annotations` so it should not affect any of the existing integrations.
In order to enable the flag users will have to update the clusterrole and allow Vault to read service accounts. If this change is accepted we'll open PRs to update various docs, terraform providers, etc.
This will al so introduce another roundtrip to the Kubernetes API, however we are using a pooled tcp client so hopefully not too many new open connections.
@CodyKurtz
Copy link

I’d also like to comment here as an up vote on this feature. Looks like the work has been completed in a forked repo. Same issue as everyone else. We wish to use custom metadata to enhance templated policies. But we need to create the entity alias ahead of time for that to work. Sometimes the service account doesn’t exist yet, which means we have to use name instead of UID for the alias name, which could create a name conflict.

@sass1997
Copy link

sass1997 commented Dec 1, 2023

Just cam across this thread today. I would also love to have this feature of course. But in the meantime - for anyone that's interested - I can show you how I manage hundreds of services with just 1 policy. The policy is does not need to be updated for any new service. This can be achieved by using ACL Policy Path Templating. So all of my hundreds of services are managed with just this policy: path "secret/data/services/{{identity.entity.aliases.auth_kubernetes_d325ac65.metadata.service_account_namespace}}/{{identity.entity.aliases.auth_kubernetes_d325ac65.metadata.service_account_name}}/*" { capabilities = ["read", "list"] } If anyone is interested, I can share more details. We have also created a small job which automatically updates the kubernetes token accessor, so that this policy is valid even if the k8s engine or the vault cluster is replaced.

Hi @gkid, thank you for sharing this. Did you ever had the requirement to extended this as well with the dimension of auth method name. So you have n-kubernetes-clusters each have it's own authenication method. Your secrets path is constructed lik this: secrets/data//services// ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.