The kubernetes dashboard allows one to see secrets in plain text (not base64 encoded) and make an easy change to any key-value pair within a Secret. I cannot find a way to easily make a similar change on the command line.
My best attempt has been to write a script which uses kubectl get secret to pull all of the data in Json format, grab each key-value pair, base64 decode the values, update the one I actually want, then feed them all back in to kubectl apply. After running into multiple issues I figured there is probably a kubectl option that I'm overlooking which will allow me to update just one key-value pair in a given Secret.
How can I do this?
Usually you would have your secrets manifest stashed somewhere where it is secure.
I dont usually change the secrets using the dashboard, but instead do a kubectl apply -f mysecret.yaml. the mysecret.yaml file keeps the latest and greatest values. No in-place editing. This way you get consistency across deployments.
Related
I'm a newbie on K8s, and now i have some questions about his best practices.
I'm creating a Secret to save my sensitive data and i came across kubernetes docs saying something about data:, where the content must be saved on base64 string and stringData: where is not needed, what is the best practice in this case, save on data or stringData?
If i choose data:, will be a moment when kubernetes will translate it back to it's original or i have to do it mannually?
In general the "stringData" is more comfortable so in the "stringData" property you can put your data in plain text and kubernetes then writes it base64 encoded for you into the "data" property of the secret. If you directly want to set the "data" property you need to manually base64 encode it
I have an API Token that I am storing in an Azure Key Vault. I want to provide access to this secret so it can be used from various pipelines. But I don't necessarily want anyone editing/executing those pipelines to be able to retain the Token. If a pipeline just echoes the secret value then won't the build agent logs simply display it, making the whole key vault process a useless step?
If that is the case, is there a way to safeguard a value if I don't necessarily want to trust everyone that can create pipelines?
It depends on how the secret is being retrieved and turned into a variable. In general, secrets retrieved via the standard Azure Pipelines tasks will be masked as **** when being displayed.
However, there's nothing to stop someone malicious from base64 encoding the value and printing it. Or ROT encoding it. Or reversing it. Or splitting the string in half and printing both halves. Or running a script that does this: az keyvault secret show. And so on and so forth.
If there's a secret value in memory as plain text, and people have the ability to manipulate the environment on which the secret is stored in memory as plain text, it's trivial to get the plaintext value of the secret. That's true for any computer under any circumstances.
If this is a concern, by far the best approach is to not have pipelines read secrets. If your application can be configured to integrate directly with keyvault and retrieve the secrets as needed at runtime, there's no need to have the pipeline retrieve the secret as an intermediate step.
I'm not finding any answers to this on Google but I may just not know what terms to search for.
In a CRD, is there a way to define a field in the spec that is a secret (and therefore shouldn't be stored in plain text)? For example, if the custom resource needs to have an API token included in it, how do you define that in the CRD?
One thought I had was to just have the user create a Secret outside of the CRD and then provide the secret's name in a custom resource field so the operator can query it from the K8s API on demand when needed (and obviously associated RBAC needs to be configured so the operator has read access to the Secret). So the field in the CRD would just be a normal string that is the name of the target Secret.
But is there a better way? Any existing best practices around this?
You do indeed just store the value in an actual Secret and reference it. You'll find the same pattern all over k8s. Then in your controller code you get your custom object, find the ref, get that secret, and then you have your data.
Is there a way to easily query Kubernetes resources in an intuitive way? Basically I want to run queries to extract info about objects which match my criteria. Currently I face an issue where my match labels isn't quite working and I would like to run the match labels query manually to try and debug my issue.
Basically in a pseudo code way:
Select * from pv where labels in [red,blue,green]
Any third party tools who do something like this? Currently all I have to work with is the search box on the dashboard which isn't quite robust enough.
You could use kubectl with JSONPath (https://kubernetes.io/docs/reference/kubectl/jsonpath/). More information on JSONPath: https://github.com/json-path/JsonPath
It allows you to query any resource property, example:
kubectl get pods -o=jsonpath='{$.items[?(#.metadata.namespace=="default")].metadata.name}'
This would list all pod names in namespace "default". Your pseudo code would be something along the lines:
kubectl get pv -o=jsonpath='{$.items[?(#.metadata.label in ["red","blue","green"])]}'
Have been using Kubernetes secrets up to date.
Now we have ConfigMaps as well.
What is the preferred way forward - secrets or config maps?
P.S. After a few iterations we have stabilised at the following rule:
configMaps are per solution domain (can be shared across microservices within the domain, but ultimately are single purpose config entries)
secrets are shared across solution domains, usually represent third party systems or databases
I'm the author of both of these features. The idea is that you should:
Use Secrets for things which are actually secret like API keys, credentials, etc
Use ConfigMaps for not-secret configuration data
In the future, there will likely be some differentiators for secrets like rotation or support for backing the secret API w/ HSMs, etc. In general, we like intent-based APIs, and the intent is definitely different for secret data vs. plain old configs.
One notable difference in the implementation is that kubectl apply -f:
ConfigMaps are "unchanged" if the data hasn't changed.
Secrets are always "configured" - even if the file hasn't changed
Both, ConfigMaps and Secrets store data as a key value pair. The major difference is, Secrets store data in base64 format meanwhile ConfigMaps store data in a plain text.
If you have some critical data like, keys, passwords, service accounts credentials, db connection string, etc then you should always go for Secrets rather than Configs.
And if you want to do some application configuration using environment variables which you don't want to keep secret/hidden like, app theme, base platform url, etc then you can go for ConfigMaps