# Airshipctl Secret Encryption Lifecycle Management > This is an active work in progress and the documentation below will be subject to changes ## Current Status of this implementation - [x] [Design documentation and review](https://docs.google.com/document/d/1EjiCuXoiy8DEEXe15KxVJ4iWrwogCyG113_0LdzcWzQ/edit?usp=drive_web&ouid=102644738301620637153) - [x] [Proof of concept implementation](https://review.opendev.org/#/c/742695/) - [x] [Proof of concept demo](https://drive.google.com/file/d/1IBYROqkLnQHAVpc2vu-Ipo6E4Bq8o52g/view?usp=sharing) - [x] [Adding encryption config to airshipctl config](https://review.opendev.org/#/c/749892/) - [x] [Airshipctl commands to get and set encryption configs](https://review.opendev.org/#/c/751068/) - [x] [Airshipctl secret encrypt and decrypt subcommands](https://review.opendev.org/#/c/751869/) - [x] [Airshipctl encrypt and decrypt using Sops](https://review.opendev.org/#/c/750604/) - [x] [Airshipctl sops plugin for decryption](https://review.opendev.org/#/c/750613/) ## Setup for encrypt/decrypt demo The current implementation of this feature allows the operator to encrypt and decrypt secrets using the airshipctl secret subcommand. ### Step 1: Setup airshipctl locally ```bash= ➜ git clone https://github.com/airshipit/airshipctl ➜ cd airshipctl ➜ git:(master) ✗ git fetch https://review.opendev.org/airship/airshipctl refs/changes/04/750604/8 && git checkout FETCH_HEAD ➜ git:(master) ✗ export GOBIN=$PWD ➜ git:(master) ✗ go install ./ ``` ### Step 2: Verify new subcommands exist Verify the new `get-encryption-config` and `set-encryption-config` subcommands exist in `airshipctl config` command ```bash= ➜ airshipctl git:(c904f3f) ✗ ./airshipctl config Manage the airshipctl config file Usage: airshipctl config [command] Available Commands: get-context Get context information from the airshipctl config get-encryption-config Get an encryption config information from the airshipctl config get-management-config View a management config or all management configs defined in the airshipctl config get-manifest Get a manifest information from the airshipctl config init Generate initial configuration files for airshipctl set-context Manage contexts set-encryption-config Manage encryption configs in airship config set-management-config Modify an out-of-band management configuration set-manifest Manage manifests in airship config use-context Switch to a different context Flags: -h, --help help for config Global Flags: --airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config") --debug enable verbose output --kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig") Use "airshipctl config [command] --help" for more information about a command. ``` Verify the new `encrypt` and `decrypt` subcommands exist in `airshipctl secret` command ```bash= ➜ airshipctl git:(h4) ✗ ./airshipctl secret -h Manage secrets Usage: airshipctl secret [command] Available Commands: decrypt Decrypt encrypted yaml files into plaintext files representing Kubernetes objects consisting of sensitive data. encrypt Encrypt plain text yaml files representing Kubernetes objects consisting of sensitive configuration. generate Generate various secrets Flags: -h, --help help for secret Global Flags: --airshipconf string Path to file for airshipctl configuration. (default "$HOME/.airship/config") --debug enable verbose output --kubeconfig string Path to kubeconfig associated with airshipctl configuration. (default "$HOME/.airship/kubeconfig") Use "airshipctl secret [command] --help" for more information about a command. ``` ### Step 4: Generate local gpg keys for encryption We will use the gnu gpg implementation that is available as a CLI to generate a key in the local vault and then export the private key and public key into local files. > Make sure to not set any passphrase when the gpg cli prompts for it. The current implementation of gpg does not allow passing a passphrase programmatically and hence airship wont be able to use any keys that were generated using passphrases ```bash= # Generate a local gpg key pair that will be used for encryption and decryption ➜ gpg --gen-key pub rsa2048 2020-08-18 [SC] [expires: 2022-08-18] D15BD522C22855EFE6055A20BFD406778973BDBA uid Docker <Docker@cluster.local> sub rsa2048 2020-08-18 [E] [expires: 2022-08-18] # Export the key pair into a private and public key, to be passed to airshipctl ➜ gpg --export-secret-keys D15BD522C22855EFE6055A20BFD406778973BDBA > private-key ➜ gpg --armor --export D15BD522C22855EFE6055A20BFD406778973BDBA > public-key # Export the key pair into a private and public key, to be passed to airshipctl ➜ ./airshipctl config set-encryption-config dockertest-1 --decryption-key-path $PWD/private-key --encryption-key-path $PWD/public-key # Set the current context to use the new encryption config ➜ ./airshipctl config set-context kind-clusterapi --encryption-config dockertest-1 ``` ### Step 5: Set encryption config to use local gpg key You can now set the encryption config or your current context to point at the local public/private key files, that would later be used for encrypting and decrypting secrets ```bash= # Export the key pair into a private and public key, to be passed to airshipctl ➜ ./airshipctl config set-encryption-config dockertest-1 --decryption-key-path $PWD/private-key --encryption-key-path $PWD/public-key # Set the current context to use the new encryption config ➜ ./airshipctl config set-context kind-clusterapi --encryption-config dockertest-1 # Verify existing encryption configs and current context ➜ ./airshipctl config get-encryption-config decryptionKeyPath: /Users/uday/go/src/github.com/airshipit/airshipctl/private-key encryptionKeyPath: /Users/uday/go/src/github.com/airshipit/airshipctl/public-key ➜ ./airshipctl config get-context Context: kind-clusterapi contextKubeconf: kind-clusterapi_target encryptionConfig: dockertest-1 manifest: default ``` ## Local Demonstration of Secret Encryption ### Secret and non-secret yaml files setup Ensure the following files are setup: ```yaml= # secret.yaml apiVersion: v1 kind: Secret metadata: name: test-secret annotations: airshipit.org/encrypt: "true" data: username: bXktYXBw password: Mzk1MjgkdmRnN0pi ``` You can now run the encrypt command to encrypt this file to a destination file ```bash= ➜ ./airshipctl secret encrypt --src ./secret.yaml --dst ./secret-encrypted.yaml ``` If you `cat` the `secret-encrypted.yaml` file, you should see the secret contents being encrypted and also see some sops metadata. You can also run a `decrypt` command to decrypt this into a plaintext file. ```bash= ➜ ./airshipctl secret encrypt --dst ./secret-plaintext.yaml --src ./secret-encrypted.yaml ``` Besides secrets, you can encrypt other kinds of Kubernetes objects. See an example of a helm-release being encrypted below: ```yaml= apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - pass1 - pass2 ``` After encryption, the destination file would look something like the following, encrypting only the passwords field and not others: ```yaml= apiVersion: v1 kind: Secret metadata: name: test-secret annotations: airshipit.org/encrypt: "true" data: username: ENC[AES256_GCM,data:K7fYO/qqPB4=,iv:+Z0bF+GBhfZKjQEaUSxF+dRPmzJOStvOxgfUvLaZh40=,tag:emgLKQHCQMQlh80nDYy0rA==,type:str] password: ENC[AES256_GCM,data:l5NqxL6fI9raC2UBFj9lfw==,iv:E27YkDx69inS99iZ3NMKDLj+x9nMm4UGQVj5Jz532iw=,tag:ehsl/eOHryv0mpbglzW56g==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] lastmodified: '2020-10-15T19:47:57Z' mac: ENC[AES256_GCM,data:wmtf3NEdN2ye3LoX9Do/LaYNjFz7AWZ20EF3ZrvZ7BMHS+eAQsgiR3aofVPYnHLO0wWbMxspW+8Ck6XwhO+PMzvDps93cCTV1RUoyxGYkU6yAtl4BRwtfjoLSJN5eYet/FrY5npdYBNRFd68AC/JxuYb56/z2HqqCS5d1xA/Trc=,iv:ix2HOi2B18uhq73M/nu6TnvenKpfLsZr72HGmJe+VAI=,tag:3RPbzK0CuTQU/8lwj3+Tmg==,type:str] pgp: - created_at: '2020-10-15T19:47:57Z' enc: | -----BEGIN PGP MESSAGE----- hQEMA94v/8CA+lyiAQgAtVT7cakD8KJWF7mbC4KC8G4/DxsWHlc1uDQ0iKVop/z6 zav6zO2ngxJYL+V91zMsjmzeGHTJKprUMPHoPVbrLBoAXZRWo6OhBfucAejpZ3fr Xtu10IfOb1BYUzjzcLMyL5utQAOfSu0zq8fbImVTwYhGywP6iBRzGxSwQLzbEqF9 vSEEEM94LL5eernREU+3LfxjUBf3vH/Iw0XHiCIhzlWfGqeDTcbslOksnnIEMciG +DlnZZgur3C6Ob5XLi1lppm3epmuoy5kMcfixdTLLC0rNBH2W5G7GzD77NYAI57I 3lppWV2jhiZfPlIofcIXcjgnS2+4X0IWupCL4scpmtJeAWRh1qv45JbuChDtAMpS G8ziq7uMFObfk3RyVHExr1pc5DvRc4Ue6Bb36T+1zRVHgp5f33Ydut3hdwgXyXjT Xhbk2VzMx6zDDnJVXGAz2dIu5G48yiN4Y9r5QoBnwA== =GpcQ -----END PGP MESSAGE----- fp: 382C4220D8CB1003455A6E0EB36A79B39FD6F3C3 encrypted_regex: ^data version: 3.6.0 ``` ### Encrypt the entire site ```bash= --dst string Path to the file or directory that has encrypted secrets for decryption. Defaults to src. -h, --help help for encrypt --src string Path to the file or directory that has secrets in plaintext that need to be encrypted. Defaults to the manifest location in airship config ``` As you can see from the `airshipctl secret encrypt -h` output, `--src` is optional for the encrypt and decrypt commands. It defaults to the `target_path/metadata_phase_path` if you do not pass the `-src`, there by allowing operators to enrypt an entire phase. See the following demo: ```bash= ➜ airshipctl git:(h4) ✗ mkdir -p exampleTargetPath/phasePath ➜ airshipctl git:(h4) ✗ cat <<EOF > exampleTargetPath/encryptedPhasePath/secret.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - pass1 - pass2 EOF # create a metadata file pointing at the current location for phase path ➜ airshipctl git:(h4) ✗ cat <<EOF > exampleTargetPath/phasePath/metadata.yaml inventory: path: "" phase: path: "phasePath" EOF # create a directory to store the encrypted files ➜ airshipctl git:(h4) ✗ mkdir -p exampleTargetPath/encryptedPhasePath # set the current manifest location to point at the corresponding target path and metadata path ➜ airshipctl git:(h4) ✗ airshipctl config set-manifest default --target-path ${PWD}/exampleTargetPath --metadata-path phasePath/metadata.yaml ➜ airshipctl git:(h4) ✗ airshipctl config get-Context: kind-clusterapi contextKubeconf: kind-clusterapi_target encryptionConfig: dockertest-1 managementConfiguration: "" manifest: default ➜ airshipctl git:(h4) ✗ airshipctl config get-manifests metadataPath: phasePath/metadata.yaml primaryRepositoryName: primary repositories: primary: checkout: branch: master commitHash: "" force: false tag: "" url: https://opendev.org/airship/treasuremap subPath: demo-manifests targetPath: /Users/uday/workspace/patchsets2/airshipctl/exampleTargetPath # you are now ready to call the encrypt command ➜ airshipctl git:(h4) ✗ ./airshipctl secret encrypt --dst exampleTargetPath/encryptedPhasePath # check the output of the encrypt command ➜ airshipctl git:(h4) ✗ cat exampleTargetPath/encryptedPhasePath/secret.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - ENC[AES256_GCM,data:a8xuOa8=,iv:RA2iQMRfQUTNkg8uzDCfg1ymrPZOpHqRvi9qqC6Cwd0=,tag:Ef6qiSDlrumUyuyr4MHGQw==,type:str] - ENC[AES256_GCM,data:faJeQBQ=,iv:vP4rvF/p387EB034QNFfTc3tJ84wMo7LN1JkJZjo0MY=,tag:hdbQJUmS2oHEkwD6SnTTLw==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] lastmodified: '2020-10-16T06:47:07Z' mac: ENC[AES256_GCM,data:2xHS7C50OmKMmAKloZV2FMdLrR4tmlDtjGcbHb3kwRYa6VIoGAFaBTbl0KPu5dDf7euv8AS4PIveABitI5UH0Gn3G4WbafxtWp4E/dG7IWie8MTfROhPd7HEA/WJ1gxQns1+9BiUO15M2YaB+egQGt/BpRFNrX4knoAknUKsaF8=,iv:BMZdbB6rgmwQxpQPh3ES6/p7iHZZCq66e8Znnx/Iah8=,tag:iAZRU3+PXTGcXtNMxe/mkw==,type:str] pgp: - created_at: '2020-10-16T06:47:07Z' enc: | -----BEGIN PGP MESSAGE----- hQEMA94v/8CA+lyiAQf/d8//jz+I3aeGUhJDDDCsDU//JeXPUphHt+oRAVTYa8zG 7CtX36U9Kdbf6pfGBm+5hgx1asoTr3078FxagmgFqaPCC1SAikkYqgbnSOv+woO6 /WVxb/dUflUFAX2cSxuh9kBbYOVCf8K8N2skDWUUsXpZU/xlgwCMwPMKSVQLOkZy Y41ADLk2Y8laoFJXIqrwyzKXfcq6Mm82rcbkdZgt2+mkJeXHTpp7O35tePkJXRpd q2Ke6Hmo7auBR8X6BmbF2AEW6NaXRrYnHl8EWWEPVrnx5OsJ4OWrfedv3NnK2j7O dT8EdSbx0nzprzMhuFOp6Ah9wU65wtOlNu3suHlDVNJeAXSJc0/z4a94TINjI0Hc bFcKWLCYcLaR7MPIxkkS9hC/hCXSjvd+whO4MQk/C7AxSGi94ylA5josj3Le+/Nb CKaSy9fOWrxZY7sBt8q6MwudNbja0ySKHEnpTIqAFA== =53Ss -----END PGP MESSAGE----- fp: 382C4220D8CB1003455A6E0EB36A79B39FD6F3C3 encrypted_regex: ^data|^password version: 3.6.0 # you can pass an empty dst explicitly to encrypt in place ➜ airshipctl git:(h4) ✗ cat exampleTargetPath/phasePath/secret.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - pass1 - pass2 ➜ airshipctl git:(h4) ✗ ./airshipctl secret encrypt --dst "" ➜ airshipctl git:(h4) ✗ cat exampleTargetPath/phasePath/secret.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - ENC[AES256_GCM,data:Sah3CWU=,iv:EZxiiVpVfuikuE8ddQY3PsA9AFDozZQ/aoRijUFB9a0=,tag:MQyCJHm4ceKLTqvcvvAiIw==,type:str] - ENC[AES256_GCM,data:FogSaBo=,iv:Gbr8PVGfFdwnZCyJV790USLk/gUc1KJ5psYwID/yKsY=,tag:sIrktQSpk9F/E7EvBgWGqA==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] lastmodified: '2020-10-16T06:48:16Z' mac: ENC[AES256_GCM,data:YO5ZmGjgYqOj2yogoCr9CAnzHquXukr87XBdRYVSbx1IM5K3X7kbOx4roxKk77/tOoAqW03HFAiRRPrBOslgQYg+BizHBXPk5pJRQPymJVbpbBZHXLDnupK5rhZluD5j5e+0n1TzJqpdTHGfv33IQBfgDRAdokw4SQvniW9h/jo=,iv:gEI/RQsONRsvl1aA+fafVee5mXyJTzGQPGFH3MvMP6s=,tag:eogX2KT8bwg+qQqhNE9f2Q==,type:str] pgp: - created_at: '2020-10-16T06:48:16Z' enc: | -----BEGIN PGP MESSAGE----- hQEMA94v/8CA+lyiAQgAv8moYrLFQv9ThZzc0BLYZxpPRcsel+zTITQvKxoaN6cy SOc5GePYDqKjCNM3m026eS0zwfjq6xXuUZgTYmCPNU8HNHOCchSmoazsg5g7/J+E tqmufIRHB8xzhATAu6YAVwPanpuofs+LUBrbeWY/pO3qFoz7BVnArhi1RnJre5vf y9902A5hncB4c+taJIy4rzcqPrqYLXUkj+75BMUfUNe7mL1qg7e6EkbeM6SCq906 NIDxNanI0dH8s1MGDpyievJWS6CA3Rim0HXRx8lqoSeJRpTZl7mkCZnNv44yyC7z vN3me4f8Sz/sm64Kcv2MKlLwQax2phW/f/+vQGAx69JeAU7ksJZvrG78tF22jo21 j33faY1oE2oJkPpaqUjclxoAz/lXJUpYZa8AQzWrU8auKn++woiqZXCxpuG0np9f VscERVv7A+oVrSWt6D7w9baUux4s6iozsYBs13dZrw== =/2OP -----END PGP MESSAGE----- fp: 382C4220D8CB1003455A6E0EB36A79B39FD6F3C3 encrypted_regex: ^data|^password version: 3.6.0 # you can now run the command to decrypt the file back inplace ➜ airshipctl git:(h4) ✗ ./airshipctl secret decrypt --dst "" ➜ airshipctl git:(h4) ✗ cat exampleTargetPath/phasePath/secret.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - pass1 - pass2 ``` ## Sops Kustomize Plugin As part of this feature, we also implemented a sops kustomize plugin that is capable of doing a decryption of sops encrypted secret files during `airshipctl phase apply`. The steps demonstrate the usage of the kustomize plugin: > There is active work right now to move all document plugins into kustomize krm plugins. ### Create kustomize structure Setup a directory and file structure like the following: ```bash= ➜ airshipctl git:(kust4) ✗ tree kustomize kustomize ├── secrets │   ├── helm-release.yaml │   └── secret.yaml └── sops.yaml 1 directory, 3 files ``` Fill the contents of the files above as described below: ```bash= ➜ airshipctl git:(kust4) ✗ cat kustomize/sops.yaml apiVersion: airshipit.org/v1alpha1 kind: Sops metadata: name: notImportantHere file: "secrets" ➜ airshipctl git:(kust4) ✗ cat kustomize/secrets/helm-release.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - secret1 - secret2 ➜ airshipctl git:(kust4) ✗ cat kustomize/secrets/secret.yaml apiVersion: v1 kind: Secret metadata: name: test-secret annotations: airshipit.org/encrypt: "true" data: username: bXktYXBw password: Mzk1MjgkdmRnN0pi ``` Encrypt the secret using `airshipctl secret encrypt` before using the kustomize plugin to see sops in action ```bash= ➜ airshipctl git:(kust4) ✗ ./airshipctl secret encrypt --src=./kustomize/secrets --dst="" ``` Confirm encryption has been done on both objects ```bash= ➜ airshipctl git:(kust4) ✗ cat kustomize/secrets/secret.yaml apiVersion: v1 kind: Secret metadata: name: test-secret annotations: airshipit.org/encrypt: "true" data: username: ENC[AES256_GCM,data:cxvSoJ2iJE8=,iv:HGAaGn81y5pU/JyIjdqrlZwe9pF5zpuVb3Npa5eHO8Y=,tag:RxGAlmLioLNTG8stHHIaJw==,type:str] password: ENC[AES256_GCM,data:ldEdFgSLGsqcyfoXgojg/g==,iv:U58p/hLjcBgjPOQ0OfXuBHeDlNCpT0luBODgZDX8QMA=,tag:BtwJQwcz6s43sycIEf6Cjw==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] lastmodified: '2020-10-21T10:04:04Z' mac: ENC[AES256_GCM,data:Jb8n1J0fEn/iB42DJwH9BwgKF+Q3NV1dWJ4zGKSWonRevMZfFBDhLv3mvnRw6T6yHUkJHixUo3nildcPQ1njoJUqmgjkeB4rHVHex5hiFS3gX62WvDg+3zVMJNM7U6Ryl0YvQwI1Gs/onENwzzrQ3LB2HCZ64eANLGLSfPbX9lI=,iv:eE2+aEgBkypr85f/PJSXijtouH76FDKZy2HhbJfe2F4=,tag:FVr7KcEEILHrtv/uLdQjEA==,type:str] pgp: - created_at: '2020-10-21T10:03:58Z' enc: | -----BEGIN PGP MESSAGE----- hQEMA94v/8CA+lyiAQgAtWme2RzVrDYCHfkx0o6WrYr+TY1BS2clVfWUhjaTm0Ga IxLbMxSU4nTB2ug8p69OOXsdRwJ6RipicC1rBh38bl8E/CRozYHQO7xAubRgn89k xKA5d5QugR9WxvlfwpMlOQNSPVGdrd7mDsu1UPKXtRxlPwa5IJMbq9x/gwkMEjTv bSgEu/kmOlDztWvDyTStJVG6IAcsqjtymmej/4tTiGMTHoS4nTJES60LPhOKb4iP kkQtuDLfxTL+6LGKcCfTbSPb5/kyWyQqJs/eVUmDe1BkdD8LdIh+2gFEf5HZcEpQ 97bn7MQvI2La3uTh8AF8T6sG9JhXdTEdWJ0dDZDiVtJeAW7hI4m1ce23r3HXnlAi D59wVvIT90oRRGxo4GMfYxb9Vd1cXTYg7UfYrWMg8Dz7bZtdXwqqX/LUkduVKW8M QVppGJE81U7OUBRXdXTf8tuUlB/5OcE2m396BCEcrg== =jFrE -----END PGP MESSAGE----- fp: 382C4220D8CB1003455A6E0EB36A79B39FD6F3C3 encrypted_regex: ^data version: 3.6.0 ➜ airshipctl git:(kust4) ✗ cat kustomize/secrets/helm-release.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - ENC[AES256_GCM,data:h+uS/6qdSA==,iv:b+sXSORCmpr3lWV5kk8YlyfDbUSAdHBtPQk/gbD8n2A=,tag:50OexEZbv9b3bKvk2BG+Hw==,type:str] - ENC[AES256_GCM,data:JFjFnp2AJg==,iv:PcT0DJRm6Bcoj1EwkI5shOjUYufscbGZQkMl/Os9uCA=,tag:A69B9vTgkRa9u0HJTBkKJw==,type:str] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] lastmodified: '2020-10-21T09:58:10Z' mac: ENC[AES256_GCM,data:gs1NGZOhLNreO09MXFg1i6kn9qrTvAkNd1VN1XgGaGqrZBcrEx1cCMzPaxCRaDMcWQL2c0vFyw+l4unlv+BWiMPnAjRr0uuKDy3IBVGmcL2kW0W31Qh5rt/A2EP43T0XskIxDNAIQuZ8f7sM8SpnRpz4HYBvm1OeSbZzChAyYmo=,iv:d4iAYkIcCAOBBWY4fxAiqim4Mk1lZk82+l4yrfTPGbg=,tag:KL251rQpWeHJ5RkokdVImQ==,type:str] pgp: - created_at: '2020-10-21T09:58:10Z' enc: | -----BEGIN PGP MESSAGE----- hQEMA94v/8CA+lyiAQf+MnFMlvtqmuKydbiCOj0WGKUyaA495K6j8VKeJCUp0pWI NAkF9BWfymjNAg6Pv+PBEYCWo9MyyvwdWjbPc5CV8QL9g3O1F1VjPmKfWwZxNC1d fcXBeRoch6p/lEawfz8YLDFGYLKaSceoVTWgTlAafcOKK0abBXFRjFLaAGeqEF80 n9qtyaXBJOeEMicL29pSUvuCiTKgeyLCKMEe8GpVroG0rpNbKpgs0QF7UpEoX1n7 ymIZ+fk4hh574oNMNluk4M0Lc9LHhDfjq0kNABKXIbkoWLiHe4jfG4lwZMuQiPTT EFpGIrSqXTR9qczMLfVKvhGyAg6zejGGeWhb5BGQD9JeASMTMzedViDE/PArzHfj 5Sq1ExbxVichXckH5vFbY6hYUlZI3NjNoQDIRO1vuQLbkA2gYAKjG2sIiCpMM1AP ezaXgTqKgaLxXIk898P8BM4S7cXRCCZBiPZdrkQOzg== =SDRw -----END PGP MESSAGE----- fp: 382C4220D8CB1003455A6E0EB36A79B39FD6F3C3 encrypted_regex: ^data|^password version: 3.6.0 ``` Run the `airshipctl document plugin` command now: ```bash= ➜ airshipctl git:(kust4) ✗ ./airshipctl document plugin kustomize/sops.yaml apiVersion: helm.fluxcd.io/v1 kind: HelmRelease metadata: name: podinfo namespace: default annotations: airshipit.org/encrypt: "true" airshipit.org/encryption-regex: ^password spec: values: foo: hi bar: hello passwords: - secret1 - secret2 --- apiVersion: v1 kind: Secret metadata: name: test-secret annotations: airshipit.org/encrypt: "true" data: username: bXktYXBw password: Mzk1MjgkdmRnN0pi --- ``` As you can see above, the secrets have been decrypted and printed on Stdout.