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
Secret Management in Helm #2196
Comments
I'm in favor of this. What is the proposed method for storing the plaintext secret in the code repository? |
The method proposed above does not seem like it would work with I would be more interested in seeing an actual secrets storage mechanism (Vault-like) that we could use to inject secrets into the template at template resolution time. I like the idea of having That said, I have no idea how we would proceed with supporting a secret storage backend. While developing the backend seems out of scope for Helm, bridging Tiller and the secret storage would be something I would absolutely salivate over. |
I think it could be reasonable to use Kubernetes secrets to do what you're suggesting @technosophos instead of involving another service like Vault. Brainstorming a little: |
You're right about |
As for supporting a secret backend, the hardest thing would probably be ensuring tiller remains authenticated. For vault the actual operations would simply be API calls to set/retrieve secrets. I'd imagine a Vault implementation would be as follows:
Example: End userAs an end user, I would run helm install --name myrelease server/mychart
Please set values for secrets requested by mychart
# The password for your admin user
adminPassword:
# Your github API key
apiKey: These secrets are defined in a Rotating secrets could be achieved by adding a I like the approach of prompting people to enter their secrets because it will keep them from committing them to source along with the rest of their config values while maintaining the simplicity of the TillerI have a release called curl -X POST -H "X-Vault-Token:$VAULT_TOKEN" -d '{"adminPassword":"passw0rd!", "apiKey":"asdf1234asdf1234"}' https://vault.vaultnamespace:8200/v1/secret/helm-myrelease Then, at the point where tiller is finalizing the set of values to be used with the release, it would make an API call to vault again curl -X GET -H "X-Vault-Token:$VAULT_TOKEN" https://vault.vaultnamespace:8200/v1/secret/helm-myrelease which would return {
"auth": null,
"warnings": null,
"wrap_info": null,
"data": {
"adminPassword": "passw0rd!",
"apiKey": "asdf1234asdf1234"
},
"lease_duration": 2764800,
"renewable": false,
"lease_id": "",
"request_id": "5e246671-ec05-6fc8-9f93-4fe4512f34ab"
} These values would get merged in with the rest of the values and dropped into templates as normal. My thought would be to use a |
So if we combined @ejether 's suggestion with @johnw188 's well-thought-out ideas about Vault. It might be possible for us to support secret management with a default path of storing in Kubernetes secrets, and a more robust path that would support Vault. That would make it simple for people using things like Minikube for dev, but also provide enterprises with a solution that would meet regulatory compliance. I agree with @johnw188 's bullet list above. And even if we add secret rotation later, the proposal above makes sense to me as to how we would present that to the user. I think that the experimental Rudder work that @nebril is working paves the way for making a plugin-style backend work. So this might be the ideal candidate for a second kind of Rudder backend. (See #2079) |
@technosophos Reading through the release module proposal you wrote up here, it seems that tiller would still be responsible for generating a complete set of template outputs before passing them on to the release module for installation. How do you see this integrating with that architecture, as the secret values will need to be pulled in during the template evaluation step. I like the idea of having multiple secret backends, starting with kube secrets. We could define a simple interface along the lines of type secretBackend interface {
getSecrets() map[string]string
getSecret(key string) string
setSecrets(map[string]string)
setSecret(key string, value string)
} do an initial implementation backed by kubernetes secrets, then implement a vault backend. |
I would like to expand this proposal by adding for supporting for secret versioning. (This is copied from a separate issue for organization) We want to move storage of Helm manifests to Secrets from ConfigMaps. This is favorable because of the future updates coming to k8s secrets storage in the near future (1.7). K8s will support secrets encryption at rest, making the usage of Tiller much more secure for storing versions of secrets than the current situation. In addition, there is talk within the Kubernetes community to expand support for multiple backends to handle secrets, specifically Vault. By staying with k8s secrets, we will be able to take advantage of these features for free. Inside of the Helm chart templates, we will specify a secret object in which we will populate the values of the secrets by reading in a file called secrets.yaml which will resemble the format and function of values.yaml. TillerTiller will have a new tiller --storage=secret This will configure Tiller to store and look for deployment versions in secrets instead of ConfigMaps. This will obviously ruin old deployed versions if one wanted to switch from configmaps to secrets storage, but potentially a one-time script could be made to port those over pretty easily. Use CasesApplication InstallWhen a user installs a chart, have Helm look for a secrets.yaml file and populate any secret values that it defines in the templates where it is referenced. This will behave identically to the use of values.yaml, the caveat being that secrets.yaml should never be committed to your repository. A new argument will be added to helm install and will act similarly to --values, namely its ability to specify a file from which to get secrets from: helm install stable/mysql --secrets=my-secrets.yaml If no file is specified, then Helm will default to using secrets.yaml. The manifest of the chart’s version will then be stored as a secret instead of a ConfigMap. This way we will be able to support secret versioning that corresponds to deployment versions. We'll also add support for a new argument Upgrading applicationWith the secrets.yaml file in your chart directory, updating secrets should be just as easy as updating values. Thus, another argument from upgrade would need to be added: helm upgrade opining-rooster --secrets=secrets.yaml Rolling backHelm rollback should take care of this as old charts will point at old secrets |
Tagged this as a feature since discussion seemed to be concluded and @RemingtonReackhof has some code in the works |
@RemingtonReackhof's workflow looks great to me, and that pattern may work well with security tools like Summon. That said, are Secrets or ConfigMaps the best place for storing potentially sensitive charts? Ideally this solution would support both string (API keys, etc) and file (SSL certs, etc) secrets. Given that the current implementation of K8S Secrets has several outstanding issues - unencrypted (base64 doesn't count), unauthenticated, unaudited, not well scoped, etc - seems like a Memory volume is a better fit. That way secrets can be shared within a Pod without clear boundaries (Secrets and ConfigMaps are pretty much global right?). In the Pod, a pluggable sidecar can handle authn/authz, fetching secrets, and passing them to the app container. The same or another sidecar could provide rotation-handling logic. |
@dustinmm80 I think we all agree that secrets aren't perfect, however, encrypted secrets have been enabled as alpha in k8s 1.7 and so it is a good starting point that can be expanded later into using something like Vault. |
That sounds great, thanks a bunch @thomastaylor312! Appreciate all the hard work put into this project :) |
@RemingtonReackhof @thomastaylor312 any news on this? |
Waiting on a second review (which I can tackle today). |
Are you guys aware of this implementation? https://github.com/futuresimple/helm-secrets It's the nicest one I've seen so-far and feels a lot like other systems like Ansible, but would be great if instead of using a wrapper around the helm binary we can just integrate something similar with helm. |
I am going to pull this out of 2.7 since the PR only partially implements this |
/remove-lifecycle rotten |
+1 |
2 similar comments
+1 |
+1 |
Hello! Here is a short write-up about the problem: https://dev.to/evilmartians/painless-migration-of-existing-helms-tiller-setup-to-kubernetes-secrets-d1p Hope it will help somebody! |
@dragonsmith not to dissuade you, but Tiller has had the option to store release information as secrets via the However, I could definitely see this being useful as a migration tool! |
To answer your questions, @itaysk,
Yes, storing release information as Secrets has been available since 2.7 via #2721. The comment you mention about pulling it off 2.7 was just the fact that we were close to considering pulling it off the milestone due to inactivity, but we managed to squeeze it in on the day before the release was cut. As mentioned in my comment above, documentation on how to enable the backend is available in the docs.
No. It's considered "partially implemented" because the OP indicated interest in also adding support for splitting values.yaml into two objects: values.yaml and secrets.yaml, which was not a part of #2721. More information can be found in the original comment.
We don't plan on supporting additional backends for Helm 2. I'm not sure I understand the second part of your question though, would you mind elaborating more? Also worthy to note that in Helm 3, state management of releases will be tracked through a Release object and a Secret. See https://github.com/helm/community/blob/master/helm-v3/003-state.md for more information. |
Yeah, I'm exploiting exactly that, and I've mentioned it in the write-up (sorry, it seems dev.to doesn't provide direct links to headers.) Still, it is the problem to migrate from ConfigMaps to Secrets for Tiller if you have a lot deployed via Helm. This small app is about helping you do that using default options, I'm not claiming more. It can convert ConfigMaps to Secrets, configure Tiller to use |
We use sops to keep only encrypted file in storage, and decrypt on the fly, not perfect but works:
|
@schollii are you also using |
@ejether Thanks for reminder, it's on list of things to do soon! |
Have we seen this project? https://github.com/futuresimple/helm-secrets Seems like it offers many of the desired features but does not support additional external sources. If you stacked this with the secret storage setting seems like you would have security all the way through so long as you keep your GPG key safe. |
@aba182 helm-secrets seems a lot like the solution @schollii came up with; encrypt value files client-side and decrypt on-the-fly them prior to calling Both solutions miss an important use case though: helm-secrets and sops both decrypt the values prior to being submitted to Tiller, which means that the secret is stored in plain text in etcd. If I'm understanding the use case, most users here seem to be asking for an end-to-end encryption solution from source code all the way to the runtime. Has anyone tested whether or not pairing sops with encryption of secret data at rest works? That should cover the last security concern most people seem to have here, which is the issue of values being stored unencrypted in etcd. |
@bacongobbler if the values are stored encrypted in etcd, then the container needs to decrypt them somehow, say with sops and an AWS profile mounted from a config map. But if that info is present in the container, then anyone able to enter the container (which presumably would be anyone able to snoop into etcd), can also decrypt them. Is there a way to prevent that? |
|
Imho even encryption in etcd will not help as long you can do: "helm get values supersecretapp" |
This is a problem of Tiller architecture, not secrets management. If you have Tiller access, you can do anything: even if these secrets are encrypted they are still accessible by tiller, cause it must be able to deploy apps that use the secrets. |
If you're using the secret storage backend and asking Kubernetes to encrypt the release objects Helm creates, those values will be encrypted in etcd. The last case to cover in that case would be how Helm could decrypt those values. This should be much simpler to handle in Helm 3 given the client-only architecture, so I'm curious to hear if anyone's experimented with that feature, and how we can accomodate this so Helm can encrypt/decrypt those values on the fly, keeping that data encrypted at rest. |
This ticket has been open for over 3 years, yet there hasn't been any movement on this proposal since it first came up. I'm going to close this as it looks like there aren't any community members interested enough to implement the proposal. If someone is interested in moving the proposal further, please feel free to chime in here and we can re-open this ticket. Thanks! |
Consider configuration of a Jenkins instance. In our
values.yaml
we might encounterwith a secret being defined as
The problem is that anyone with access to tiller can run a
helm get values
command and be sent back the password in plain text.Requirements
helm inspect
, a listing of secrets that can be set for the chart--set
directive or by passing a yaml file, as they do withvalues.yaml
currently.helm upgrade
commandProposed implementation
values.yaml
ofSecrets
(helm:Secrets
?). This would inform Tiller that the values under that key are to be treated as secret values. The downside to this approach is it feels a bit magick-y.values.yaml
approach intovalues.yaml
andsecrets.yaml
. This approach is more clear, but the existing workflow ofhelm inspect stable/jenkins > myvalues.yaml
->helm install -f myvalues.yaml stable/jenkins
is quite elegant and I can't see a good way to maintain that simplicity with two separate config files.{{ if .Values.Master.AdminPassword }}
to{{ if .Secrets.Master.AdminPassword }}
--set-secret
command to helm to allow for command line setting/upgrading of secretsThe text was updated successfully, but these errors were encountered: