diff --git a/docs/guides/mozilla-sops.md b/docs/guides/mozilla-sops.md index 4ff88850d7..c39fec0dff 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 @@ -19,71 +19,62 @@ 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 " +```sh +export KEY_NAME="cluster0.yourdomain.com" +export KEY_COMMENT="flux secrets" + +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 +gpg --delete-secret-keys "${KEY_FP}" ``` -!!! 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 +## Configure in-cluster secrets decryption -Registry the Git repository on your cluster: +Register the Git repository on your cluster: ```sh flux create source git my-secrets \ @@ -95,15 +86,100 @@ 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 \ --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 + +Commit the public key to the repository so that team members who clone the repo can encrypt new files: + +```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. + +```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: + +```sh +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 +cat < ./clusters/cluster0/.sops.yaml +creation_rules: + - path_regex: .*.yaml + encrypted_regex: ^(data|stringData)$ + pgp: ${KEY_FP} +EOF +``` + +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 @@ -210,5 +286,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