{"id":21521043,"url":"https://github.com/kaweezle/krmfnsops","last_synced_at":"2026-05-17T20:03:00.192Z","repository":{"id":39886094,"uuid":"492998549","full_name":"kaweezle/krmfnsops","owner":"kaweezle","description":"KRM function (Kustomize) to decrypt SOPS encoded resources","archived":false,"fork":false,"pushed_at":"2023-03-14T13:04:38.000Z","size":40473,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-04T12:25:27.859Z","etag":null,"topics":["kubernetes","kustomize","kustomize-plugin","sops"],"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/kaweezle.png","metadata":{"files":{"readme":"README.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":"2022-05-16T21:02:08.000Z","updated_at":"2024-05-15T18:45:12.000Z","dependencies_parsed_at":"2024-06-21T08:48:05.119Z","dependency_job_id":"af13c820-f3bc-49bc-a315-b250b1722880","html_url":"https://github.com/kaweezle/krmfnsops","commit_stats":{"total_commits":21,"total_committers":2,"mean_commits":10.5,"dds":0.04761904761904767,"last_synced_commit":"e0e8d89246d9870fe5ad632d7540b7c499ca57ba"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/kaweezle/krmfnsops","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaweezle%2Fkrmfnsops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaweezle%2Fkrmfnsops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaweezle%2Fkrmfnsops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaweezle%2Fkrmfnsops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaweezle","download_url":"https://codeload.github.com/kaweezle/krmfnsops/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaweezle%2Fkrmfnsops/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33153662,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T09:28:26.183Z","status":"ssl_error","status_checked_at":"2026-05-17T09:27:52.702Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["kubernetes","kustomize","kustomize-plugin","sops"],"created_at":"2024-11-24T01:05:32.100Z","updated_at":"2026-05-17T20:03:00.177Z","avatar_url":"https://github.com/kaweezle.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# krmfnsops\n\n[![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta)\n\nkrmfnsops is a\n[kustomize plugin](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/)\nthat you can use to decrypt resources encrypted with\n[SOPS](https://github.com/mozilla/sops). It uses the\n[Exec KRM functions](https://kubectl.docs.kubernetes.io/guides/extending_kustomize/exec_krm_functions/)\nmechanism that is currently cooking both in Kustomize and\n[Kpt](https://kpt.dev/).\n\nAs it embeds SOPS, you **don't need** to install SOPS in addition to krmfnsops.\n\nYou can use it either as a Generator or as a Transformer (see below). To obtain\nthe expected results, you need to run `kustomize` with the following flags:\n\n```console\n\u003e kustomize build . --enable-alpha-plugins --enable-exec\n```\n\n## Use case 1/4: Configuration as a Generator\n\nYou create a `sops-generator.yaml` resource for the generator:\n\n```yaml\n# sops-generator.yaml\napiVersion: kaweezle\n# suffix Generator\nkind: SecretsGenerator\nmetadata:\n  name: whatever\n  annotations:\n    config.kubernetes.io/function: |\n      exec:\n        path: ../dist/krmfnsops_linux_amd64/krmfnsops\nspec:\n  files:\n    - ./secret.enc.yaml\n```\n\nThe files to decrypt are specified in `spec/files`. Then reference the generator\nin the `kustomization.yaml` configuration file:\n\n```yaml\n# kustomization.yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\ngenerators:\n  - sops-generator.yaml\n```\n\n## Use case 2/4: Configuration as a Transformer\n\n**CAUTION** Sops computes a Message authentication code from the source file and\nchecks it after decrypt in order to verify that the encrypted file has not been\nmodified. However, the transformer doesn't receive the original source, but an\nobject representing each resource inside it, modified by kustomize for\nprocessing purposes. In consequence, the MAC verification is **disabled** in\ntransformer mode.\n\nThe following is the configuration for the function in Transformer mode:\n\n```yaml\n# sops-transformer.yaml\napiVersion: kaweezle\n# suffix Transformer\nkind: SecretsTransformer\nmetadata:\n  name: whatever\n  annotations:\n    config.kubernetes.io/function: |\n      exec:\n        path: ../dist/krmfnsops_linux_amd64/krmfnsops\n\n# Note that there is no spec\n```\n\nAnd configure it in your `kustomization.yaml`:\n\n```yaml\n# kustomization.yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Add the encrypted resources\nresources:\n  - ./secret.yaml\n\ntransformers:\n  - sops-transformer.yaml\n```\n\n## Use case 3/4: Configuration as an _In place_ Generator\n\nIn this use case, the generator configuration is the actual resource that needs\nto be added. Let's imagine that you have this secret in your kustomization:\n\n```yaml\n# secret.yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  labels:\n    argocd.argoproj.io/secret-type: repository\n  name: private-repo\n  namespace: argocd\nstringData:\n  password: my-password\n  type: git\n  url: https://github.com/argoproj/private-repo\n  username: my-username\n```\n\nYou want it encrypted. For that, you add the krmfnsops function annotation:\n\n```yaml\nannotations:\n  config.kubernetes.io/function: |\n    exec:\n      path: krmfnsops\n```\n\nand encrypt it with sops:\n\n```console\n\u003e sops -e -i secret.yaml\n```\n\nYou obtain an encrypted version of the secret that can be added _as is_ as a\ngenerator in your kustomization:\n\n```yaml\n# kustomization.yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\ngenerators:\n  - secret.yaml\n```\n\nThe command:\n\n```console\n\u003e kustomize build --enable-alpha-plugins --enable-exec .\n```\n\nwill output the unencrypted secret.\n\n## Use case 4/4: Use an encrypted generator as a source for replacements\n\nIn this use case, we use an encrypted generator that contains all our secrets:\n\n```yaml\n# secrets.yaml\napiVersion: krmfnsops.kaweezle.com/v1alpha1\nkind: Secrets\nmetadata:\n  name: all-my-secrets\n  annotations:\n    # this annotation will keep the resource out of the output\n    krmfnsops.kaweezle.com/keep-local-config: \"true\"\n    # this annotation will perform decryption for us\n    config.kubernetes.io/function: |\n      exec:\n        path: ../../krmfnsops\ndata:\n  github:\n    password: gh_\u003cgithub_token\u003e\n    application_secret: \u003csecret\u003e\n  ovh:\n    consumer_key: \u003csecret\u003e\n    application_secret: \u003csecret\u003e\n```\n\nNote that it contains the function annotation, and a new annotation\n`krmfnsops.kaweezle.com/keep-local-config`. This annotation will make the\nresource available in the kustomization pipeline but will keep it out of the\noutput. This will allow us to use the data of the resource as a source for\nreplacements.\n\nWe encrypt our secrets with the following command:\n\n```console\n\u003e sops -e -i secret.yaml\n```\n\nNow we can have a secret in our kustomization with a fake password:\n\n```yaml\n# secret.yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  labels:\n    argocd.argoproj.io/secret-type: repository\n  name: private-repo\nstringData:\n  password: this-is-a-fake-password\n  type: git\n  url: https://github.com/argoproj/private-repo\n  username: my-username\n```\n\nA make the kustomization replace the fake password with the unencrypted one:\n\n```yaml\n# kustomization.yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\n\n# Add the faked resource\nresources:\n  - secret.yaml\n\n# Add our encypted secrets\ngenerators:\n  - secrets.yaml\n\n# Replace the fake password with te real one\nreplacements:\n  - source:\n      kind: Secrets\n      fieldPath: data.github.password\n    targets:\n      - select:\n          kind: Secret\n          name: private-repo\n        fieldPaths:\n          - stringData.password\n```\n\nNow the kustomization gives:\n\n```console\n❯ kustomize build --enable-alpha-plugins --enable-exec\napiVersion: v1\nkind: Secret\nmetadata:\n  labels:\n    argocd.argoproj.io/secret-type: repository\n  name: private-repo\nstringData:\n  password: gh_\u003cgithub_token\u003e\n  type: git\n  url: https://github.com/argoproj/private-repo\n  username: my-username\n```\n\nThe files are available in `examples/secrets`.\n\n## Installation\n\nWith each [Release](https://github.com/kaweezle/krmfnsops/releases), we provide\nbinaries for most platforms as well as Alpine based packages. Typically, you\nwould install it on linux with the following command:\n\n```console\n\u003e KRMFNSOPS_VERSION=\"v0.1.5\"\n\u003e curl -sLo /usr/local/bin/krmfnsops https://github.com/kaweezle/krmfnsops/releases/download/${KRMFNSOPS_VERSION}/krmfnsops_${KRMFNSOPS_VERSION}_linux_amd64\n```\n\n## Argo CD integration\n\nTo use krmfnsops with Argo CD, you need to:\n\n- Make the `krmfnsops`binary available to the `argo-repo-server` pod.\n- Have Argo CD run kustomize with the `--enable-alpha-plugins --enable-exec`\n  parameters.\n- Make the decrypting keys available to `krmfnsops`.\n\nTo add krmfnsops on argo-repo-server, the\n[Argo CD documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/custom_tools/)\nprovides different methods to make custom tools available.\n\nIf you get serious about Argo CD, you will probably end up cooking your own\nimage. This\n[docker file](https://github.com/antoinemartin/autocloud/blob/deploy/citest/repo-server/Dockerfile#L45)\nshows how to use the above installation instructions in your image. To\nsummarize:\n\n```Dockerfile\nFROM argoproj/argocd:latest\n\nARG KRMFNSOPS_VERSION=v0.1.5\n\n# Switch to root for the ability to perform install\nUSER root\n\n# Install tools\nRUN apt-get update \u0026\u0026 \\\n    apt-get install -y curl \u0026\u0026 \\\n    apt-get clean \u0026\u0026 \\\n    rm -rf /var/lib/apt/lists/* \u0026\u0026 \\\n    curl -sLo /usr/local/bin/krmfnsops https://github.com/kaweezle/krmfnsops/releases/download/${KRMFNSOPS_VERSION}/krmfnsops_${KRMFNSOPS_VERSION}_linux_amd64\n\nUSER argocd\n```\n\nFor the other points, we assume in the following that your Argo CD deployment\noccurs through kustomize. Here is the kustomization file layout:\n\n```console\n.\n├── argocd-cm.yaml\n├── argocd-repo-server-patch.yaml\n├── kustomization.yaml\n├── secrets.yaml\n└── sops-generator.yaml\n```\n\nThe base `kustomization.yaml` contains:\n\n```yaml\n# kustomization.yaml\napiVersion: kustomize.config.k8s.io/v1beta1\nkind: Kustomization\nnamespace: argocd\n\nresources:\n  # The standard Argo CD installation\n  - https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml\n\ngenerators:\n  # This generator will generate the secret containing our AGE key\n  - sops-generator.yaml\n\n# Kustomization of the Argo CD standard installation\npatches:\n  - path: argocd-repo-server-patch.yaml\n    target:\n      kind: Deployment\n      name: argocd-repo-server\n  - path: argocd-cm.yaml\n```\n\nThe `argocd-cm.yaml` patch contains the configuration needed for the parameters:\n\n```yaml\n# argocd-cm.yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: argocd-cm\ndata:\n  # Options to enable exec plugins (krmfnsops).\n  kustomize.buildOptions: \"--enable-alpha-plugins --enable-exec\"\n  ...\n```\n\nThe `sops-generator.yaml` file will allow decrypting our secrets on deployment:\n\n```yaml\n# sops-generator.yaml\napiVersion: iknite.krm.kaweezle.com/v1beta1\nkind: SopsGenerator\nmetadata:\n  name: secrets\n  annotations:\n    config.kubernetes.io/function: |\n      exec:\n        path: krmfnsops\nspec:\n  files:\n    - ./secrets.yaml\n```\n\nThe `secrets.yaml` file is a SOPS encrypted file containing all the secrets\nneeded by Argo CD, including the key used by krmfnsops on the server.\n\nWe will use here an [Age](https://github.com/FiloSottile/age) key as an example.\nThe key is generated and exported as a base64 payload with the following:\n\n```console\n\u003e mkdir -p ~/.config/sops/age \u0026\u0026 age-keygen -o ~/.config/sops/age/keys.txt\n\u003e cat ~/.config/sops/age/keys.txt | openssl base64 -e -A\n\u003cbase64 encoded key\u003e\n```\n\nThen it's added it to the `secrets.yaml` file:\n\n```yaml\n# secrets.yaml\n# In addition, this file would contain:\n# - The git credentials to access private repositories\n# - The admin password\n# - The external OIDC identification credentials (client secret, ...)\n# ...\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  name: argocd-sops-private-keys\ntype: Opaque\ndata:\n  keys.txt: \u003cbase64 encoded key\u003e\n```\n\nIt is encrypted with the following command:\n\n```console\n\u003e export SOPS_AGE_RECIPIENTS=$(cat ~/.config/sops/age/keys.txt | age-keygen -y)\n\u003e sops -e -i secrets.yaml\n```\n\nThe file now contains encrypted entries:\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n    name: argocd-sops-private-keys\ntype: Opaque\ndata:\n    age_key.txt: ENC[AES256_GCM,data:xbP4U...,type:str]\nsops:\n    age:\n        - recipient: age1...\n          enc: | ...\n    kms: []\n```\n\n⚠️ To keep the encrypted entries to a minimum, add a `.sops.yaml` file to your\nproject with the following:\n\n```yaml\ncreation_rules:\n  - encrypted_regex: \"^(data|stringData)$\"\n    # You can put your age key here (obtain it with cat ~/.config/sops/age/keys.txt| age-keygen -y)\n    # age: age1..\n```\n\nNow that the secret is configured, making it available for the argocd-repo-sever\nis done with the `argocd-repo-server-patch.yaml` patch file:\n\n```yaml\n# argocd-repo-server-patch.yaml\n# Use custom image\n- op: replace\n  path: /spec/template/spec/containers/0/image\n  value: \u003cyour custom image\u003e\n# Add sops secrets volume\n- op: add\n  path: /spec/template/spec/volumes/-\n  value:\n    name: argocd-sops-private-keys\n    secret:\n      secretName: argocd-sops-private-keys\n      optional: true\n      defaultMode: 420\n# Mount volume on server\n- op: add\n  path: /spec/template/spec/containers/0/volumeMounts/-\n  value:\n    mountPath: /home/argocd/.config/sops/age\n    name: argocd-sops-private-keys\n```\n\nDeploy Argo CD with:\n\n```console\n\u003e kustomize build --enable-alpha-plugins --enable-exec . | kubectl apply -f\n```\n\n## Similar projects\n\n- [viaduct-ai/kustomize-sops](https://github.com/viaduct-ai/kustomize-sops)\n- [goabout/kustomize-sopssecretgenerator](https://github.com/goabout/kustomize-sopssecretgenerator)\n  that also contains a more complete list of\n  [other alternatives](https://github.com/goabout/kustomize-sopssecretgenerator#alternatives).\n\n```\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaweezle%2Fkrmfnsops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaweezle%2Fkrmfnsops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaweezle%2Fkrmfnsops/lists"}