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 | 152 ++++++++++++++++++++++++++---------- 1 file changed, 110 insertions(+), 42 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 < ./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: @@ -66,44 +164,14 @@ kubectl -n default create secret generic basic-auth \ Encrypt the secret with sops using your GPG key: ```sh -sops --encrypt \ ---pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \ ---encrypted-regex '^(data|stringData)$' \ ---in-place basic-auth.yaml +sops --encrypt --in-place basic-auth.yaml ``` -!!! hint - Note that you should encrypt only the `data` section. Encrypting the Kubernetes - secret metadata, kind or apiVersion is not supported by kustomize-controller. - 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: - -```sh -flux create source git my-secrets \ ---url=https://github.com/my-org/my-secrets -``` - -Create a kustomization for reconciling the secrets on the cluster: - -```sh -flux create kustomization my-secrets \ ---source=my-secrets \ ---prune=true \ ---interval=10m \ ---decryption-provider=sops \ ---decryption-secret=sops-gpg -``` - -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. - ### 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.