diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 99fd21609b4e55e92b1616563f71c84dce8dfc41..42e9e6ebab7ebd91257755073f40f6f7f6a0b0f0 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -80,9 +80,16 @@ jobs:
       - name: tk resume kustomization
         run: |
           ./bin/tk resume kustomization podinfo
+      - name: tk export
+        run: |
+          ./bin/tk export source git --all
+          ./bin/tk export kustomization --all
       - name: tk delete kustomization
         run: |
           ./bin/tk delete kustomization podinfo --silent
+      - name: tk delete source git
+        run: |
+          ./bin/tk delete source git podinfo --silent
       - name: tk check
         run: |
           ./bin/tk check
diff --git a/cmd/tk/delete_source.go b/cmd/tk/delete_source.go
new file mode 100644
index 0000000000000000000000000000000000000000..31e95266408048a412f9b98b79049c482eac7cb0
--- /dev/null
+++ b/cmd/tk/delete_source.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+	"github.com/spf13/cobra"
+)
+
+var deleteSourceCmd = &cobra.Command{
+	Use:   "source",
+	Short: "Delete sources commands",
+}
+
+func init() {
+	deleteCmd.AddCommand(deleteSourceCmd)
+}
diff --git a/cmd/tk/delete_source_git.go b/cmd/tk/delete_source_git.go
new file mode 100644
index 0000000000000000000000000000000000000000..9ff9bb39ca081e962fcbc50a27a5bbf8e2b77dbd
--- /dev/null
+++ b/cmd/tk/delete_source_git.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+	"context"
+	"fmt"
+
+	sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
+	"github.com/manifoldco/promptui"
+	"github.com/spf13/cobra"
+	"k8s.io/apimachinery/pkg/types"
+)
+
+var deleteSourceGitCmd = &cobra.Command{
+	Use:   "git [name]",
+	Short: "Delete git source",
+	RunE:  deleteSourceGitCmdRun,
+}
+
+func init() {
+	deleteSourceCmd.AddCommand(deleteSourceGitCmd)
+}
+
+func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error {
+	if len(args) < 1 {
+		return fmt.Errorf("git name is required")
+	}
+	name := args[0]
+
+	ctx, cancel := context.WithTimeout(context.Background(), timeout)
+	defer cancel()
+
+	kubeClient, err := utils.kubeClient(kubeconfig)
+	if err != nil {
+		return err
+	}
+
+	namespacedName := types.NamespacedName{
+		Namespace: namespace,
+		Name:      name,
+	}
+
+	var git sourcev1.GitRepository
+	err = kubeClient.Get(ctx, namespacedName, &git)
+	if err != nil {
+		return err
+	}
+
+	if !deleteSilent {
+		prompt := promptui.Prompt{
+			Label: fmt.Sprintf(
+				"Are you sure you want to delete the %s source from the %s namespace", name, namespace,
+			),
+			IsConfirm: true,
+		}
+		if _, err := prompt.Run(); err != nil {
+			return fmt.Errorf("aborting")
+		}
+	}
+
+	logAction("deleting source %s in %s namespace", name, namespace)
+	err = kubeClient.Delete(ctx, &git)
+	if err != nil {
+		return err
+	}
+	logSuccess("source deleted")
+
+	return nil
+}
diff --git a/cmd/tk/export.go b/cmd/tk/export.go
new file mode 100644
index 0000000000000000000000000000000000000000..55aebbec57daa1739bac1fd940de9c2be8859009
--- /dev/null
+++ b/cmd/tk/export.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"github.com/spf13/cobra"
+)
+
+var exportCmd = &cobra.Command{
+	Use:   "export",
+	Short: "Export commands",
+}
+
+var (
+	exportAll bool
+)
+
+func init() {
+	exportCmd.PersistentFlags().BoolVar(&exportAll, "all", false, "select all resources")
+
+	rootCmd.AddCommand(exportCmd)
+}
diff --git a/cmd/tk/export_kustomization.go b/cmd/tk/export_kustomization.go
new file mode 100644
index 0000000000000000000000000000000000000000..dbb59b4b3ff581ed0fa9e3044a33bc479c6b7222
--- /dev/null
+++ b/cmd/tk/export_kustomization.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+	"context"
+	"fmt"
+
+	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
+	"github.com/spf13/cobra"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/yaml"
+)
+
+var exportKsCmd = &cobra.Command{
+	Use:     "kustomization [name]",
+	Aliases: []string{"ks"},
+	Short:   "Export kustomization in YAML format",
+	Example: `  # Export all kustomizations
+  export kustomization --all > kustomizations.yaml
+
+  # Export a kustomization
+  export kustomization my-app > kustomization.yaml
+`,
+	RunE: exportKsCmdRun,
+}
+
+func init() {
+	exportCmd.AddCommand(exportKsCmd)
+}
+
+func exportKsCmdRun(cmd *cobra.Command, args []string) error {
+	if !exportAll && len(args) < 1 {
+		return fmt.Errorf("kustomization name is required")
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), timeout)
+	defer cancel()
+
+	kubeClient, err := utils.kubeClient(kubeconfig)
+	if err != nil {
+		return err
+	}
+
+	if exportAll {
+		var list kustomizev1.KustomizationList
+		err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
+		if err != nil {
+			return err
+		}
+
+		if len(list.Items) == 0 {
+			logFailure("no kustomizations found in %s namespace", namespace)
+			return nil
+		}
+
+		for _, kustomization := range list.Items {
+			if err := exportKs(kustomization); err != nil {
+				return err
+			}
+		}
+	} else {
+		name := args[0]
+		namespacedName := types.NamespacedName{
+			Namespace: namespace,
+			Name:      name,
+		}
+		var kustomization kustomizev1.Kustomization
+		err = kubeClient.Get(ctx, namespacedName, &kustomization)
+		if err != nil {
+			return err
+		}
+		return exportKs(kustomization)
+	}
+	return nil
+}
+
+func exportKs(kustomization kustomizev1.Kustomization) error {
+	gvk := kustomizev1.GroupVersion.WithKind("Kustomization")
+	export := kustomizev1.Kustomization{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       gvk.Kind,
+			APIVersion: gvk.GroupVersion().String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      kustomization.Name,
+			Namespace: kustomization.Namespace,
+		},
+		Spec: kustomization.Spec,
+	}
+
+	data, err := yaml.Marshal(export)
+	if err != nil {
+		return err
+	}
+
+	fmt.Println("---")
+	fmt.Println(string(data))
+	return nil
+}
diff --git a/cmd/tk/export_source.go b/cmd/tk/export_source.go
new file mode 100644
index 0000000000000000000000000000000000000000..78524a98fbf219551fdf3edf7c683fa611167929
--- /dev/null
+++ b/cmd/tk/export_source.go
@@ -0,0 +1,20 @@
+package main
+
+import (
+	"github.com/spf13/cobra"
+)
+
+var exportSourceCmd = &cobra.Command{
+	Use:   "source",
+	Short: "Export source commands",
+}
+
+var (
+	exportSourceWithCred bool
+)
+
+func init() {
+	exportSourceCmd.PersistentFlags().BoolVar(&exportSourceWithCred, "with-credentials", false, "include credential secrets")
+
+	exportCmd.AddCommand(exportSourceCmd)
+}
diff --git a/cmd/tk/export_source_git.go b/cmd/tk/export_source_git.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd8535d6fab5bbd14d97d233629429cc506c8f8f
--- /dev/null
+++ b/cmd/tk/export_source_git.go
@@ -0,0 +1,146 @@
+package main
+
+import (
+	"context"
+	"fmt"
+
+	sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
+	"github.com/spf13/cobra"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/yaml"
+)
+
+var exportSourceGitCmd = &cobra.Command{
+	Use:   "git [name]",
+	Short: "Export git sources in YAML format",
+	Example: `  # Export all git sources
+  export source git --all > sources.yaml
+
+  # Export a git source including the SSH keys or basic auth credentials
+  export source git my-private-repo --with-credentials > source.yaml
+`,
+	RunE: exportSourceGitCmdRun,
+}
+
+func init() {
+	exportSourceCmd.AddCommand(exportSourceGitCmd)
+}
+
+func exportSourceGitCmdRun(cmd *cobra.Command, args []string) error {
+	if !exportAll && len(args) < 1 {
+		return fmt.Errorf("kustomization name is required")
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), timeout)
+	defer cancel()
+
+	kubeClient, err := utils.kubeClient(kubeconfig)
+	if err != nil {
+		return err
+	}
+
+	if exportAll {
+		var list sourcev1.GitRepositoryList
+		err = kubeClient.List(ctx, &list, client.InNamespace(namespace))
+		if err != nil {
+			return err
+		}
+
+		if len(list.Items) == 0 {
+			logFailure("no source found in %s namespace", namespace)
+			return nil
+		}
+
+		for _, repository := range list.Items {
+			if err := exportGit(repository); err != nil {
+				return err
+			}
+			if exportSourceWithCred {
+				if err := exportGitCredentials(ctx, kubeClient, repository); err != nil {
+					return err
+				}
+			}
+		}
+	} else {
+		name := args[0]
+		namespacedName := types.NamespacedName{
+			Namespace: namespace,
+			Name:      name,
+		}
+		var repository sourcev1.GitRepository
+		err = kubeClient.Get(ctx, namespacedName, &repository)
+		if err != nil {
+			return err
+		}
+		if err := exportGit(repository); err != nil {
+			return err
+		}
+		if exportSourceWithCred {
+			return exportGitCredentials(ctx, kubeClient, repository)
+		}
+	}
+	return nil
+}
+
+func exportGit(source sourcev1.GitRepository) error {
+	gvk := sourcev1.GroupVersion.WithKind("GitRepository")
+	export := sourcev1.GitRepository{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       gvk.Kind,
+			APIVersion: gvk.GroupVersion().String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      source.Name,
+			Namespace: source.Namespace,
+		},
+		Spec: source.Spec,
+	}
+
+	data, err := yaml.Marshal(export)
+	if err != nil {
+		return err
+	}
+
+	fmt.Println("---")
+	fmt.Println(string(data))
+	return nil
+}
+
+func exportGitCredentials(ctx context.Context, kubeClinet client.Client, source sourcev1.GitRepository) error {
+	if source.Spec.SecretRef != nil {
+		namespacedName := types.NamespacedName{
+			Namespace: source.Namespace,
+			Name:      source.Spec.SecretRef.Name,
+		}
+		var cred corev1.Secret
+		err := kubeClinet.Get(ctx, namespacedName, &cred)
+		if err != nil {
+			return fmt.Errorf("get secret failed: %w", err)
+		}
+
+		exported := corev1.Secret{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: "v1",
+				Kind:       "Secret",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      namespacedName.Name,
+				Namespace: namespacedName.Namespace,
+			},
+			Data: cred.Data,
+			Type: cred.Type,
+		}
+
+		data, err := yaml.Marshal(exported)
+		if err != nil {
+			return err
+		}
+
+		fmt.Println("---")
+		fmt.Println(string(data))
+	}
+	return nil
+}
diff --git a/cmd/tk/main.go b/cmd/tk/main.go
index afd97f655be91392bc1737588b34d623b425a504..cedadbd177b92d2ef5a87aa6f51d55cea37c36ce 100644
--- a/cmd/tk/main.go
+++ b/cmd/tk/main.go
@@ -27,14 +27,23 @@ var rootCmd = &cobra.Command{
   tk install --version=master
 
   # Create a source from a public Git repository
-  tk create source git webapp \
+  tk create source git webapp-latest \
     --url=https://github.com/stefanprodan/podinfo \
     --branch=master \
     --interval=3m
 
+  # List git sources and their status
+  tk get sources git
+
+  # Trigger a git sync
+  tk sync source git webapp-latest
+
+  # Export git sources in YAML format
+  tk export source git --all > sources.yaml
+
   # Create a kustomization for deploying a series of microservices
-  tk create kustomization webapp \
-    --source=webapp \
+  tk create kustomization webapp-dev \
+    --source=webapp-latest \
     --path="./deploy/webapp/" \
     --prune="instance=webapp" \
     --generate=true \
@@ -45,7 +54,25 @@ var rootCmd = &cobra.Command{
     --health-check-timeout=2m
 
   # Trigger a git sync and apply changes if any
-  sync kustomization webapp --with-source
+  tk sync kustomization webapp-dev --with-source
+
+  # Suspend a kustomization reconciliation
+  tk suspend kustomization webapp-dev
+
+  # Export kustomizations in YAML format
+  tk export kustomization --all > kustomizations.yaml
+
+  # Resume a kustomization reconciliation
+  tk resume kustomization webapp-dev
+
+  # Delete a kustomization
+  tk delete kustomization webapp-dev
+
+  # Delete a git source
+  tk delete source git webapp-latest
+
+  # Uninstall the toolkit and delete CRDs
+  tk uninstall --crds
 `,
 }
 
diff --git a/cmd/tk/utils.go b/cmd/tk/utils.go
index c5aaad868a7054286d5d2272ad7271265c087ddf..41ae679fb1247ad784f51b0f2072c592ae9c0684 100644
--- a/cmd/tk/utils.go
+++ b/cmd/tk/utils.go
@@ -12,6 +12,7 @@ import (
 
 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
 	sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
+	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/client-go/tools/clientcmd"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -98,6 +99,7 @@ func (*Utils) kubeClient(config string) (client.Client, error) {
 	}
 
 	scheme := runtime.NewScheme()
+	_ = corev1.AddToScheme(scheme)
 	_ = sourcev1.AddToScheme(scheme)
 	_ = kustomizev1.AddToScheme(scheme)
 
diff --git a/go.mod b/go.mod
index e5d8063ab328a5fbb6f599a9ef0d8594f8a900dc..867428c3ee70181fdbc50398afa06e8b3c29a749 100644
--- a/go.mod
+++ b/go.mod
@@ -12,6 +12,7 @@ require (
 	k8s.io/apimachinery v0.18.2
 	k8s.io/client-go v0.18.2
 	sigs.k8s.io/controller-runtime v0.6.0
+	sigs.k8s.io/yaml v1.2.0
 )
 
 // fix AKS auth