Repository: godaddy/kubernetes-external-secrets
Pull request #197 (2019-11-05 13:08:10)

Retrieve binary secrets from AWS Secrets Manager
Should fix https://github.com/godaddy/kubernetes-external-secrets/issues/149 issue

arruzk: @silasbw Flydiverny Could you please take a look?

Patch:
diff --git a/charts/kubernetes-external-secrets/README.md b/charts/kubernetes-external-secrets/README.md
index 9be45f9..315ed90 100644
--- a/charts/kubernetes-external-secrets/README.md
+++ b/charts/kubernetes-external-secrets/README.md
@@ -22,6 +22,12 @@ $ helm install --name my-release external-secrets/kubernetes-external-secrets
 
 > **Tip:** A namespace can be specified by the `Helm` option '`--namespace kube-external-secrets`'
 
+To install the chart with [AWS IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html):
+
+```bash
+$ helm install --name my-release --set securityContext.fsGroup=65534 --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"='arn:aws:iam::111111111111:role/ROLENAME' external-secrets/kubernetes-external-secrets
+```
+
 ## Uninstalling the Chart
 
 To uninstall/delete the deployment:
@@ -49,8 +55,10 @@ The following table lists the configurable parameters of the `kubernetes-externa
 | `nameOverride`                   | Override the name of app                                            | `nil`                                          |
 | `fullnameOverride`                   | Override the full name of app                                            | `nil`                                          |
 | `rbac.create`                        | Create & use RBAC resources                                  | `true`                                                  |
+| `securityContext.fsGroup`            | Security context for the container                           | `{}`                                                    |
 | `serviceAccount.create`              | Whether a new service account name should be created.        | `true`                                                  |
-| `serviceAccount.name`                | Service account to be used.                                  | automatically generated
+| `serviceAccount.name`                | Service account to be used.                                  | automatically generated                                 |
+| `serviceAccount.annotations`         | Annotations to be added to service account                   | `nil`                                                   |
 | `podAnnotations`                     | Annotations to be added to pods                              | `{}`                                                    |
 | `replicaCount`                       | Number of replicas                                           | `1`                                                     |
 | `nodeSelector`                       | node labels for pod assignment                               | `{}`                                                    |
diff --git a/charts/kubernetes-external-secrets/templates/deployment.yaml b/charts/kubernetes-external-secrets/templates/deployment.yaml
index 3df7d94..72ea442 100644
--- a/charts/kubernetes-external-secrets/templates/deployment.yaml
+++ b/charts/kubernetes-external-secrets/templates/deployment.yaml
@@ -24,6 +24,9 @@ spec:
       {{- end }}
     spec:
       serviceAccountName: {{ template "kubernetes-external-secrets.serviceAccountName" . }}
+      {{- if .Values.securityContext }}
+      securityContext: {{ toYaml .Values.securityContext | nindent 8 }}
+      {{- end }}
       containers:
         - name: {{ .Chart.Name }}
           image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
diff --git a/charts/kubernetes-external-secrets/values.yaml b/charts/kubernetes-external-secrets/values.yaml
index 95441aa..2584b66 100644
--- a/charts/kubernetes-external-secrets/values.yaml
+++ b/charts/kubernetes-external-secrets/values.yaml
@@ -43,6 +43,9 @@ fullnameOverride: ""
 
 podAnnotations: {}
 
+securityContext: {}
+  # fsGroup: 65534
+
 resources: {}
   # We usually recommend not to specify default resources and to leave this as a conscious
   # choice for the user. This also increases chances charts run on environments with little
diff --git a/lib/backends/secrets-manager-backend.js b/lib/backends/secrets-manager-backend.js
index 8f8eb43..99fdcbf 100644
--- a/lib/backends/secrets-manager-backend.js
+++ b/lib/backends/secrets-manager-backend.js
@@ -39,7 +39,14 @@ class SecretsManagerBackend extends KVBackend {
       .getSecretValue({ SecretId: secretKey })
       .promise()
 
-    return data.SecretString
+    if ('SecretBinary' in data) {
+      return data.SecretBinary
+    } else if ('SecretString' in data) {
+      return data.SecretString
+    }
+
+    this._logger.error(`Unexpected data from Secrets Manager secret ${secretKey}`)
+    return null
   }
 }
 
diff --git a/package-lock.json b/package-lock.json
index 691b574..e60c060 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -520,19 +520,19 @@
       "dev": true
     },
     "aws-sdk": {
-      "version": "2.433.0",
-      "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.433.0.tgz",
-      "integrity": "sha512-p1OL35yw89BpL4Pzpu8Ct0/0w2HNUU/pjx5vC9D0t0rb/5T0cRa4ms13XdeSgGm8tVDLDOwuESlF+vE4oUkNig==",
-      "requires": {
-        "buffer": "4.9.1",
-        "events": "1.1.1",
-        "ieee754": "1.1.8",
-        "jmespath": "0.15.0",
-        "querystring": "0.2.0",
-        "sax": "1.2.1",
-        "url": "0.10.3",
-        "uuid": "3.3.2",
-        "xml2js": "0.4.19"
+      "version": "2.566.0",
+      "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.566.0.tgz",
+      "integrity": "sha512-AifnTGUUOri1xaOK7UyE4Qol97Cr309SJxA0EKuGBUkCG7KehgPYTMm13JAuXU0lyn7y0X6o1RKvNYeYsZ5DCg==",
+      "requires": {
+        "buffer": "^4.9.1",
+        "events": "^1.1.1",
+        "ieee754": "^1.1.13",
+        "jmespath": "^0.15.0",
+        "querystring": "^0.2.0",
+        "sax": "^1.2.1",
+        "url": "^0.10.3",
+        "uuid": "^3.3.2",
+        "xml2js": "^0.4.19"
       }
     },
     "aws-sign2": {
@@ -606,9 +606,9 @@
       }
     },
     "base64-js": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
-      "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+      "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
     },
     "base64url": {
       "version": "3.0.1",
@@ -1600,7 +1600,6 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
       "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
-      "dev": true,
       "requires": {
         "object-keys": "^1.0.12"
       }
@@ -1764,7 +1763,6 @@
       "version": "1.13.0",
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
       "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
-      "dev": true,
       "requires": {
         "es-to-primitive": "^1.2.0",
         "function-bind": "^1.1.1",
@@ -1778,7 +1776,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
       "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
-      "dev": true,
       "requires": {
         "is-callable": "^1.1.4",
         "is-date-object": "^1.0.1",
@@ -3279,8 +3276,7 @@
     "function-bind": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-      "dev": true
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
     },
     "functional-red-black-tree": {
       "version": "1.0.1",
@@ -3716,7 +3712,6 @@
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
       "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dev": true,
       "requires": {
         "function-bind": "^1.1.1"
       }
@@ -3730,8 +3725,7 @@
     "has-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
-      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
-      "dev": true
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
     },
     "has-value": {
       "version": "1.0.0",
@@ -3829,9 +3823,9 @@
       }
     },
     "ieee754": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
-      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
+      "version": "1.1.13",
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+      "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
     },
     "ignore": {
       "version": "4.0.6",
@@ -4000,8 +3994,7 @@
     "is-callable": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
-      "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
-      "dev": true
+      "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
     },
     "is-ci": {
       "version": "1.2.1",
@@ -4035,8 +4028,7 @@
     "is-date-object": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
-      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
-      "dev": true
+      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
     },
     "is-descriptor": {
       "version": "0.1.6",
@@ -4173,7 +4165,6 @@
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
       "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
-      "dev": true,
       "requires": {
         "has": "^1.0.1"
       }
@@ -4194,7 +4185,6 @@
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
       "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
-      "dev": true,
       "requires": {
         "has-symbols": "^1.0.0"
       }
@@ -5359,8 +5349,7 @@
     "object-keys": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
-      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
     },
     "object-visit": {
       "version": "1.0.1",
@@ -5387,7 +5376,6 @@
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
       "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
-      "dev": true,
       "requires": {
         "define-properties": "^1.1.2",
         "es-abstract": "^1.5.1"
@@ -6336,9 +6324,9 @@
       "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
     },
     "sax": {
-      "version": "1.2.1",
-      "resolved": "http://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
-      "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
     },
     "semver": {
       "version": "5.6.0",
@@ -7614,6 +7602,15 @@
       "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
       "dev": true
     },
+    "util.promisify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+      "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+      "requires": {
+        "define-properties": "^1.1.2",
+        "object.getownpropertydescriptors": "^2.0.3"
+      }
+    },
     "utils-merge": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -7775,18 +7772,19 @@
       "dev": true
     },
     "xml2js": {
-      "version": "0.4.19",
-      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
-      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "version": "0.4.22",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.22.tgz",
+      "integrity": "sha512-MWTbxAQqclRSTnehWWe5nMKzI3VmJ8ltiJEco8akcC6j3miOhjjfzKum5sId+CWhfxdOs/1xauYr8/ZDBtQiRw==",
       "requires": {
         "sax": ">=0.6.0",
-        "xmlbuilder": "~9.0.1"
+        "util.promisify": "~1.0.0",
+        "xmlbuilder": "~11.0.0"
       }
     },
     "xmlbuilder": {
-      "version": "9.0.7",
-      "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
-      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+      "version": "11.0.1",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
     },
     "xtend": {
       "version": "4.0.2",
diff --git a/package.json b/package.json
index 530d16e..c4489ab 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,7 @@
     "node": ">=12.0.0"
   },
   "dependencies": {
-    "aws-sdk": "^2.433.0",
+    "aws-sdk": "^2.566.0",
     "express": "^4.17.1",
     "json-stream": "^1.0.0",
     "kubernetes-client": "^8.3.0",


Test patch:
diff --git a/lib/backends/secrets-manager-backend.test.js b/lib/backends/secrets-manager-backend.test.js
index 3d0acd1..7816d9e 100644
--- a/lib/backends/secrets-manager-backend.test.js
+++ b/lib/backends/secrets-manager-backend.test.js
@@ -55,6 +55,23 @@ describe('SecretsManagerBackend', () => {
       expect(secretPropertyValue).equals('fakeSecretPropertyValue')
     })
 
+    it('returns binary secret', async () => {
+      getSecretValuePromise.promise.resolves({
+        SecretBinary: Buffer.from('fakeSecretPropertyValue', 'utf-8')
+      })
+
+      const secretPropertyValue = await secretsManagerBackend._get({
+        secretKey: 'fakeSecretKey'
+      })
+
+      expect(clientMock.getSecretValue.calledWith({
+        SecretId: 'fakeSecretKey'
+      })).to.equal(true)
+      expect(clientFactoryMock.getCall(0).args).deep.equals([])
+      expect(assumeRoleMock.callCount).equals(0)
+      expect(secretPropertyValue.toString()).equals('fakeSecretPropertyValue')
+    })
+
     it('returns secret property value assuming a role', async () => {
       getSecretValuePromise.promise.resolves({
         SecretString: 'fakeAssumeRoleSecretValue'