diff --git a/cmd/gotk/create_kustomization.go b/cmd/gotk/create_kustomization.go
index 4c6d3d120c94ac46588854b61ff27dccc603ee15..d2eb02cb8966d14da11158a186f1d73d2c4b7ee3 100644
--- a/cmd/gotk/create_kustomization.go
+++ b/cmd/gotk/create_kustomization.go
@@ -73,15 +73,17 @@ var createKsCmd = &cobra.Command{
 }
 
 var (
-	ksSource        string
-	ksPath          string
-	ksPrune         bool
-	ksDependsOn     []string
-	ksValidation    string
-	ksHealthCheck   []string
-	ksHealthTimeout time.Duration
-	ksSAName        string
-	ksSANamespace   string
+	ksSource             string
+	ksPath               string
+	ksPrune              bool
+	ksDependsOn          []string
+	ksValidation         string
+	ksHealthCheck        []string
+	ksHealthTimeout      time.Duration
+	ksSAName             string
+	ksSANamespace        string
+	ksDecryptionProvider string
+	ksDecryptionSecret   string
 )
 
 func init() {
@@ -94,6 +96,8 @@ func init() {
 	createKsCmd.Flags().StringArrayVar(&ksDependsOn, "depends-on", nil, "Kustomization that must be ready before this Kustomization can be applied")
 	createKsCmd.Flags().StringVar(&ksSAName, "sa-name", "", "service account name")
 	createKsCmd.Flags().StringVar(&ksSANamespace, "sa-namespace", "", "service account namespace")
+	createKsCmd.Flags().StringVar(&ksDecryptionProvider, "decryption-provider", "", "enables secrets decryption, provider can be 'sops'")
+	createKsCmd.Flags().StringVar(&ksDecryptionSecret, "decryption-secret", "", "set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption")
 	createCmd.AddCommand(createKsCmd)
 }
 
@@ -178,6 +182,21 @@ func createKsCmdRun(cmd *cobra.Command, args []string) error {
 		}
 	}
 
+	if ksDecryptionProvider != "" {
+		if !utils.containsItemString(supportedDecryptionProviders, ksDecryptionProvider) {
+			return fmt.Errorf("decryption provider %s is not supported, can be %v",
+				ksDecryptionProvider, supportedDecryptionProviders)
+		}
+
+		kustomization.Spec.Decryption = &kustomizev1.Decryption{
+			Provider: ksDecryptionProvider,
+		}
+
+		if ksDecryptionSecret != "" {
+			kustomization.Spec.Decryption.SecretRef = &corev1.LocalObjectReference{Name: ksDecryptionSecret}
+		}
+	}
+
 	if export {
 		return exportKs(kustomization)
 	}
diff --git a/cmd/gotk/main.go b/cmd/gotk/main.go
index cad7015be8f005617752348260728d711b912fce..03e1afbcb1839039c26d499bbd72334977619e32 100644
--- a/cmd/gotk/main.go
+++ b/cmd/gotk/main.go
@@ -104,11 +104,12 @@ var (
 )
 
 var (
-	defaultComponents   = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
-	defaultVersion      = "latest"
-	defaultNamespace    = "gitops-system"
-	defaultNotification = "notification-controller"
-	supportedArch       = []string{"arm64", "amd64"}
+	defaultComponents            = []string{"source-controller", "kustomize-controller", "helm-controller", "notification-controller"}
+	defaultVersion               = "latest"
+	defaultNamespace             = "gitops-system"
+	defaultNotification          = "notification-controller"
+	supportedArch                = []string{"arm64", "amd64"}
+	supportedDecryptionProviders = []string{"sops"}
 )
 
 func init() {
diff --git a/docs/cmd/gotk_create_kustomization.md b/docs/cmd/gotk_create_kustomization.md
index 171f6c0f37c3e4b2dacf10613ad04e7e87ea53b8..78893d7104460acbcbd71ab7d71d49121065e203 100644
--- a/docs/cmd/gotk_create_kustomization.md
+++ b/docs/cmd/gotk_create_kustomization.md
@@ -48,6 +48,8 @@ gotk create kustomization [name] [flags]
 ### Options
 
 ```
+      --decryption-provider string      enables secrets decryption, provider can be 'sops'
+      --decryption-secret string        set the Kubernetes secret name that contains the OpenPGP private keys used for sops decryption
       --depends-on stringArray          Kustomization that must be ready before this Kustomization can be applied
       --health-check stringArray        workload to be included in the health assessment, in the format '<kind>/<name>.<namespace>'
       --health-check-timeout duration   timeout of health checking operations (default 2m0s)
diff --git a/docs/guides/mozilla-sops.md b/docs/guides/mozilla-sops.md
new file mode 100644
index 0000000000000000000000000000000000000000..b210a93371583f630044f86b3d145de08a6a2928
--- /dev/null
+++ b/docs/guides/mozilla-sops.md
@@ -0,0 +1,166 @@
+# Manage Kubernetes secrets with Mozilla SOPS
+
+In order to store secrets safely in a public or private Git repository, you can use
+Mozilla's [SOPS](https://github.com/mozilla/sops) CLI to encrypt 
+Kubernetes secrets with OpenPGP, AWS KMS, GCP KMS and Azure Key Vault.
+
+## Prerequisites
+
+To follow this guide you'll need a Kubernetes cluster with the GitOps 
+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):
+
+```sh
+brew install gnupg sops
+```
+
+## Generate a GPG key
+
+Generate a GPG key with OpenPGP without specifying a passphrase:
+
+```console
+$ gpg --full-generate-key
+
+Real name: stefanprodan
+Email address: stefanprodan@users.noreply.github.com
+Comment: 
+You selected this USER-ID:
+    "stefanprodan <stefanprodan@users.noreply.github.com>"
+```
+
+Retrieve the GPG key ID (second row of the sec column):
+
+```console
+$ gpg --list-secret-keys stefanprodan@users.noreply.github.com
+
+sec   rsa3072 2020-09-06 [SC]
+      1F3D1CED2F865F5E59CA564553241F147E7C5FA4
+```
+
+Export the public and private keypair from your local GPG keyring and
+create a Kubernetes secret named `sops-gpg` in the `gitops-system` namespace:
+
+```sh
+gpg --export-secret-keys \
+--armor 1F3D1CED2F865F5E59CA564553241F147E7C5FA4 |
+kubectl create secret generic sops-gpg \
+--namespace=gitops-system \
+--from-file=sops.asc=/dev/stdin 
+```
+
+## 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 \
+--pgp=1F3D1CED2F865F5E59CA564553241F147E7C5FA4 \
+--encrypted-regex '^(data|stringData)$' \
+--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.
+
+## Configure secrets decryption
+
+Registry the Git repository on your cluster:
+
+```sh
+gotk create source git my-secrets \
+--url=https://github.com/my-org/my-secrets
+```
+
+Create a kustomization for reconciling the secrets on the cluster:
+
+```sh
+gotk 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.
+
+!!! hint KMS
+    When using AWS/GCP KMS or Azure Key Vault, you'll have to bind an IAM Role
+    with read access to the KMS keys to the `default` service account of the
+    `gitops-system` namespace for kustomize-controller to be able to fetch
+    keys from KMS.
+
+## GitOps workflow
+
+A cluster admin should create the Kubernetes secret with the PGP keys on each cluster and
+add the GitRepository/Kustomization manifests to the fleet repository.
+
+Git repository manifest:
+
+```yaml
+apiVersion: source.toolkit.fluxcd.io/v1alpha1
+kind: GitRepository
+metadata:
+  name: my-secrets
+  namespace: gitops-system
+spec:
+  interval: 1m
+  url: https://github.com/my-org/my-secrets
+```
+
+Kustomization manifest:
+
+```yaml
+apiVersion: kustomize.toolkit.fluxcd.io/v1alpha1
+kind: Kustomization
+metadata:
+  name: my-secrets
+  namespace: gitops-system
+spec:
+  interval: 10m0s
+  sourceRef:
+    kind: GitRepository
+    name: my-secrets
+  path: ./
+  prune: true
+  decryption:
+    provider: sops
+    secretRef:
+      name: sops-gpg
+```
+
+!!! hint
+    You can generate the above manifests using `gotk create <kind> --export > manifest.yaml`.
+
+Assuming a team member wants to deploy an application that needs to connect
+to a database using a username and password, they'll be doing the following:
+
+* create a Kubernetes Secret manifest locally with the db credentials e.g. `db-auth.yaml`
+* encrypt the secret `data` field with sops
+* create a Kubernetes Deployment manifest for the app e.g. `app-deployment.yaml`
+* add the Secret to the Deployment manifest as a [volume mount or env var](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets)
+* commit the manifests `db-auth.yaml` and `app-deployment.yaml` to a Git repository that's being synced by the GitOps toolkit controllers
+
+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
+* kubelet creates the pods and mounts the secret as a volume or env variable inside the app container
diff --git a/mkdocs.yml b/mkdocs.yml
index 135d9e5442077b2f468787819ba7ccf42683c16a..ef9c36cf2b2b655926e060cd2b2c4db4a43a946f 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -50,6 +50,7 @@ nav:
       - Setup Notifications: guides/notifications.md
       - Setup Webhook Receivers: guides/webhook-receivers.md
       - Sealed Secrets: guides/sealed-secrets.md
+      - Mozilla SOPS: guides/mozilla-sops.md
   - Toolkit Components:
     - Source Controller:
       - Overview: components/source/controller.md