-
Notifications
You must be signed in to change notification settings - Fork 115
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
Secrets in plain text in Kubernetes resource outputs.__inputs
#734
Labels
impact/security
last-applied-configuration
Issues related to the last-applied-configuration annotation
p1
A bug severe enough to be the next item assigned to an engineer
Milestone
Comments
We're also leaking the secret through |
Matt is taking the lead on this for now since he's more familiar with the changes required to fix. |
ellismg
added a commit
that referenced
this issue
Aug 26, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 26, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 26, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 27, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 27, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). In addition, this adds code to mark `data` as secret on `k8s.core.v1.Secret` if `stringData` is a secret (the API Server base64 encodes the `stringData` bag into `data` and so we should logically flow the secretness). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 27, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). In addition, this adds code to mark `data` as secret on `k8s.core.v1.Secret` if `stringData` is a secret (the API Server base64 encodes the `stringData` bag into `data` and so we should logically flow the secretness). Fixes #734
ellismg
added a commit
that referenced
this issue
Aug 28, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a coresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object iself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevent members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). In addition, this adds code to mark `data` as secret on `k8s.core.v1.Secret` if `stringData` is a secret (the API Server base64 encodes the `stringData` bag into `data` and so we should logically flow the secretness). Fixes #734
lblackstone
pushed a commit
that referenced
this issue
Aug 28, 2019
In order to support tracking secretness that flows from inputs to outputs when using providers that do not understand secrets directly, the engine takes any input that is secret and if there is a corresponding output with the same name, marks it as a secret. This works in common cases, but does not work for Kubernetes for two key reasons: 1. The provider retains a copy of the inputs for a resource on an object called `__inputs` inside the state object. It uses this during Diff for reasons that are un-interesting to this PR. 2. The provider JSON stringifies the inputs and stores them as an annotation on the object itself, as `kubectl` would. These two decisions mean that if a secret value is used as an input to a k8s resource, we will persist the plaintext value in the state file, since the engine has no idea to look at `__inputs` or `lastAppliedConfig`. This change updates the provider to be able to handle secrets. The engine will now pass any secret inputs as strongly typed secrets. The provider will use this information to ensure that the relevant members in the `__inputs` bag are marked as secrets as well as ensuring that if there are any inputs that are secret, all of `lastAppliedConfig` (which is a stringified JSON object) is marked as a secret as well. An integration test confirms this behavior by stringifying the state and ensuring that our secret values do not end up in it (which will catch cases where we may copy this data to other places as well). In addition, this adds code to mark `data` as secret on `k8s.core.v1.Secret` if `stringData` is a secret (the API Server base64 encodes the `stringData` bag into `data` and so we should logically flow the secretness). Fixes #734
infin8x
added
the
p1
A bug severe enough to be the next item assigned to an engineer
label
Jul 10, 2021
lblackstone
added
the
last-applied-configuration
Issues related to the last-applied-configuration annotation
label
Jul 18, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
impact/security
last-applied-configuration
Issues related to the last-applied-configuration annotation
p1
A bug severe enough to be the next item assigned to an engineer
If I deploy a resource with secrets, they are encypted in the inputs and in the main part of outputs, but are in plain text in
outputs.__inputs
for Kubernetes resources.The RandomPassword is correct:
The Kubernetes ConfigMap is correct on inputs, but leaks plaintext on outputs:
The text was updated successfully, but these errors were encountered: