{"id":13645073,"url":"https://github.com/viaduct-ai/kustomize-sops","last_synced_at":"2025-10-21T04:52:35.962Z","repository":{"id":38751740,"uuid":"217334716","full_name":"viaduct-ai/kustomize-sops","owner":"viaduct-ai","description":"KSOPS - A Flexible Kustomize Plugin for SOPS Encrypted Resources","archived":false,"fork":false,"pushed_at":"2025-03-21T22:14:21.000Z","size":597,"stargazers_count":691,"open_issues_count":25,"forks_count":87,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-07T05:35:58.681Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viaduct-ai.png","metadata":{"files":{"readme":"README-legacy.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-24T15:41:14.000Z","updated_at":"2025-04-04T19:12:06.000Z","dependencies_parsed_at":"2023-09-28T17:06:58.611Z","dependency_job_id":"2f8576e0-6dd3-48fd-8a7f-ecb73f976da5","html_url":"https://github.com/viaduct-ai/kustomize-sops","commit_stats":null,"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viaduct-ai%2Fkustomize-sops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viaduct-ai%2Fkustomize-sops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viaduct-ai%2Fkustomize-sops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viaduct-ai%2Fkustomize-sops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viaduct-ai","download_url":"https://codeload.github.com/viaduct-ai/kustomize-sops/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250064679,"owners_count":21368948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T01:02:25.569Z","updated_at":"2025-10-21T04:52:30.903Z","avatar_url":"https://github.com/viaduct-ai.png","language":"Go","funding_links":[],"categories":["Go","Plugins","Secret Management"],"sub_categories":["Generators"],"readme":"# KSOPS - A Flexible Kustomize Plugin for SOPS Encrypted Resources\n\n![Tests and Build](https://github.com/viaduct-ai/kustomize-sops/workflows/Run%20Tests%20and%20Build/badge.svg?branch=master)\n\n- [Background](#background)\n- [Overview](#overview)\n- [Requirements](#requirements)\n- [Installation Options](#installation-options)\n- [Getting Started](#getting-started)\n- [Generator Options](#generator-options)\n- [Development and Testing](#development-and-testing)\n- [Argo CD Integration 🤖](#argo-cd-integration-)\n\n## Background\n\nAt [Viaduct](https://www.viaduct.ai/), we manage our Kubernetes resources via the [GitOps](https://www.weave.works/blog/gitops-operations-by-pull-request) pattern; however, we could not find a solution compatible with our stack for managing secrets via the GitOps paradigm. We built `KSOPS` to connect [kustomize](https://github.com/kubernetes-sigs/kustomize/) to [SOPS](https://github.com/mozilla/sops) and integrated it with [Argo CD](https://github.com/argoproj/argo-cd) to safely manage our secrets the same way we manage the rest our Kubernetes manifest.\n\n## Overview\n\n`KSOPS`, or kustomize-SOPS, is a [kustomize](https://github.com/kubernetes-sigs/kustomize/) [exec plugin](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins) for SOPS encrypted resources. `KSOPS` can be used to decrypt any Kubernetes resource, but is most commonly used to decrypt encrypted Kubernetes Secrets and ConfigMaps. As a [kustomize](https://github.com/kubernetes-sigs/kustomize/) plugin, `KSOPS` allows you to manage, build, and apply encrypted manifests the same way you manage the rest of your Kubernetes manifests.\n\n## Requirements\n\n- [kustomize](https://github.com/kubernetes-sigs/kustomize/)\n- `XDG_CONFIG_HOME` environment variable is set in your shell. If it's not set, run the following\n\n```bash\n# Don't forget to define XDG_CONFIG_HOME in your .bashrc or .zshrc\necho \"export XDG_CONFIG_HOME=\\$HOME/.config\" \u003e\u003e $HOME/.zshrc\nsource $HOME/.zshrc\n```\n\n## Installation\n\n### Install the Latest Release\n\nUsing curl\n\n```bash\n# Verify the $XDG_CONFIG_HOME environment variable exists then run\ncurl -s https://raw.githubusercontent.com/viaduct-ai/kustomize-sops/master/scripts/install-legacy-ksops-archive.sh | bash\n```\n\nOr using wget\n\n```bash\n# Verify the $XDG_CONFIG_HOME environment variable exists then run\nwget -qcO - https://raw.githubusercontent.com/viaduct-ai/kustomize-sops/master/scripts/install-legacy-ksops-archive.sh | bash\n```\n\n### Install from Source\n\n```bash\n# Optionally, install kustomize via\n# make kustomize\n# Verify the $XDG_CONFIG_HOME environment variable exists then run\nmake install\n```\n\n## Getting Started (Tutorial)\n\n### 0. Verify Requirements\n\nBefore continuing, verify your installation of [kustomize](https://github.com/kubernetes-sigs/kustomize/)\nand `gpg`. Below are a few non-comprehensive commands to quickly check your installations:\n\n```bash\n# Verify kustomize is installed\nkustomize version\n\n# Verify gpg is installed\ngpg --help\n\n# Verify XDG_CONFIG_HOME environment variable is set\necho $XDG_CONFIG_HOME\n```\n\n### 1. Download and install KSOPS\n\n```bash\n# Verify the $XDG_CONFIG_HOME environment variable exists then run\nsource \u003c(curl -s https://raw.githubusercontent.com/viaduct-ai/kustomize-sops/master/scripts/install-legacy-ksops-archive.sh)\n```\n\n### 2. Import Test PGP Keys\n\nTo simplify local development and testing, we use PGP test keys. To import the keys, run the following command from the repository's root directory:\n\n```bash\nmake import-test-keys\n```\n\nIf you are following this tutorial, be sure to run this before the following steps. The PGP keys will also be imported when you run `make test`\n\nSee [SOPS](https://github.com/mozilla/sops) for details.\n\n### 3. Configure SOPS via .sops.yaml\n\nFor this example and testing, `KSOPS` relies on the `SOPS` creation rules defined in `.sops.yaml`. To make encrypted secrets more readable, we suggest using the following encryption regex to only encrypt `data` and `stringData` values. This leaves non-sensitive fields, like the secret's name, unencrypted and human readable.\n\n**Note:** You only have to modify `.sops.yaml` if you want to use your key management service in this example instead of the default PGP key imported in the previous step.\n\n```yaml\ncreation_rules:\n  - unencrypted_regex: \"^(apiVersion|metadata|kind|type)$\"\n    # Specify kms/pgp/etc encryption key\n    # This tutorial uses a local PGP key for encryption.\n    # DO NOT USE IN PRODUCTION ENV\n    pgp: \"FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4\"\n    # Optionally you can configure to use a providers key store\n    # kms: XXXXXX\n    # gcp_kms: XXXXXX\n```\n\n### 4. Create a Resource\n\n```bash\n# Create a local Kubernetes Secret\ncat \u003c\u003cEOF \u003e secret.yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: mysecret\ntype: Opaque\ndata:\n  username: YWRtaW4=\n  password: MWYyZDFlMmU2N2Rm\nEOF\n```\n\n### 5. Encrypt the Resources\n\n```bash\n# Encrypt with SOPS CLI\n# Specify SOPS configuration in .sops.yaml\nsops -e secret.yaml \u003e secret.enc.yaml\n```\n\n### 6. Define KSOPS kustomize Generator\n\n```bash\n# Create a local Kubernetes Secret\ncat \u003c\u003cEOF \u003e secret-generator.yaml\napiVersion: viaduct.ai/v1\nkind: ksops\nmetadata:\n  # Specify a name\n  name: example-secret-generator\nfiles:\n  - ./secret.enc.yaml\nEOF\n```\n\n### 7. Create the kustomization.yaml\n\n[Read about kustomize plugins](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins/)\n\n```bash\ncat \u003c\u003cEOF \u003e kustomization.yaml\ngenerators:\n  - ./secret-generator.yaml\nEOF\n```\n\n### 8. Build with kustomize 🔑\n\n```bash\n# Build with kustomize to verify\n# In kustomize v2 and v3 the command is\n# kustomize build --enable_alpha_plugins .\nkustomize build --enable-alpha-plugins .\n```\n\n### Troubleshooting\n\n#### Sanity Checks\n\n- Validate `ksops` is in the `kustomize` plugin path\n  - `$XDG_CONFIG_HOME/kustomize/plugin/viaduct.ai/v1/ksops/ksops`\n\n#### Check Existing Issues\n\nSomeone might have already encountered your issue.\n\nhttps://github.com/viaduct-ai/kustomize-sops/issues\n\n## Generate secret directly from encrypted files\n\n`KSOPS` can also generate a Kubernetes Secret directly from encrypted files or dotenv files.\n\n```bash\n# Create a Kubernetes Secret from encrypted file\ncat \u003c\u003cEOF \u003e secret-generator.yaml\napiVersion: viaduct.ai/v1\nkind: ksops\nmetadata:\n  name: example-secret-generator\nsecretFrom:\n- metadata:\n    name: secret-name\n    labels:\n      app: foo\n    annotations:\n      kustomize.config.k8s.io/needs-hash: \"false\"\n  type: Opaque\n  files:\n  - ./secret.enc.conf\n  - secret.yaml=./secret.enc.yaml\nEOF\n```\n\n```bash\n# Create a Kubernetes Secret from encrypted dotenv file\ncat \u003c\u003cEOF \u003e secret-generator.yaml\napiVersion: viaduct.ai/v1\nkind: ksops\nmetadata:\n  name: example-secret-generator\nsecretFrom:\n- metadata:\n    name: secret-name\n  envs:\n  - ./secret.enc.env\nEOF\n```\n\n## Generator Options\n\n`KSOPS` supports [kustomize exec plugins](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins/#generator-options) annotation based generator options. At the time of writing, the supported annotations are:\n\n- `kustomize.config.k8s.io/needs-hash`\n- `kustomize.config.k8s.io/behavior`\n\nFor information, read the [kustomize generator options documentation](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/generatorOptions.md).\n\n### Encrypted Secret Overlays w/ Generator Options\n\nSometimes there is a default secret as part of a project's base manifests, like the [base Argo CD secret](https://github.com/argoproj/argo-cd/blob/master/manifests/base/config/argocd-secret.yaml), which you want to `replace` in your overlay. Other times, you have parts of base secret that are common across different overlays but you want to partially update, or `merge`, changes specific to each overlay as well. You can achieve both of these goals by simply adding the following annotations to your encrypted secrets:\n\n#### Replace a Base Secret\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: argocd-secret\n  annotations:\n    # replace the base secret data/stringData values with these encrypted data/stringData values\n    kustomize.config.k8s.io/behavior: replace\ntype: Opaque\ndata:\n  # Encrypted data here\nstringData:\n  # Encrypted data here\n```\n\n#### Merge/Patch a Base Secret\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: argocd-secret\n  annotations:\n    # merge the base secret data/stringData values with these encrypted data/stringData values\n    kustomize.config.k8s.io/behavior: merge\ntype: Opaque\ndata:\n  # Encrypted data here\nstringData:\n  # Encrypted data here\n```\n\n## Development and Testing\n\nBefore developing or testing `KSOPS`, ensure all external [requirements](#requirements) are properly installed.\n\n```bash\n# Setup development environment\nmake setup\n```\n\n### Development\n\n`KSOPS` implements the [kustomize](https://github.com/kubernetes-sigs/kustomize/) plugin API in `ksops.go`.\n\n`KSOPS`'s logic is intentionally simple. Given a list of SOPS encrypted Kubernetes manifests, it iterates over each file and decrypts it via SOPS [decrypt](https://godoc.org/go.mozilla.org/sops/decrypt) library. `KSOPS` assumes nothing about the structure of the encrypted resource and relies on [kustomize](https://github.com/kubernetes-sigs/kustomize/) for manifest validation. `KSOPS` expects the encryption key to be accessible. This is important to consider when using `KSOPS` for CI/CD.\n\n### Testing\n\nTesting `KSOPS` requires:\n\nEverything is handled for you by `make test`. Just run it from the repo's root directory:\n\n```bash\nmake test\n```\n\n## Migration from KSOPS v2.x.x to v3.x.x\n\n### Required Changes\n\n- The opt-in `ksops-exec` kind is deprecated. If you are using the `ksops-exec` kind, please migrate to `ksops` once you've upgrade to _v3.x.x_.\n\n### Background\n\nIn `KSOPS` _v3.x.x_, the kustomize plugin `ksops` was migrated to an [exec plugin](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins) from a [Go plugin](https://kubernetes-sigs.github.io/kustomize/guides/plugins/#go-plugins) because of simpler installation, dependency management, and package maintenance.\n\n`KSOPS` was originally developed as a [kustomize Go plugin](https://kubernetes-sigs.github.io/kustomize/guides/plugins/#go-plugins). Up until _v2.2.0_ this was the only installation option, but in _v2.2.0_, `KSOPS` introduced an opt-in [exec plugin](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins) under via the `ksops-exec` kind. Now that `KSOPS` is only an [exec plugin](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_plugins), the `ksops-exec` kind is deprecated.\n\n## Argo CD Integration 🤖\n\n`KSOPS` becomes even more powerful when integrated with a CI/CD pipeline. By combining `KSOPS` with [Argo CD](https://github.com/argoproj/argo-cd/), you can manage Kubernetes secrets via the same Git Ops pattern you use to manage the rest of your kubernetes manifests. To integrate `KSOPS` and [Argo CD](https://github.com/argoproj/argo-cd/), you will need to update the Argo CD ConifgMap and create a [strategic merge patch](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md) or a [custom Argo CD build](https://argoproj.github.io/argo-cd/operator-manual/custom_tools/#byoi-build-your-own-image). As an alternative you can also use the [Argo CD Helm Chart](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd) with [custom values](#argo-cd-helm-chart-with-custom-tooling). Don't forget to inject any necessary credentials (i.e AWS credentials) when deploying the [Argo CD](https://github.com/argoproj/argo-cd/) + `KSOPS` build!\n\n[KSOPS Docker Image](https://hub.docker.com/r/viaductoss/ksops)\n\n[KSOPS Quay.io Image](https://quay.io/repository/viaductoss/ksops)\n\n### Enable Kustomize Plugins via Argo CD ConfigMap\n\nAs of now to allow [Argo CD](https://github.com/argoproj/argo-cd/) to use [kustomize](https://github.com/kubernetes-sigs/kustomize/) plugins you must use the `enable-alpha-plugins` flag. This is configured by the `kustomize.buildOptions` setting in the [Argo CD](https://github.com/argoproj/argo-cd/) ConfigMap\n\n```yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: argocd-cm\n  labels:\n    app.kubernetes.io/name: argocd-cm\n    app.kubernetes.io/part-of: argocd\ndata:\n  # For KSOPs versions \u003c v2.5.0, use the old kustomize flag style\n  # kustomize.buildOptions: \"--enable_alpha_plugins\"\n  kustomize.buildOptions: \"--enable-alpha-plugins\"\n```\n\n### KSOPS Repo Sever Patch\n\nThe simplest way to integrate `KSOPS` with [Argo CD](https://github.com/argoproj/argo-cd/) is with a [strategic merge patch](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md) on the Argo CD repo server deployment. The patch below uses an init container to build `KSOPS` and volume mount to inject the `KSOPS` plugin and, optionally, override the [kustomize](https://github.com/kubernetes-sigs/kustomize/) executable.\n\n```yaml\n# argo-cd-repo-server-ksops-patch.yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: argocd-repo-server\nspec:\n  template:\n    spec:\n      # 1. Define an emptyDir volume which will hold the custom binaries\n      volumes:\n        - name: custom-tools\n          emptyDir: {}\n      # 2. Use an init container to download/copy custom binaries into the emptyDir\n      initContainers:\n        - name: install-ksops\n          image: viaductoss/ksops:v3.1.0\n          command: [\"/bin/sh\", \"-c\"]\n          args:\n            - echo \"Installing KSOPS...\";\n              mv ksops /custom-tools/;\n              mv $GOPATH/bin/kustomize /custom-tools/;\n              echo \"Done.\";\n          volumeMounts:\n            - mountPath: /custom-tools\n              name: custom-tools\n      # 3. Volume mount the custom binary to the bin directory (overriding the existing version)\n      containers:\n        - name: argocd-repo-server\n          volumeMounts:\n            - mountPath: /usr/local/bin/kustomize\n              name: custom-tools\n              subPath: kustomize\n              # Verify this matches a XDG_CONFIG_HOME=/.config env variable\n            - mountPath: /.config/kustomize/plugin/viaduct.ai/v1/ksops/ksops\n              name: custom-tools\n              subPath: ksops\n          # 4. Set the XDG_CONFIG_HOME env variable to allow kustomize to detect the plugin\n          env:\n            - name: XDG_CONFIG_HOME\n              value: /.config\n        ## If you use AWS or GCP KMS, don't forget to include the necessary credentials to decrypt the secrets!\n        #  - name: AWS_ACCESS_KEY_ID\n        #    valueFrom:\n        #      secretKeyRef:\n        #        name: argocd-aws-credentials\n        #        key: accesskey\n        #  - name: AWS_SECRET_ACCESS_KEY\n        #    valueFrom:\n        #      secretKeyRef:\n        #        name: argocd-aws-credentials\n        #        key: secretkey\n```\n\n### Custom Argo CD w/ KSOPS Dockerfile\n\nAlternatively, for more control and faster pod start times you can build a custom docker image.\n\n```Dockerfile\nARG ARGO_CD_VERSION=\"v1.7.7\"\n# https://github.com/argoproj/argo-cd/blob/master/Dockerfile\nARG KSOPS_VERSION=\"v3.1.0\"\n\n#--------------------------------------------#\n#--------Build KSOPS and Kustomize-----------#\n#--------------------------------------------#\n\nFROM viaductoss/ksops:$KSOPS_VERSION as ksops-builder\n\n#--------------------------------------------#\n#--------Build Custom Argo Image-------------#\n#--------------------------------------------#\n\nFROM argoproj/argocd:$ARGO_CD_VERSION\n\n# Switch to root for the ability to perform install\nUSER root\n\n# Set the kustomize home directory\nENV XDG_CONFIG_HOME=$HOME/.config\nENV KUSTOMIZE_PLUGIN_PATH=$XDG_CONFIG_HOME/kustomize/plugin/\n\nARG PKG_NAME=ksops\n\n# Override the default kustomize executable with the Go built version\nCOPY --from=ksops-builder /go/bin/kustomize /usr/local/bin/kustomize\n\n# Copy the plugin to kustomize plugin path\nCOPY --from=ksops-builder /go/bin/ksops  $KUSTOMIZE_PLUGIN_PATH/viaduct.ai/v1/${PKG_NAME}/\n\n# Switch back to non-root user\nUSER argocd\n```\n\n### Argo CD Helm Chart with Custom Tooling\n\nWe can setup `KSOPS` custom tooling in the [Argo CD Chart](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd) with the following values:\n\n```yaml\n# Enable Kustomize Alpha Plugins via Argo CD ConfigMap, required for ksops\nserver:\n  config:\n    kustomize.buildOptions: \"--enable-alpha-plugins\"\n\nrepoServer:\n  # Set the XDG_CONFIG_HOME env variable to allow kustomize to detect the plugin\n  env:\n    - name: XDG_CONFIG_HOME\n      value: /.config\n\n  # Use init containers to configure custom tooling\n  # https://argoproj.github.io/argo-cd/operator-manual/custom_tools/\n  volumes:\n    - name: custom-tools\n      emptyDir: {}\n\n  initContainers:\n    - name: install-ksops\n      image: viaductoss/ksops:v3.1.0\n      command: [\"/bin/sh\", \"-c\"]\n      args:\n        - echo \"Installing KSOPS...\";\n          mv ksops /custom-tools/;\n          mv $GOPATH/bin/kustomize /custom-tools/;\n          echo \"Done.\";\n      volumeMounts:\n        - mountPath: /custom-tools\n          name: custom-tools\n  volumeMounts:\n    - mountPath: /usr/local/bin/kustomize\n      name: custom-tools\n      subPath: kustomize\n      # Verify this matches a XDG_CONFIG_HOME=/.config env variable\n    - mountPath: /.config/kustomize/plugin/viaduct.ai/v1/ksops/ksops\n      name: custom-tools\n      subPath: ksops\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviaduct-ai%2Fkustomize-sops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviaduct-ai%2Fkustomize-sops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviaduct-ai%2Fkustomize-sops/lists"}