aws / secrets-store-csi-driver-provider-aws

The AWS provider for the Secrets Store CSI Driver allows you to fetch secrets from AWS Secrets Manager and AWS Systems Manager Parameter Store, and mount them into Kubernetes pods.
Apache License 2.0
468 stars 133 forks source link

Sync all key/value pairs from AWS secret to K8S secret #46

Open cryptk opened 3 years ago

cryptk commented 3 years ago

I am currently experimenting with using secretObjects to sync AWS Secrets into K8S secrets, and while I can use the jmesPath functionality to get a kubernetes secret that mirrors the AWS Secret, I have to list out every key in the secret manually. For a secret named MySecret with the below data:

{
  "FOO": "bar",
  "BIN": "baz"
}

I would need to create the following SecretProviderClass in order to fully mirror that into a Kubernetes secret:

    apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
    kind: SecretProviderClass
    metadata:
      name: secret-access-test
      namespace: default
    spec:
      provider: aws
      secretObjects:
      - data:
        - key: FOO
          objectName: FOOAlias
        - key: BIN
          objectName: BINAlias
        secretName: test-sync-secret
        type: Opaque
      parameters:
        objects: |
          - objectName: "MySecret"
            objectType: "secretsmanager"
            jmesPath:
            - path: "FOO"
              objectAlias: "FOOAlias"
            - path: "BIN"
              objectAlias: "BINAlias"

If I added a new value to the AWS Secret, I would then need to also update the secretObjects and parameters adding it there as well. It would be nice if the provider could take a key/value formatted secret and automatically sync all key/value pairs into the kubernetes secret.

Perhaps something like this:

    apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
    kind: SecretProviderClass
    metadata:
      name: secret-access-test
      namespace: default
    spec:
      provider: aws
      secretObjects:
      - data:
          objectName: MySecret
          syncAllKeys: true
        secretName: test-sync-secret
        type: Opaque
      parameters:
        objects: |
          - objectName: "MySecret"
            objectType: "secretsmanager"

under secretObjects, for any given objectName, rather than specifying a key value, you could instead set syncAllKeys to true. Assuming that the object could be decoded as key/value pairs, each of those key/value pairs would be entered into the kubernetes secret leaving you with a secret such as this:

apiVersion: v1
data:
  BIN: YmF6
  FOO: YmFy
kind: Secret
metadata:
  name: test-sync-secret
  namespace: default
type: Opaque
sharmavijay86 commented 3 years ago

Hi Folks! Anyone get any idea on this? We have the same use case and struggling since very long time. Any clue or reference would be appreciated please !

cbalan23 commented 3 years ago

If you're not "forced" to use this solution, have a look at https://external-secrets.io which does exactly that, in a far more elegant way. This seems way too complicated to maintain.

sharmavijay86 commented 3 years ago

@cbalan23 two problem with external-secrets.io . 1- It needs to story aws asm reader user’s key and secrets in a secret which is not recommended. 2- aws role and assume role support is not available. The way enterprise working account dealing with.

cbalan23 commented 3 years ago

@cbalan23 two problem with external-secrets.io . 1- It needs to story aws asm reader user’s key and secrets in a secret which is not recommended. 2- aws role and assume role support is not available. The way enterprise working account dealing with.

@sharmavijay86 it does support IRSA (IAM Roles for Service Accounts). See the bottom of this page.

bgdnlp commented 3 years ago

What happens if you provide @ as path?

I don't have it installed, I was just looking at issues for potential show stoppers, so I can't test. According to the docs and my tests on https://jmespath.org/, @ should return the secret as is. Does it?

jim-hm commented 3 years ago

I am also looking for the solution. Thanks, @bgdnlp. But your solution is probably not working since also need add all the key to spec. secretObjects. data

bgdnlp commented 3 years ago

Well, no, that's the point, if you want all the keys, @ should return all the keys. If you want a subset, then yes, you need to specify, of course. Did anyone try, does it complain about something?

jim-hm commented 3 years ago

I saw a PR opened from driver side to add this feature, but to use this feature provider side may change as well.

riosje commented 2 years ago

What happens if you provide @ as path?

I don't have it installed, I was just looking at issues for potential show stoppers, so I can't test. According to the docs and my tests on https://jmespath.org/, @ should return the secret as is. Does it?

HI @bgdnlp, I just try your suggested workaround and I'm getting the following error: MountVolume.SetUp failed for volume "secrets-store01-inline" : rpc error: code = Unknown desc = failed to mount secrets store objects for pod xxxx/ubuntu-cli, err: rpc error: code = Unknown desc = Invalid JMES search result type for path:@. Only string is allowed.

scalp42 commented 2 years ago

Same here, it's really painful to sync by hand and extract every key from Secrets Manager JSON.

simonmarty commented 2 years ago

There seems to be a feature request for this in the Secret Store repo, we're waiting on them to implement it.

endersonmaia commented 2 years ago

@cryptk I'm doing something similar to create a secret needed for ArgoCD

  Warning  FailedToCreateSecret  18s (x14 over 59s)  csi-secrets-store-controller  failed to get data in spc argocd/github-cartesi-corp-repo-creds for secret repo-creds, err: file matching objectName type not found in the pod                                                                                             
ApiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
  name: github-repo-creds
  namespace: argocd
spec:
  parameters:
    provider: aws
    objects: |2
      - objectName: "repo-creds"
        objectType: "secretsmanager"
        jmesPath:
          - path: "type"
            objectAlias: "type"
          - path: "url"
            objectAlias: "url"
          - path: "githubAppID"
            objectAlias: "githubAppID"
          - path: "githubAppInstallationID"
            objectAlias: "githubAppInstallationID"
          - path: "githubAppPrivateKey"
            objectAlias: "githubAppPrivateKey"
  secretObjects:
    - data:
      - key: type
        objectName: type
      - key: url
        objectName: url
      - key: githubAppID
        objectName: githubAppID
      - key: githubAppInstallationID
        objectName: githubAppInstallationID
      - key: githubAppPrivateKey
        objectName: githubAppPrivateKey
      labels:
        argocd.argoproj.io/secret-type: repo-creds
      secretName: repo-creds

Inside the container, I can only see the file container the secret in JSON format.

I expected to have a file for each key

cat /var/run/secrets/argocd/repo-creds | jq
{
  "type": "git",
  "url": "https://github.com/my-org",
  "githubAppID": 123,
  "githubAppInstallationID": 456,
  "githubAppPrivateKey": "-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----"
}