question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Kubernetes secrets created by helm are saved as plaintext in the state

See original GitHub issue

It seems that pulumi doesn’t encrypt the data property of Kubernetes secrets when it is saved to the state. I’m doing the following to deploy charts:

helmv3.NewChart(ctx, deploymentName, chartArgs, pulumi.Provider(p))

I tried using local file backend and s3 backend and had the same result. My encryption provider is passphrase

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
yarinmcommented, Oct 15, 2020

@lblackstone I think the default approach should be that any kubernetes secret generated by helm is considered as secret value that needs to be encrypted.

1reaction
lblackstonecommented, Oct 12, 2020

I tested this out, and it seems to be working as expected for me:

  1. The Secret outputs (data and stringData) were properly masked/encrypted in the state
  2. Exporting the .Data field did not reveal the secret in the terminal (secret: "[secret]")

I did notice that the input field in the statefile will contain the secret string in plaintext if you don’t have it marked as secret, so perhaps that was the issue you were seeing?

Here’s the program I tested:

package main

import (
	"fmt"

	corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v2/go/kubernetes/core/v1"
	"github.com/pulumi/pulumi/sdk/v2/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {

		val, ok := ctx.GetConfig("go-passphrase:test")
		if !ok {
			return fmt.Errorf("missing expected config: test")
		}

		secret, err := corev1.NewSecret(ctx, "test", &corev1.SecretArgs{
			StringData: pulumi.StringMap{
				"test": pulumi.ToSecret(val).(pulumi.StringOutput),
			},
		})
		if err != nil {
			return err
		}
		ctx.Export("secret", secret.Data)

		return nil
	})
}

I created the config value with the following:

pulumi config set test foobar --secret

Here’s the resulting state:

{
    "version": 3,
    "deployment": {
        "manifest": {
            "time": "2020-10-12T14:55:48.163619-06:00",
            "magic": "98f78d57683dc19b6e286aab23b466609878e712bd0deda86789fe3abe0f8146",
            "version": "v2.11.2"
        },
        "secrets_providers": {
            "type": "passphrase",
            "state": {
                "salt": "v1:EQVleCdv9FM=:v1:Qr9ZMlSy0AdlsPdp:rERnXfkwdwT9GOmLLSg9guvzxLxK5A=="
            }
        },
        "resources": [
            {
                "urn": "urn:pulumi:dev::go-passphrase::pulumi:pulumi:Stack::go-passphrase-dev",
                "custom": false,
                "type": "pulumi:pulumi:Stack",
                "outputs": {
                    "secret": {
                        "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                        "ciphertext": "v1:sbDgE3TUzr0hKSwe:lnMYmYe8MUCLD6I4IBM7K/NCITNI4e9ERfhyBkjZQSlvY0U="
                    }
                }
            },
            {
                "urn": "urn:pulumi:dev::go-passphrase::pulumi:providers:kubernetes::default",
                "custom": true,
                "id": "cd63e3f2-fd08-4061-b84a-791f60e03363",
                "type": "pulumi:providers:kubernetes",
                "inputs": {
                    "version": "2.5.1"
                },
                "outputs": {
                    "version": "2.5.1"
                }
            },
            {
                "urn": "urn:pulumi:dev::go-passphrase::kubernetes:core/v1:Secret::test",
                "custom": true,
                "id": "default/test-fj5j6gc1",
                "type": "kubernetes:core/v1:Secret",
                "inputs": {
                    "apiVersion": "v1",
                    "kind": "Secret",
                    "metadata": {
                        "annotations": {
                            "pulumi.com/autonamed": "true"
                        },
                        "labels": {
                            "app.kubernetes.io/managed-by": "pulumi"
                        },
                        "name": "test-fj5j6gc1"
                    },
                    "stringData": {
                        "test": {
                            "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                            "ciphertext": "v1:xK9KiHyPzoxDYApK:RWEiaa+0Ky4u/4yzSdRxeJKa2CGdxOu5"
                        }
                    }
                },
                "outputs": {
                    "__initialApiVersion": "v1",
                    "__inputs": {
                        "apiVersion": "v1",
                        "kind": "Secret",
                        "metadata": {
                            "annotations": {
                                "pulumi.com/autonamed": "true"
                            },
                            "labels": {
                                "app.kubernetes.io/managed-by": "pulumi"
                            },
                            "name": "test-fj5j6gc1"
                        },
                        "stringData": {
                            "test": {
                                "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                                "ciphertext": "v1:kqoXS1p/1WuzX4JX:gL0ixYEYdv5O0KFcsmaDOp51DII4PNSl"
                            }
                        }
                    },
                    "apiVersion": "v1",
                    "data": {
                        "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                        "ciphertext": "v1:7TE4cX2ur2Zk6yOX:tlxkAKp73ClEmIsXqIJSH8GXRn0QI2fx2VmzOJjT3G/bFEyqDEFaiuLgJJgetFM1Dwt2KFnUIPelo7a9KgvcThuPRTOcDbNJ34P+kCjg7ufd+bmpYt5cS45TNkCtJT535w+R4Z9GJ0HWQWKAmOdWlhZsPPMl16YFQEf8GA=="
                    },
                    "kind": "Secret",
                    "metadata": {
                        "annotations": {
                            "kubectl.kubernetes.io/last-applied-configuration": {
                                "4dabf18193072939515e22adb298388d": "1b47061264138c4ac30d75fd1eb44270",
                                "ciphertext": "v1:WtECzeJ12SUkRtC4:bJz00nGT3G4xBhIKcxt+9l92DbD7qo3DbCMIk0UWusX4ydQKO28nCaBXHI4Yv5EIERZUlm/q16al9/NMIMiXmpJGr4buFnpJDuyvViwP5ZF6Jjr99nhmfOuvNZHbtnxq8fa0dJYNszUMXtAiB3WZ8pIlmNNeOubMFw6o7moMxyUvx80I1yQ9gwcXel9XaOwO6OhKwHg+bW+FN7xA491MZR1nysh0EbVSt5OPpO+N3PMELdyCs4Ox+o816s95zRVskMNyQowZu9yvYkg3CtwSpLOVqfQqpwZ6oRRV2qFzgXoKGzKM4F+P1g8rxwxBG7fi8tfhfbYV2NnZxZA="
                            },
                            "pulumi.com/autonamed": "true"
                        },
                        "creationTimestamp": "2020-10-12T20:55:48Z",
                        "labels": {
                            "app.kubernetes.io/managed-by": "pulumi"
                        },
                        "managedFields": [
                            {
                                "apiVersion": "v1",
                                "fieldsType": "FieldsV1",
                                "fieldsV1": {
                                    "f:data": {
                                        ".": {},
                                        "f:test": {}
                                    },
                                    "f:metadata": {
                                        "f:annotations": {
                                            ".": {},
                                            "f:kubectl.kubernetes.io/last-applied-configuration": {},
                                            "f:pulumi.com/autonamed": {}
                                        },
                                        "f:labels": {
                                            ".": {},
                                            "f:app.kubernetes.io/managed-by": {}
                                        }
                                    },
                                    "f:type": {}
                                },
                                "manager": "pulumi-resource-kubernetes",
                                "operation": "Update",
                                "time": "2020-10-12T20:55:48Z"
                            }
                        ],
                        "name": "test-fj5j6gc1",
                        "namespace": "default",
                        "resourceVersion": "721442",
                        "selfLink": "/api/v1/namespaces/default/secrets/test-fj5j6gc1",
                        "uid": "4f29a4ef-469d-4b67-9fc6-60a808af1c5b"
                    },
                    "type": "Opaque"
                },
                "parent": "urn:pulumi:dev::go-passphrase::pulumi:pulumi:Stack::go-passphrase-dev",
                "provider": "urn:pulumi:dev::go-passphrase::pulumi:providers:kubernetes::default::cd63e3f2-fd08-4061-b84a-791f60e03363",
                "propertyDependencies": {
                    "apiVersion": [],
                    "kind": [],
                    "stringData": []
                },
                "additionalSecretOutputs": [
                    "data",
                    "stringData"
                ]
            }
        ]
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Secrets in Helm chart resource are plaintext in state file #999
When a Pulumi secret is used in a Helm chart resource, its plaintext value ends up in the Pulumi state file where in...
Read more >
Secrets | Kubernetes
Kubernetes Secrets are, by default, stored unencrypted in the API server's underlying data store (etcd). Anyone with API access can retrieve or ...
Read more >
Manage Auto-generated Secrets In Your Helm Charts - ITNEXT
Using Helm's lookup function, we can inspect the current state of the cluster in order to create & manage the secret within the...
Read more >
Kubernetes Secrets - How to Create, Use, & Access Secrets
A secret is a Kubernetes object storing sensitive pieces of data ... Save the file and use the kubectl apply command to create...
Read more >
How to keep your Kubernetes secrets secure in Git - Learnk8s
Kubernetes secrets hold the most sensitive information of your application - API keys, tokens, database passwords, etc. If a hacker can retrieve one...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found