From accb4c915ee510e02809bbd6b7de3dbca77b0217 Mon Sep 17 00:00:00 2001 From: leigh capili Date: Wed, 3 Mar 2021 08:38:00 -0700 Subject: [PATCH 1/3] Improve SOPS GPG guide key management - Switch to batch GPG key creation - Accurately name the cluster's decryption key - Suggest password-manager backup - Optionally cleanup secret key from generating machine - Optionally commit the public key to the repo for team members - Document SOPS limitations decryption required for editing / appending fields Signed-off-by: leigh capili --- docs/guides/mozilla-sops.md | 148 ++++++++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 40 deletions(-) diff --git a/docs/guides/mozilla-sops.md b/docs/guides/mozilla-sops.md index 4ff88850..1554fee1 100644 --- a/docs/guides/mozilla-sops.md +++ b/docs/guides/mozilla-sops.md @@ -19,24 +19,30 @@ brew install gnupg sops ## Generate a GPG key -Generate a GPG key with OpenPGP without specifying a passphrase: +Generate a GPG/OpenPGP key with no passphrase (`%no-protection`): ```console -$ gpg --full-generate-key - -Real name: stefanprodan -Email address: stefanprodan@users.noreply.github.com -Comment: -You selected this USER-ID: - "stefanprodan " +gpg --batch --full-generate-key < basic-auth.yaml -``` - -Encrypt the secret with sops using your GPG key: +It's a good idea to back up this secret-key/k8s-Secret with a password manager or offline storage. +Also consider deleting the secret decryption key from you machine: -```sh -sops --encrypt \ ---pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \ ---encrypted-regex '^(data|stringData)$' \ ---in-place basic-auth.yaml +```console +gpg --delete-secret-keys 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 ``` -!!! hint - Note that you should encrypt only the `data` section. Encrypting the Kubernetes - secret metadata, kind or apiVersion is not supported by kustomize-controller. +## Configure in-cluster secrets decryption -You can now commit the encrypted secret to your Git repository. - -!!! hint - Note that you shouldn't apply the encrypted secrets onto the cluster with kubectl. SOPS encrypted secrets are designed to be consumed by kustomize-controller. - -## Configure secrets decryption - -Registry the Git repository on your cluster: +Register the Git repository on your cluster: ```sh flux create source git my-secrets \ @@ -95,6 +78,7 @@ Create a kustomization for reconciling the secrets on the cluster: ```sh flux create kustomization my-secrets \ --source=my-secrets \ +--path=./clusters/cluster0 \ --prune=true \ --interval=10m \ --decryption-provider=sops \ @@ -104,6 +88,90 @@ flux create kustomization my-secrets \ Note that the `sops-gpg` can contain more than one key, sops will try to decrypt the secrets by iterating over all the private keys until it finds one that works. +## Optional: Export the public key into the git directory + +Commit the public key to the repository so that team members who clone the repo can encrypt new files: + +```console +gpg --export \ +--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 > ./clusters/cluster0/.sops.pub.asc +``` + +Check the file contents to ensure it's the public key before adding it to the repo and committing. + +```console +git add ./clusters/cluster0/.sops.pub.asc +git commit -am 'Share GPG public key for secrets generation' +``` + +Team members can then import this key when they pull the git repository: + +```console +gpg --import ./clusters/cluster0/.sops.pub.asc +``` + +!!! hint + The public key is sufficient for creating brand new files. + The secret key is required for decrypting and editing existing files because SOPS computes a MAC on all values. + When using solely the public key to add or remove a field, the whole file should be deleted and recreated. + +## Configure the git directory for encryption + +Write a [sops config file](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) to the specific cluster or namespace directory used +to store encrypted objects with this particular GPG key's fingerprint. + +```yaml +# ./clusters/cluster0/.sops.yaml +creation_rules: + - path_regex: .*.yaml + encrypted_regex: ^(data|stringData)$ + pgp: 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 +``` + +This config applies recursively to all sub-directories. +Multiple directories can use separate sops configs. +Contributors using the `sops` CLI to create and encrypt files +won't have to worry about specifying the proper key for the target cluster or namespace. + +`encrypted_regex` helps encrypt the the proper `data` and `stringData` fields for Secrets. +You may wish to add other fields if you are encrypting other types of Objects. + +!!! hint + Note that you should encrypt only the `data` or `stringData` section. Encrypting the Kubernetes + secret metadata, kind or apiVersion is not supported by kustomize-controller. + +Ignore all `.sops.yaml` files in a [`.sourceignore`](../components/source/gitrepositories#excluding-files) file at the root of your repo. + +```sh +touch .sourceignore +echo '**/.sops.yaml' >> .sourceignore +``` + +You can now commit your SOPS config. + +## Encrypt secrets + +Generate a Kubernetes secret manifest with kubectl: + +```sh +kubectl -n default create secret generic basic-auth \ +--from-literal=user=admin \ +--from-literal=password=change-me \ +--dry-run=client \ +-o yaml > basic-auth.yaml +``` + +Encrypt the secret with sops using your GPG key: + +```sh +sops --encrypt --in-place basic-auth.yaml +``` + +You can now commit the encrypted secret to your Git repository. + +!!! hint + Note that you shouldn't apply the encrypted secrets onto the cluster with kubectl. SOPS encrypted secrets are designed to be consumed by kustomize-controller. + ### Using various cloud providers When using AWS/GCP KMS, you don't have to include the gpg `secretRef` under From 095c8323a1245f7bb38a4532d526cb2dc02824b8 Mon Sep 17 00:00:00 2001 From: leigh capili Date: Thu, 4 Mar 2021 09:04:04 -0700 Subject: [PATCH 2/3] Capitalize SOPS, K8s, and Git Signed-off-by: leigh capili --- docs/guides/mozilla-sops.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/guides/mozilla-sops.md b/docs/guides/mozilla-sops.md index 1554fee1..fd2d16d1 100644 --- a/docs/guides/mozilla-sops.md +++ b/docs/guides/mozilla-sops.md @@ -11,7 +11,7 @@ toolkit controllers installed on it. Please see the [get started guide](../get-started/index.md) or the [installation guide](installation.md). -Install [gnupg](https://www.gnupg.org/) and [sops](https://github.com/mozilla/sops): +Install [gnupg](https://www.gnupg.org/) and [SOPS](https://github.com/mozilla/sops): ```sh brew install gnupg sops @@ -57,7 +57,7 @@ kubectl create secret generic sops-gpg \ --from-file=sops.asc=/dev/stdin ``` -It's a good idea to back up this secret-key/k8s-Secret with a password manager or offline storage. +It's a good idea to back up this secret-key/K8s-Secret with a password manager or offline storage. Also consider deleting the secret decryption key from you machine: ```console @@ -85,10 +85,10 @@ flux create kustomization my-secrets \ --decryption-secret=sops-gpg ``` -Note that the `sops-gpg` can contain more than one key, sops will try to decrypt the +Note that the `sops-gpg` can contain more than one key, SOPS will try to decrypt the secrets by iterating over all the private keys until it finds one that works. -## Optional: Export the public key into the git directory +## Optional: Export the public key into the Git directory Commit the public key to the repository so that team members who clone the repo can encrypt new files: @@ -104,7 +104,7 @@ git add ./clusters/cluster0/.sops.pub.asc git commit -am 'Share GPG public key for secrets generation' ``` -Team members can then import this key when they pull the git repository: +Team members can then import this key when they pull the Git repository: ```console gpg --import ./clusters/cluster0/.sops.pub.asc @@ -115,9 +115,9 @@ gpg --import ./clusters/cluster0/.sops.pub.asc The secret key is required for decrypting and editing existing files because SOPS computes a MAC on all values. When using solely the public key to add or remove a field, the whole file should be deleted and recreated. -## Configure the git directory for encryption +## Configure the Git directory for encryption -Write a [sops config file](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) to the specific cluster or namespace directory used +Write a [SOPS config file](https://github.com/mozilla/sops#using-sops-yaml-conf-to-select-kms-pgp-for-new-files) to the specific cluster or namespace directory used to store encrypted objects with this particular GPG key's fingerprint. ```yaml @@ -129,7 +129,7 @@ creation_rules: ``` This config applies recursively to all sub-directories. -Multiple directories can use separate sops configs. +Multiple directories can use separate SOPS configs. Contributors using the `sops` CLI to create and encrypt files won't have to worry about specifying the proper key for the target cluster or namespace. @@ -161,7 +161,7 @@ kubectl -n default create secret generic basic-auth \ -o yaml > basic-auth.yaml ``` -Encrypt the secret with sops using your GPG key: +Encrypt the secret with SOPS using your GPG key: ```sh sops --encrypt --in-place basic-auth.yaml @@ -278,5 +278,5 @@ Once the manifests have been pushed to the Git repository, the following happens * source-controller pulls the changes from Git * kustomize-controller loads the GPG keys from the `sops-pgp` secret -* kustomize-controller decrypts the Kubernetes secrets with sops and applies them on the cluster +* kustomize-controller decrypts the Kubernetes secrets with SOPS and applies them on the cluster * kubelet creates the pods and mounts the secret as a volume or env variable inside the app container From d2cdd02a573dfa1ca4b3309021933857055794c1 Mon Sep 17 00:00:00 2001 From: leigh capili Date: Thu, 4 Mar 2021 10:31:54 -0700 Subject: [PATCH 3/3] Parameterize GPG key input and fingerprint Signed-off-by: leigh capili --- docs/guides/mozilla-sops.md | 40 ++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/guides/mozilla-sops.md b/docs/guides/mozilla-sops.md index fd2d16d1..c39fec0d 100644 --- a/docs/guides/mozilla-sops.md +++ b/docs/guides/mozilla-sops.md @@ -21,7 +21,10 @@ brew install gnupg sops Generate a GPG/OpenPGP key with no passphrase (`%no-protection`): -```console +```sh +export KEY_NAME="cluster0.yourdomain.com" +export KEY_COMMENT="flux secrets" + gpg --batch --full-generate-key < ./clusters/cluster0/.sops.pub.asc +```sh +gpg --export --armor "${KEY_FP}" > ./clusters/cluster0/.sops.pub.asc ``` Check the file contents to ensure it's the public key before adding it to the repo and committing. -```console +```sh git add ./clusters/cluster0/.sops.pub.asc git commit -am 'Share GPG public key for secrets generation' ``` Team members can then import this key when they pull the Git repository: -```console +```sh gpg --import ./clusters/cluster0/.sops.pub.asc ``` @@ -121,11 +128,12 @@ Write a [SOPS config file](https://github.com/mozilla/sops#using-sops-yaml-conf- to store encrypted objects with this particular GPG key's fingerprint. ```yaml -# ./clusters/cluster0/.sops.yaml +cat < ./clusters/cluster0/.sops.yaml creation_rules: - path_regex: .*.yaml encrypted_regex: ^(data|stringData)$ - pgp: 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 + pgp: ${KEY_FP} +EOF ``` This config applies recursively to all sub-directories.