Browse Source

:sparkles: Enabling Vault IAM auth (#2208)

* Enabling Vault IAM auth

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Adding spec

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Adding test cases and decoupling vault provider from aws for iam auth

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Fixing comments

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Fixing linter issues

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Fixing the check-diff errors

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

* Adding support for assumeRole operations when using static creds

Signed-off-by: Gaurav Dasson <gdasson@Gauravs-Mac-mini.local>

* Bumping the dependencies to fix the go.mod/go.sum conflicts

Signed-off-by: Gaurav Dasson <gdasson@Gauravs-Mac-mini.local>

* Bumping up e2e go mod files

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>

---------

Signed-off-by: Gaurav Dasson <gaurav.dasson@gmail.com>
Gaurav Dasson 3 years ago
parent
commit
7b8fef2c18

+ 59 - 0
apis/externalsecrets/v1beta1/secretstore_vault_types.go

@@ -112,6 +112,11 @@ type VaultAuth struct {
 	// Cert authentication method
 	// +optional
 	Cert *VaultCertAuth `json:"cert,omitempty"`
+
+	// Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials
+	// AWS IAM authentication method
+	// +optional
+	Iam *VaultIamAuth `json:"iam,omitempty"`
 }
 
 // VaultAppRole authenticates with Vault using the App Role auth mechanism,
@@ -178,6 +183,37 @@ type VaultLdapAuth struct {
 	SecretRef esmeta.SecretKeySelector `json:"secretRef,omitempty"`
 }
 
+// VaultAwsAuth tells the controller how to do authentication with aws.
+// Only one of secretRef or jwt can be specified.
+// if none is specified the controller will try to load credentials from its own service account assuming it is IRSA enabled.
+type VaultAwsAuth struct {
+	// +optional
+	SecretRef *VaultAwsAuthSecretRef `json:"secretRef,omitempty"`
+	// +optional
+	JWTAuth *VaultAwsJWTAuth `json:"jwt,omitempty"`
+}
+
+// VaultAWSAuthSecretRef holds secret references for AWS credentials
+// both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+type VaultAwsAuthSecretRef struct {
+	// The AccessKeyID is used for authentication
+	AccessKeyID esmeta.SecretKeySelector `json:"accessKeyIDSecretRef,omitempty"`
+
+	// The SecretAccessKey is used for authentication
+	SecretAccessKey esmeta.SecretKeySelector `json:"secretAccessKeySecretRef,omitempty"`
+
+	// The SessionToken used for authentication
+	// This must be defined if AccessKeyID and SecretAccessKey are temporary credentials
+	// see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
+	// +Optional
+	SessionToken *esmeta.SecretKeySelector `json:"sessionTokenSecretRef,omitempty"`
+}
+
+// Authenticate against AWS using service account tokens.
+type VaultAwsJWTAuth struct {
+	ServiceAccountRef *esmeta.ServiceAccountSelector `json:"serviceAccountRef,omitempty"`
+}
+
 // VaultKubernetesServiceAccountTokenAuth authenticates with Vault using a temporary
 // Kubernetes service account token retrieved by the `TokenRequest` API.
 type VaultKubernetesServiceAccountTokenAuth struct {
@@ -237,3 +273,26 @@ type VaultCertAuth struct {
 	// authenticate with Vault using the Cert authentication method
 	SecretRef esmeta.SecretKeySelector `json:"secretRef,omitempty"`
 }
+
+// VaultIamAuth authenticates with Vault using the Vault's AWS IAM authentication method. Refer: https://developer.hashicorp.com/vault/docs/auth/aws
+type VaultIamAuth struct {
+
+	// Path where the AWS auth method is enabled in Vault, e.g: "aws"
+	Path string `json:"path,omitempty"`
+	// AWS region
+	Region string `json:"region,omitempty"`
+	// This is the AWS role to be assumed before talking to vault
+	AWSIAMRole string `json:"role,omitempty"`
+	// Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+	Role string `json:"vaultRole"`
+	// AWS External ID set on assumed IAM roles
+	ExternalID string `json:"externalID,omitempty"`
+	// X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
+	VaultAWSIAMServerID string `json:"vaultAwsIamServerID,omitempty"`
+	// Specify credentials in a Secret object
+	// +optional
+	SecretRef *VaultAwsAuthSecretRef `json:"secretRef,omitempty"`
+	// Specify a service account with IRSA enabled
+	// +optional
+	JWTAuth *VaultAwsJWTAuth `json:"jwt,omitempty"`
+}

+ 97 - 0
apis/externalsecrets/v1beta1/zz_generated.deepcopy.go

@@ -2051,6 +2051,11 @@ func (in *VaultAuth) DeepCopyInto(out *VaultAuth) {
 		*out = new(VaultCertAuth)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Iam != nil {
+		in, out := &in.Iam, &out.Iam
+		*out = new(VaultIamAuth)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultAuth.
@@ -2064,6 +2069,73 @@ func (in *VaultAuth) DeepCopy() *VaultAuth {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VaultAwsAuth) DeepCopyInto(out *VaultAwsAuth) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(VaultAwsAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.JWTAuth != nil {
+		in, out := &in.JWTAuth, &out.JWTAuth
+		*out = new(VaultAwsJWTAuth)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultAwsAuth.
+func (in *VaultAwsAuth) DeepCopy() *VaultAwsAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(VaultAwsAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VaultAwsAuthSecretRef) DeepCopyInto(out *VaultAwsAuthSecretRef) {
+	*out = *in
+	in.AccessKeyID.DeepCopyInto(&out.AccessKeyID)
+	in.SecretAccessKey.DeepCopyInto(&out.SecretAccessKey)
+	if in.SessionToken != nil {
+		in, out := &in.SessionToken, &out.SessionToken
+		*out = new(metav1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultAwsAuthSecretRef.
+func (in *VaultAwsAuthSecretRef) DeepCopy() *VaultAwsAuthSecretRef {
+	if in == nil {
+		return nil
+	}
+	out := new(VaultAwsAuthSecretRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VaultAwsJWTAuth) DeepCopyInto(out *VaultAwsJWTAuth) {
+	*out = *in
+	if in.ServiceAccountRef != nil {
+		in, out := &in.ServiceAccountRef, &out.ServiceAccountRef
+		*out = new(metav1.ServiceAccountSelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultAwsJWTAuth.
+func (in *VaultAwsJWTAuth) DeepCopy() *VaultAwsJWTAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(VaultAwsJWTAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *VaultCertAuth) DeepCopyInto(out *VaultCertAuth) {
 	*out = *in
 	in.ClientCert.DeepCopyInto(&out.ClientCert)
@@ -2081,6 +2153,31 @@ func (in *VaultCertAuth) DeepCopy() *VaultCertAuth {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VaultIamAuth) DeepCopyInto(out *VaultIamAuth) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(VaultAwsAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.JWTAuth != nil {
+		in, out := &in.JWTAuth, &out.JWTAuth
+		*out = new(VaultAwsJWTAuth)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultIamAuth.
+func (in *VaultIamAuth) DeepCopy() *VaultIamAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(VaultIamAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *VaultJwtAuth) DeepCopyInto(out *VaultJwtAuth) {
 	*out = *in
 	if in.SecretRef != nil {

+ 129 - 0
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -3003,6 +3003,135 @@ spec:
                                     type: string
                                 type: object
                             type: object
+                          iam:
+                            description: Iam authenticates with vault by passing a
+                              special AWS request signed with AWS IAM credentials
+                              AWS IAM authentication method
+                            properties:
+                              externalID:
+                                description: AWS External ID set on assumed IAM roles
+                                type: string
+                              jwt:
+                                description: Specify a service account with IRSA enabled
+                                properties:
+                                  serviceAccountRef:
+                                    description: A reference to a ServiceAccount resource.
+                                    properties:
+                                      audiences:
+                                        description: Audience specifies the `aud`
+                                          claim for the service account token If the
+                                          service account uses a well-known annotation
+                                          for e.g. IRSA or GCP Workload Identity then
+                                          this audiences will be appended to the list
+                                        items:
+                                          type: string
+                                        type: array
+                                      name:
+                                        description: The name of the ServiceAccount
+                                          resource being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    required:
+                                    - name
+                                    type: object
+                                type: object
+                              path:
+                                description: 'Path where the AWS auth method is enabled
+                                  in Vault, e.g: "aws"'
+                                type: string
+                              region:
+                                description: AWS region
+                                type: string
+                              role:
+                                description: This is the AWS role to be assumed before
+                                  talking to vault
+                                type: string
+                              secretRef:
+                                description: Specify credentials in a Secret object
+                                properties:
+                                  accessKeyIDSecretRef:
+                                    description: The AccessKeyID is used for authentication
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                  secretAccessKeySecretRef:
+                                    description: The SecretAccessKey is used for authentication
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                  sessionTokenSecretRef:
+                                    description: 'The SessionToken used for authentication
+                                      This must be defined if AccessKeyID and SecretAccessKey
+                                      are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                type: object
+                              vaultAwsIamServerID:
+                                description: 'X-Vault-AWS-IAM-Server-ID is an additional
+                                  header used by Vault IAM auth method to mitigate
+                                  against different types of replay attacks. More
+                                  details here: https://developer.hashicorp.com/vault/docs/auth/aws'
+                                type: string
+                              vaultRole:
+                                description: Vault Role. In vault, a role describes
+                                  an identity with a set of permissions, groups, or
+                                  policies you want to attach a user of the secrets
+                                  engine
+                                type: string
+                            required:
+                            - vaultRole
+                            type: object
                           jwt:
                             description: Jwt authenticates with Vault by passing role
                               and JWT token using the JWT/OIDC authentication method

+ 129 - 0
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -3003,6 +3003,135 @@ spec:
                                     type: string
                                 type: object
                             type: object
+                          iam:
+                            description: Iam authenticates with vault by passing a
+                              special AWS request signed with AWS IAM credentials
+                              AWS IAM authentication method
+                            properties:
+                              externalID:
+                                description: AWS External ID set on assumed IAM roles
+                                type: string
+                              jwt:
+                                description: Specify a service account with IRSA enabled
+                                properties:
+                                  serviceAccountRef:
+                                    description: A reference to a ServiceAccount resource.
+                                    properties:
+                                      audiences:
+                                        description: Audience specifies the `aud`
+                                          claim for the service account token If the
+                                          service account uses a well-known annotation
+                                          for e.g. IRSA or GCP Workload Identity then
+                                          this audiences will be appended to the list
+                                        items:
+                                          type: string
+                                        type: array
+                                      name:
+                                        description: The name of the ServiceAccount
+                                          resource being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    required:
+                                    - name
+                                    type: object
+                                type: object
+                              path:
+                                description: 'Path where the AWS auth method is enabled
+                                  in Vault, e.g: "aws"'
+                                type: string
+                              region:
+                                description: AWS region
+                                type: string
+                              role:
+                                description: This is the AWS role to be assumed before
+                                  talking to vault
+                                type: string
+                              secretRef:
+                                description: Specify credentials in a Secret object
+                                properties:
+                                  accessKeyIDSecretRef:
+                                    description: The AccessKeyID is used for authentication
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                  secretAccessKeySecretRef:
+                                    description: The SecretAccessKey is used for authentication
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                  sessionTokenSecretRef:
+                                    description: 'The SessionToken used for authentication
+                                      This must be defined if AccessKeyID and SecretAccessKey
+                                      are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                    properties:
+                                      key:
+                                        description: The key of the entry in the Secret
+                                          resource's `data` field to be used. Some
+                                          instances of this field may be defaulted,
+                                          in others it may be required.
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        type: string
+                                      namespace:
+                                        description: Namespace of the resource being
+                                          referred to. Ignored if referent is not
+                                          cluster-scoped. cluster-scoped defaults
+                                          to the namespace of the referent.
+                                        type: string
+                                    type: object
+                                type: object
+                              vaultAwsIamServerID:
+                                description: 'X-Vault-AWS-IAM-Server-ID is an additional
+                                  header used by Vault IAM auth method to mitigate
+                                  against different types of replay attacks. More
+                                  details here: https://developer.hashicorp.com/vault/docs/auth/aws'
+                                type: string
+                              vaultRole:
+                                description: Vault Role. In vault, a role describes
+                                  an identity with a set of permissions, groups, or
+                                  policies you want to attach a user of the secrets
+                                  engine
+                                type: string
+                            required:
+                            - vaultRole
+                            type: object
                           jwt:
                             description: Jwt authenticates with Vault by passing role
                               and JWT token using the JWT/OIDC authentication method

+ 128 - 0
config/crds/bases/generators.external-secrets.io_vaultdynamicsecrets.yaml

@@ -139,6 +139,134 @@ spec:
                                 type: string
                             type: object
                         type: object
+                      iam:
+                        description: Iam authenticates with vault by passing a special
+                          AWS request signed with AWS IAM credentials AWS IAM authentication
+                          method
+                        properties:
+                          externalID:
+                            description: AWS External ID set on assumed IAM roles
+                            type: string
+                          jwt:
+                            description: Specify a service account with IRSA enabled
+                            properties:
+                              serviceAccountRef:
+                                description: A reference to a ServiceAccount resource.
+                                properties:
+                                  audiences:
+                                    description: Audience specifies the `aud` claim
+                                      for the service account token If the service
+                                      account uses a well-known annotation for e.g.
+                                      IRSA or GCP Workload Identity then this audiences
+                                      will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
+                                  name:
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                          path:
+                            description: 'Path where the AWS auth method is enabled
+                              in Vault, e.g: "aws"'
+                            type: string
+                          region:
+                            description: AWS region
+                            type: string
+                          role:
+                            description: This is the AWS role to be assumed before
+                              talking to vault
+                            type: string
+                          secretRef:
+                            description: Specify credentials in a Secret object
+                            properties:
+                              accessKeyIDSecretRef:
+                                description: The AccessKeyID is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                type: object
+                              secretAccessKeySecretRef:
+                                description: The SecretAccessKey is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                type: object
+                              sessionTokenSecretRef:
+                                description: 'The SessionToken used for authentication
+                                  This must be defined if AccessKeyID and SecretAccessKey
+                                  are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                type: object
+                            type: object
+                          vaultAwsIamServerID:
+                            description: 'X-Vault-AWS-IAM-Server-ID is an additional
+                              header used by Vault IAM auth method to mitigate against
+                              different types of replay attacks. More details here:
+                              https://developer.hashicorp.com/vault/docs/auth/aws'
+                            type: string
+                          vaultRole:
+                            description: Vault Role. In vault, a role describes an
+                              identity with a set of permissions, groups, or policies
+                              you want to attach a user of the secrets engine
+                            type: string
+                        required:
+                        - vaultRole
+                        type: object
                       jwt:
                         description: Jwt authenticates with Vault by passing role
                           and JWT token using the JWT/OIDC authentication method

+ 264 - 0
deploy/crds/bundle.yaml

@@ -2656,6 +2656,94 @@ spec:
                                       type: string
                                   type: object
                               type: object
+                            iam:
+                              description: Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method
+                              properties:
+                                externalID:
+                                  description: AWS External ID set on assumed IAM roles
+                                  type: string
+                                jwt:
+                                  description: Specify a service account with IRSA enabled
+                                  properties:
+                                    serviceAccountRef:
+                                      description: A reference to a ServiceAccount resource.
+                                      properties:
+                                        audiences:
+                                          description: Audience specifies the `aud` claim for the service account token If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity then this audiences will be appended to the list
+                                          items:
+                                            type: string
+                                          type: array
+                                        name:
+                                          description: The name of the ServiceAccount resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      required:
+                                        - name
+                                      type: object
+                                  type: object
+                                path:
+                                  description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"'
+                                  type: string
+                                region:
+                                  description: AWS region
+                                  type: string
+                                role:
+                                  description: This is the AWS role to be assumed before talking to vault
+                                  type: string
+                                secretRef:
+                                  description: Specify credentials in a Secret object
+                                  properties:
+                                    accessKeyIDSecretRef:
+                                      description: The AccessKeyID is used for authentication
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                    secretAccessKeySecretRef:
+                                      description: The SecretAccessKey is used for authentication
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                    sessionTokenSecretRef:
+                                      description: 'The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                  type: object
+                                vaultAwsIamServerID:
+                                  description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws'
+                                  type: string
+                                vaultRole:
+                                  description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+                                  type: string
+                              required:
+                                - vaultRole
+                              type: object
                             jwt:
                               description: Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
                               properties:
@@ -6113,6 +6201,94 @@ spec:
                                       type: string
                                   type: object
                               type: object
+                            iam:
+                              description: Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method
+                              properties:
+                                externalID:
+                                  description: AWS External ID set on assumed IAM roles
+                                  type: string
+                                jwt:
+                                  description: Specify a service account with IRSA enabled
+                                  properties:
+                                    serviceAccountRef:
+                                      description: A reference to a ServiceAccount resource.
+                                      properties:
+                                        audiences:
+                                          description: Audience specifies the `aud` claim for the service account token If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity then this audiences will be appended to the list
+                                          items:
+                                            type: string
+                                          type: array
+                                        name:
+                                          description: The name of the ServiceAccount resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      required:
+                                        - name
+                                      type: object
+                                  type: object
+                                path:
+                                  description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"'
+                                  type: string
+                                region:
+                                  description: AWS region
+                                  type: string
+                                role:
+                                  description: This is the AWS role to be assumed before talking to vault
+                                  type: string
+                                secretRef:
+                                  description: Specify credentials in a Secret object
+                                  properties:
+                                    accessKeyIDSecretRef:
+                                      description: The AccessKeyID is used for authentication
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                    secretAccessKeySecretRef:
+                                      description: The SecretAccessKey is used for authentication
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                    sessionTokenSecretRef:
+                                      description: 'The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                      properties:
+                                        key:
+                                          description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                          type: string
+                                        name:
+                                          description: The name of the Secret resource being referred to.
+                                          type: string
+                                        namespace:
+                                          description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                          type: string
+                                      type: object
+                                  type: object
+                                vaultAwsIamServerID:
+                                  description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws'
+                                  type: string
+                                vaultRole:
+                                  description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+                                  type: string
+                              required:
+                                - vaultRole
+                              type: object
                             jwt:
                               description: Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
                               properties:
@@ -7154,6 +7330,94 @@ spec:
                                   type: string
                               type: object
                           type: object
+                        iam:
+                          description: Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials AWS IAM authentication method
+                          properties:
+                            externalID:
+                              description: AWS External ID set on assumed IAM roles
+                              type: string
+                            jwt:
+                              description: Specify a service account with IRSA enabled
+                              properties:
+                                serviceAccountRef:
+                                  description: A reference to a ServiceAccount resource.
+                                  properties:
+                                    audiences:
+                                      description: Audience specifies the `aud` claim for the service account token If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity then this audiences will be appended to the list
+                                      items:
+                                        type: string
+                                      type: array
+                                    name:
+                                      description: The name of the ServiceAccount resource being referred to.
+                                      type: string
+                                    namespace:
+                                      description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                      type: string
+                                  required:
+                                    - name
+                                  type: object
+                              type: object
+                            path:
+                              description: 'Path where the AWS auth method is enabled in Vault, e.g: "aws"'
+                              type: string
+                            region:
+                              description: AWS region
+                              type: string
+                            role:
+                              description: This is the AWS role to be assumed before talking to vault
+                              type: string
+                            secretRef:
+                              description: Specify credentials in a Secret object
+                              properties:
+                                accessKeyIDSecretRef:
+                                  description: The AccessKeyID is used for authentication
+                                  properties:
+                                    key:
+                                      description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      type: string
+                                    namespace:
+                                      description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                      type: string
+                                  type: object
+                                secretAccessKeySecretRef:
+                                  description: The SecretAccessKey is used for authentication
+                                  properties:
+                                    key:
+                                      description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      type: string
+                                    namespace:
+                                      description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                      type: string
+                                  type: object
+                                sessionTokenSecretRef:
+                                  description: 'The SessionToken used for authentication This must be defined if AccessKeyID and SecretAccessKey are temporary credentials see: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html'
+                                  properties:
+                                    key:
+                                      description: The key of the entry in the Secret resource's `data` field to be used. Some instances of this field may be defaulted, in others it may be required.
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      type: string
+                                    namespace:
+                                      description: Namespace of the resource being referred to. Ignored if referent is not cluster-scoped. cluster-scoped defaults to the namespace of the referent.
+                                      type: string
+                                  type: object
+                              type: object
+                            vaultAwsIamServerID:
+                              description: 'X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws'
+                              type: string
+                            vaultRole:
+                              description: Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+                              type: string
+                          required:
+                            - vaultRole
+                          type: object
                         jwt:
                           description: Jwt authenticates with Vault by passing role and JWT token using the JWT/OIDC authentication method
                           properties:

+ 265 - 0
docs/api/spec.md

@@ -5543,6 +5543,158 @@ VaultCertAuth
 Cert authentication method</p>
 </td>
 </tr>
+<tr>
+<td>
+<code>iam</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.VaultIamAuth">
+VaultIamAuth
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials
+AWS IAM authentication method</p>
+</td>
+</tr>
+</tbody>
+</table>
+<h3 id="external-secrets.io/v1beta1.VaultAwsAuth">VaultAwsAuth
+</h3>
+<p>
+<p>VaultAwsAuth tells the controller how to do authentication with aws.
+Only one of secretRef or jwt can be specified.
+if none is specified the controller will try to load credentials from its own service account assuming it is IRSA enabled.</p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>secretRef</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.VaultAwsAuthSecretRef">
+VaultAwsAuthSecretRef
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+</td>
+</tr>
+<tr>
+<td>
+<code>jwt</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.VaultAwsJWTAuth">
+VaultAwsJWTAuth
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+</td>
+</tr>
+</tbody>
+</table>
+<h3 id="external-secrets.io/v1beta1.VaultAwsAuthSecretRef">VaultAwsAuthSecretRef
+</h3>
+<p>
+(<em>Appears on:</em>
+<a href="#external-secrets.io/v1beta1.VaultAwsAuth">VaultAwsAuth</a>, 
+<a href="#external-secrets.io/v1beta1.VaultIamAuth">VaultIamAuth</a>)
+</p>
+<p>
+<p>VaultAWSAuthSecretRef holds secret references for AWS credentials
+both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.</p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>accessKeyIDSecretRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#SecretKeySelector">
+External Secrets meta/v1.SecretKeySelector
+</a>
+</em>
+</td>
+<td>
+<p>The AccessKeyID is used for authentication</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>secretAccessKeySecretRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#SecretKeySelector">
+External Secrets meta/v1.SecretKeySelector
+</a>
+</em>
+</td>
+<td>
+<p>The SecretAccessKey is used for authentication</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>sessionTokenSecretRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#SecretKeySelector">
+External Secrets meta/v1.SecretKeySelector
+</a>
+</em>
+</td>
+<td>
+<p>The SessionToken used for authentication
+This must be defined if AccessKeyID and SecretAccessKey are temporary credentials
+see: <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html">https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html</a></p>
+</td>
+</tr>
+</tbody>
+</table>
+<h3 id="external-secrets.io/v1beta1.VaultAwsJWTAuth">VaultAwsJWTAuth
+</h3>
+<p>
+(<em>Appears on:</em>
+<a href="#external-secrets.io/v1beta1.VaultAwsAuth">VaultAwsAuth</a>, 
+<a href="#external-secrets.io/v1beta1.VaultIamAuth">VaultIamAuth</a>)
+</p>
+<p>
+<p>Authenticate against AWS using service account tokens.</p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>serviceAccountRef</code></br>
+<em>
+<a href="https://pkg.go.dev/github.com/external-secrets/external-secrets/apis/meta/v1#ServiceAccountSelector">
+External Secrets meta/v1.ServiceAccountSelector
+</a>
+</em>
+</td>
+<td>
+</td>
+</tr>
 </tbody>
 </table>
 <h3 id="external-secrets.io/v1beta1.VaultCertAuth">VaultCertAuth
@@ -5594,6 +5746,119 @@ authenticate with Vault using the Cert authentication method</p>
 </tr>
 </tbody>
 </table>
+<h3 id="external-secrets.io/v1beta1.VaultIamAuth">VaultIamAuth
+</h3>
+<p>
+(<em>Appears on:</em>
+<a href="#external-secrets.io/v1beta1.VaultAuth">VaultAuth</a>)
+</p>
+<p>
+<p>VaultIamAuth authenticates with Vault using the Vault&rsquo;s AWS IAM authentication method. Refer: <a href="https://developer.hashicorp.com/vault/docs/auth/aws">https://developer.hashicorp.com/vault/docs/auth/aws</a></p>
+</p>
+<table>
+<thead>
+<tr>
+<th>Field</th>
+<th>Description</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>
+<code>path</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>Path where the AWS auth method is enabled in Vault, e.g: &ldquo;aws&rdquo;</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>region</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>AWS region</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>role</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>This is the AWS role to be assumed before talking to vault</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>vaultRole</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>externalID</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>AWS External ID set on assumed IAM roles</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>vaultAwsIamServerID</code></br>
+<em>
+string
+</em>
+</td>
+<td>
+<p>X-Vault-AWS-IAM-Server-ID is an additional header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: <a href="https://developer.hashicorp.com/vault/docs/auth/aws">https://developer.hashicorp.com/vault/docs/auth/aws</a></p>
+</td>
+</tr>
+<tr>
+<td>
+<code>secretRef</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.VaultAwsAuthSecretRef">
+VaultAwsAuthSecretRef
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>Specify credentials in a Secret object</p>
+</td>
+</tr>
+<tr>
+<td>
+<code>jwt</code></br>
+<em>
+<a href="#external-secrets.io/v1beta1.VaultAwsJWTAuth">
+VaultAwsJWTAuth
+</a>
+</em>
+</td>
+<td>
+<em>(Optional)</em>
+<p>Specify a service account with IRSA enabled</p>
+</td>
+</tr>
+</tbody>
+</table>
 <h3 id="external-secrets.io/v1beta1.VaultJwtAuth">VaultJwtAuth
 </h3>
 <p>

+ 51 - 2
docs/provider/hashicorp-vault.md

@@ -271,8 +271,9 @@ We support five different modes for authentication:
 [token-based](https://www.vaultproject.io/docs/auth/token),
 [appRole](https://www.vaultproject.io/docs/auth/approle),
 [kubernetes-native](https://www.vaultproject.io/docs/auth/kubernetes),
-[ldap](https://www.vaultproject.io/docs/auth/ldap) and
-[jwt/oidc](https://www.vaultproject.io/docs/auth/jwt), each one comes with it's own
+[ldap](https://www.vaultproject.io/docs/auth/ldap),
+[jwt/oidc](https://www.vaultproject.io/docs/auth/jwt) and
+[awsAuth](https://developer.hashicorp.com/vault/docs/auth/aws), each one comes with it's own
 trade-offs. Depending on the authentication method you need to adapt your environment.
 
 #### Token-based authentication
@@ -333,6 +334,54 @@ or `Kind=ClusterSecretStore` resource.
 ```
 **NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` in `secretRef` with the namespace where the secret resides.
 
+#### AWS IAM authentication
+
+[AWS IAM](https://developer.hashicorp.com/vault/docs/auth/aws) uses either a
+set of AWS Programmatic access credentials stored in a `Kind=Secret` and referenced by the
+`secretRef` or by getting the authentication token from an [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) enabled service account
+
+### Access Key ID & Secret Access Key
+You can store Access Key ID & Secret Access Key in a `Kind=Secret` and reference it from a SecretStore.
+
+```yaml
+{% include 'vault-iam-store-static-creds.yaml' %}
+```
+
+**NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` in `accessKeyIDSecretRef`, `secretAccessKeySecretRef` with the namespaces where the secrets reside.
+
+### EKS Service Account credentials
+
+This feature lets you use short-lived service account tokens to authenticate with AWS.
+You must have [Service Account Volume Projection](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#service-account-token-volume-projection) enabled - it is by default on EKS. See [EKS guide](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html) on how to set up IAM roles for service accounts.
+
+The big advantage of this approach is that ESO runs without any credentials.
+
+```yaml
+{% include 'vault-iam-store-sa.yaml' %}
+```
+
+Reference the service account from above in the Secret Store:
+
+```yaml
+{% include 'vault-iam-store.yaml' %}
+```
+### Controller's Pod Identity
+
+This is basicially a zero-configuration authentication approach that inherits the credentials from the controller's pod identity
+
+This approach assumes that appropriate IRSA setup is done controller's pod (i.e. IRSA enabled IAM role is created appropriately and controller's service account is annotated appropriately with the annotation "eks.amazonaws.com/role-arn" to enable IRSA)
+
+```yaml
+{% include 'vault-iam-store-controller-pod-identity.yaml' %}
+```
+
+**NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` for `serviceAccountRef` with the namespace where the service account resides.
+
+```yaml
+{% include 'vault-jwt-store.yaml' %}
+```
+**NOTE:** In case of a `ClusterSecretStore`, Be sure to provide `namespace` in `secretRef` with the namespace where the secret resides.
+
 ### PushSecret
 Vault supports PushSecret features which allow you to sync a given kubernetes secret key into a hashicorp vault secret. In order to do so, it is expected that the secret key is a valid JSON object.
 

+ 21 - 0
docs/snippets/vault-iam-store-controller-pod-identity.yaml

@@ -0,0 +1,21 @@
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+  name: vault-backend-aws-iam
+spec:
+  provider:
+    vault:
+      server: "http://my.vault.server:8200"
+      path: secret
+      version: v2
+      namespace: <vault_namespace>
+      auth:
+        iam:
+          # Path where the AWS auth method is enabled in Vault, e.g: "aws/". Defaults to aws
+          path: aws
+          # AWS Region. Defaults to us-east-1
+          region: us-east-1
+          # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+          vaultRole: vault-role-for-aws-iam-auth
+          # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
+          vaultAwsIamServerID: example-vaultAwsIamServerID

+ 7 - 0
docs/snippets/vault-iam-store-sa.yaml

@@ -0,0 +1,7 @@
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  annotations:
+    eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-irsa-enabled-role
+  name: my-serviceaccount
+  namespace: default

+ 33 - 0
docs/snippets/vault-iam-store-static-creds.yaml

@@ -0,0 +1,33 @@
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+  name: vault-backend-aws-iam
+spec:
+  provider:
+    vault:
+      server: "http://my.vault.server:8200"
+      path: secret
+      version: v2
+      namespace: <vault_namespace>
+      auth:
+        iam:
+          # Path where the AWS auth method is enabled in Vault, e.g: "aws/". Defaults to aws
+          path: aws
+          # AWS Region. Defaults to us-east-1
+          region: us-east-1
+          # optional: assume role before fetching secrets
+          role: arn:aws:iam::1234567890:role/role-a
+          # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+          vaultRole: vault-role-for-aws-iam-auth
+          # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
+          vaultAwsIamServerID: example-vaultAwsIamServerID
+          secretRef: #Use this method when you have static AWS creds.
+            accessKeyIDSecretRef:
+              name: vault-iam-creds-secret
+              key: access-key
+            secretAccessKeySecretRef:
+              name: vault-iam-creds-secret
+              key: secret-access-key
+            sessionTokenSecretRef:
+              name: vault-iam-creds-secret
+              key: secret-session-token

+ 24 - 0
docs/snippets/vault-iam-store.yaml

@@ -0,0 +1,24 @@
+apiVersion: external-secrets.io/v1beta1
+kind: SecretStore
+metadata:
+  name: vault-backend-aws-iam
+spec:
+  provider:
+    vault:
+      server: "http://my.vault.server:8200"
+      path: secret
+      version: v2
+      namespace: <vault_namespace>
+      auth:
+        iam:
+          # Path where the AWS auth method is enabled in Vault, e.g: "aws/". Defaults to aws
+          path: aws
+          # AWS Region. Defaults to us-east-1
+          region: us-east-1
+          # Vault Role. In vault, a role describes an identity with a set of permissions, groups, or policies you want to attach a user of the secrets engine
+          vaultRole: vault-role-for-aws-iam-auth
+          # Optional. Placeholder to supply header X-Vault-AWS-IAM-Server-ID. It is an additional (optional) header used by Vault IAM auth method to mitigate against different types of replay attacks. More details here: https://developer.hashicorp.com/vault/docs/auth/aws
+          vaultAwsIamServerID: example-vaultAwsIamServerID
+          jwt:
+            serviceAccountRef:
+              name: my-serviceaccount #Provide service account with IRSA enabled

+ 0 - 1
e2e/go.mod

@@ -179,7 +179,6 @@ require (
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.9.0 // indirect
 	github.com/robfig/cron v1.2.0 // indirect
-	github.com/rogpeppe/go-internal v1.9.0 // indirect
 	github.com/russross/blackfriday v1.5.2 // indirect
 	github.com/ryanuber/go-glob v1.0.0 // indirect
 	github.com/sergi/go-diff v1.1.0 // indirect

+ 0 - 1
e2e/go.sum

@@ -853,7 +853,6 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
 github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
 github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
 github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=

+ 5 - 0
go.mod

@@ -71,7 +71,9 @@ require (
 	github.com/alibabacloud-go/tea-utils/v2 v2.0.1
 	github.com/aliyun/credentials-go v1.2.7
 	github.com/avast/retry-go/v4 v4.3.4
+	github.com/golang-jwt/jwt/v5 v5.0.0-rc.2
 	github.com/hashicorp/golang-lru v0.5.4
+	github.com/hashicorp/vault/api/auth/aws v0.4.0
 	github.com/keeper-security/secrets-manager-go/core v1.5.0
 	github.com/maxbrunsfeld/counterfeiter/v6 v6.6.1
 	github.com/scaleway/scaleway-sdk-go v1.0.0-beta.16
@@ -90,6 +92,9 @@ require (
 	github.com/clbanning/mxj/v2 v2.5.7 // indirect
 	github.com/go-playground/validator/v10 v10.13.0 // indirect
 	github.com/google/s2a-go v0.1.3 // indirect
+	github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect
+	github.com/hashicorp/go-uuid v1.0.2 // indirect
+	github.com/rogpeppe/go-internal v1.9.0 // indirect
 	github.com/tjfoc/gmsm v1.4.1 // indirect
 )
 

+ 16 - 1
go.sum

@@ -154,6 +154,7 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/avast/retry-go/v4 v4.3.4 h1:pHLkL7jvCvP317I8Ge+Km2Yhntv3SdkJm7uekkqbKhM=
 github.com/avast/retry-go/v4 v4.3.4/go.mod h1:rv+Nla6Vk3/ilU0H51VHddWHiwimzX66yZ0JT6T+UvE=
+github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
 github.com/aws/aws-sdk-go v1.41.13/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
 github.com/aws/aws-sdk-go v1.44.254 h1:8baW4yal2xGiM/Wm5/ZU10drS8sd+BVjMjPFjJx2ooc=
 github.com/aws/aws-sdk-go v1.44.254/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
@@ -255,6 +256,7 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
 github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
 github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ=
 github.com/go-playground/validator/v10 v10.13.0/go.mod h1:dwu7+CG8/CtBiJFZDz4e+5Upb6OLw04gtBYw0mcG/z4=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
 github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
@@ -272,6 +274,8 @@ github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw
 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
 github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v5 v5.0.0-rc.2 h1:hXPcSazn8wKOfSb9y2m1bdgUMlDxVDarxh3lJVbC6JE=
+github.com/golang-jwt/jwt/v5 v5.0.0-rc.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -381,6 +385,8 @@ github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUD
 github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
 github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
 github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
+github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA=
+github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg=
 github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
 github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs=
 github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
@@ -389,6 +395,8 @@ github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9
 github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
 github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
 github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
+github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
+github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
@@ -401,6 +409,8 @@ github.com/hashicorp/vault/api v1.9.1 h1:LtY/I16+5jVGU8rufyyAkwopgq/HpUnxFBg+QLO
 github.com/hashicorp/vault/api v1.9.1/go.mod h1:78kktNcQYbBGSrOjQfHjXN32OhhxXnbYl3zxpd2uPUs=
 github.com/hashicorp/vault/api/auth/approle v0.4.0 h1:tjJHoUkPx8zRoFlFy86uvgg/1gpTnDPp0t0BYWTKjjw=
 github.com/hashicorp/vault/api/auth/approle v0.4.0/go.mod h1:D2gEpR0aS/F/MEcSjmhUlOsuK1RMVZojsnIQAEf0EV0=
+github.com/hashicorp/vault/api/auth/aws v0.4.0 h1:2Myo+XU3X5gQTtr3S+WGXcrLUa6iO4w97VzFFaaBOm8=
+github.com/hashicorp/vault/api/auth/aws v0.4.0/go.mod h1:CGm5PAXEREuYpszyA2ERQPFBSIUD+QTqXfKvdI2Gw/Q=
 github.com/hashicorp/vault/api/auth/kubernetes v0.4.0 h1:f6OIOF9012JIdqYvOeeewxhtQdJosnog2CHzh33j41s=
 github.com/hashicorp/vault/api/auth/kubernetes v0.4.0/go.mod h1:tMewM2hPyFNKP1EXdWbc0dUHHoS5V/0qS04BEaxuy78=
 github.com/hashicorp/vault/api/auth/ldap v0.4.0 h1:/P2HCNmcDY6s22JBXxVhr9noaFqPEQS2qwSnWIYezkc=
@@ -416,6 +426,7 @@ github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
@@ -437,6 +448,7 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -541,7 +553,9 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf
 github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -812,6 +826,7 @@ golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

+ 309 - 0
pkg/provider/vault/iamauth/iamauth.go

@@ -0,0 +1,309 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// Mostly sourced from ~/external-secrets/pkg/provider/aws/auth
+package iamauth
+
+import (
+	"context"
+	"fmt"
+	"os"
+
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
+	"github.com/aws/aws-sdk-go/aws/defaults"
+	"github.com/aws/aws-sdk-go/aws/endpoints"
+	"github.com/aws/aws-sdk-go/aws/request"
+	"github.com/aws/aws-sdk-go/aws/session"
+	"github.com/aws/aws-sdk-go/service/sts"
+	"github.com/aws/aws-sdk-go/service/sts/stsiface"
+	authv1 "k8s.io/api/authentication/v1"
+	v1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/client-go/kubernetes"
+	k8scorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
+	ctrl "sigs.k8s.io/controller-runtime"
+	kclient "sigs.k8s.io/controller-runtime/pkg/client"
+	ctrlcfg "sigs.k8s.io/controller-runtime/pkg/client/config"
+
+	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
+	"github.com/external-secrets/external-secrets/pkg/provider/vault/util"
+)
+
+var (
+	logger = ctrl.Log.WithName("provider").WithName("vault")
+)
+
+const (
+	roleARNAnnotation    = "eks.amazonaws.com/role-arn"
+	audienceAnnotation   = "eks.amazonaws.com/audience"
+	defaultTokenAudience = "sts.amazonaws.com"
+
+	STSEndpointEnv                = "AWS_STS_ENDPOINT"
+	AWSWebIdentityTokenFileEnvVar = "AWS_WEB_IDENTITY_TOKEN_FILE"
+
+	errInvalidClusterStoreMissingAKIDNamespace = "invalid ClusterSecretStore: missing AWS AccessKeyID Namespace"
+	errInvalidClusterStoreMissingSAKNamespace  = "invalid ClusterSecretStore: missing AWS SecretAccessKey Namespace"
+	errFetchAKIDSecret                         = "could not fetch accessKeyID secret: %w"
+	errFetchSAKSecret                          = "could not fetch SecretAccessKey secret: %w"
+	errFetchSTSecret                           = "could not fetch SessionToken secret: %w"
+	errMissingSAK                              = "missing SecretAccessKey"
+	errMissingAKID                             = "missing AccessKeyID"
+)
+
+// DefaultJWTProvider returns a credentials.Provider that calls the AssumeRoleWithWebidentity
+// controller-runtime/client does not support TokenRequest or other subresource APIs
+// so we need to construct our own client and use it to fetch tokens.
+func DefaultJWTProvider(name, namespace, roleArn string, aud []string, region string) (credentials.Provider, error) {
+	cfg, err := ctrlcfg.GetConfig()
+	if err != nil {
+		return nil, err
+	}
+	clientset, err := kubernetes.NewForConfig(cfg)
+	if err != nil {
+		return nil, err
+	}
+	handlers := defaults.Handlers()
+	handlers.Build.PushBack(request.WithAppendUserAgent("external-secrets"))
+	awscfg := aws.NewConfig().WithEndpointResolver(ResolveEndpoint())
+	if region != "" {
+		awscfg.WithRegion(region)
+	}
+	sess, err := session.NewSessionWithOptions(session.Options{
+		Config:            *awscfg,
+		SharedConfigState: session.SharedConfigDisable,
+		Handlers:          handlers,
+	})
+	if err != nil {
+		return nil, err
+	}
+	tokenFetcher := &authTokenFetcher{
+		Namespace:      namespace,
+		Audiences:      aud,
+		ServiceAccount: name,
+		k8sClient:      clientset.CoreV1(),
+	}
+
+	return stscreds.NewWebIdentityRoleProviderWithOptions(
+		sts.New(sess), roleArn, "external-secrets-provider-vault", tokenFetcher), nil
+}
+
+// ResolveEndpoint returns a ResolverFunc with
+// customizable endpoints.
+func ResolveEndpoint() endpoints.ResolverFunc {
+	customEndpoints := make(map[string]string)
+	if v := os.Getenv(STSEndpointEnv); v != "" {
+		customEndpoints["sts"] = v
+	}
+	return ResolveEndpointWithServiceMap(customEndpoints)
+}
+
+func ResolveEndpointWithServiceMap(customEndpoints map[string]string) endpoints.ResolverFunc {
+	defaultResolver := endpoints.DefaultResolver()
+	return func(service, region string, opts ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
+		if ep, ok := customEndpoints[service]; ok {
+			return endpoints.ResolvedEndpoint{
+				URL: ep,
+			}, nil
+		}
+		return defaultResolver.EndpointFor(service, region, opts...)
+	}
+}
+
+// mostly taken from:
+// https://github.com/aws/secrets-store-csi-driver-provider-aws/blob/main/auth/auth.go#L140-L145
+
+type authTokenFetcher struct {
+	Namespace string
+	// Audience is the token aud claim
+	// which is verified by the aws oidc provider
+	// see: https://github.com/external-secrets/external-secrets/issues/1251#issuecomment-1161745849
+	Audiences      []string
+	ServiceAccount string
+	k8sClient      k8scorev1.CoreV1Interface
+}
+
+// FetchToken satisfies the stscreds.TokenFetcher interface
+// it is used to generate service account tokens which are consumed by the aws sdk.
+func (p authTokenFetcher) FetchToken(ctx credentials.Context) ([]byte, error) {
+	logger.V(1).Info("fetching token", "ns", p.Namespace, "sa", p.ServiceAccount)
+	tokRsp, err := p.k8sClient.ServiceAccounts(p.Namespace).CreateToken(ctx, p.ServiceAccount, &authv1.TokenRequest{
+		Spec: authv1.TokenRequestSpec{
+			Audiences: p.Audiences,
+		},
+	}, metav1.CreateOptions{})
+	if err != nil {
+		return nil, fmt.Errorf("error creating service account token: %w", err)
+	}
+	return []byte(tokRsp.Status.Token), nil
+}
+
+// CredsFromServiceAccount uses a Kubernetes Service Account to acquire temporary
+// credentials using aws.AssumeRoleWithWebIdentity. It will assume the role defined
+// in the ServiceAccount annotation.
+// If the ClusterSecretStore does not define a namespace it will use the namespace from the ExternalSecret (referentAuth).
+// If the ClusterSecretStore defines the namespace it will take precedence.
+func CredsFromServiceAccount(ctx context.Context, auth esv1beta1.VaultIamAuth, region string, isClusterKind bool, kube kclient.Client, namespace string, jwtProvider util.JwtProviderFactory) (*credentials.Credentials, error) {
+	name := auth.JWTAuth.ServiceAccountRef.Name
+	if isClusterKind && auth.JWTAuth.ServiceAccountRef.Namespace != nil {
+		namespace = *auth.JWTAuth.ServiceAccountRef.Namespace
+	}
+	sa := v1.ServiceAccount{}
+	err := kube.Get(ctx, types.NamespacedName{
+		Name:      name,
+		Namespace: namespace,
+	}, &sa)
+	if err != nil {
+		return nil, err
+	}
+	// the service account is expected to have a well-known annotation
+	// this is used as input to assumeRoleWithWebIdentity
+	roleArn := sa.Annotations[roleARNAnnotation]
+	if roleArn == "" {
+		return nil, fmt.Errorf("an IAM role must be associated with service account %s (namespace: %s)", name, namespace)
+	}
+
+	tokenAud := sa.Annotations[audienceAnnotation]
+	if tokenAud == "" {
+		tokenAud = defaultTokenAudience
+	}
+	audiences := []string{tokenAud}
+	if len(auth.JWTAuth.ServiceAccountRef.Audiences) > 0 {
+		audiences = append(audiences, auth.JWTAuth.ServiceAccountRef.Audiences...)
+	}
+
+	jwtProv, err := jwtProvider(name, namespace, roleArn, audiences, region)
+	if err != nil {
+		return nil, err
+	}
+
+	logger.V(1).Info("using credentials via service account", "role", roleArn, "region", region)
+	return credentials.NewCredentials(jwtProv), nil
+}
+
+func CredsFromControllerServiceAccount(ctx context.Context, saname, ns, region string, kube kclient.Client, jwtProvider util.JwtProviderFactory) (*credentials.Credentials, error) {
+	name := saname
+	nmspc := ns
+
+	sa := v1.ServiceAccount{}
+	err := kube.Get(ctx, types.NamespacedName{
+		Name:      name,
+		Namespace: nmspc,
+	}, &sa)
+	if err != nil {
+		return nil, err
+	}
+	// the service account is expected to have a well-known annotation
+	// this is used as input to assumeRoleWithWebIdentity
+	roleArn := sa.Annotations[roleARNAnnotation]
+	if roleArn == "" {
+		return nil, fmt.Errorf("an IAM role must be associated with service account %s (namespace: %s)", name, nmspc)
+	}
+
+	tokenAud := sa.Annotations[audienceAnnotation]
+	if tokenAud == "" {
+		tokenAud = defaultTokenAudience
+	}
+	audiences := []string{tokenAud}
+
+	jwtProv, err := jwtProvider(name, nmspc, roleArn, audiences, region)
+	if err != nil {
+		return nil, err
+	}
+
+	logger.V(1).Info("using credentials via service account", "role", roleArn, "region", region)
+	return credentials.NewCredentials(jwtProv), nil
+}
+
+// CredsFromSecretRef pulls access-key / secret-access-key from a secretRef to
+// construct a aws.Credentials object
+// The namespace of the external secret is used if the ClusterSecretStore does not specify a namespace (referentAuth)
+// If the ClusterSecretStore defines a namespace it will take precedence.
+func CredsFromSecretRef(ctx context.Context, auth esv1beta1.VaultIamAuth, isClusterKind bool, kube kclient.Client, namespace string) (*credentials.Credentials, error) {
+	ke := kclient.ObjectKey{
+		Name:      auth.SecretRef.AccessKeyID.Name,
+		Namespace: namespace,
+	}
+	if isClusterKind && auth.SecretRef.AccessKeyID.Namespace != nil {
+		ke.Namespace = *auth.SecretRef.AccessKeyID.Namespace
+	}
+	akSecret := v1.Secret{}
+	err := kube.Get(ctx, ke, &akSecret)
+	if err != nil {
+		return nil, fmt.Errorf(errFetchAKIDSecret, err)
+	}
+	ke = kclient.ObjectKey{
+		Name:      auth.SecretRef.SecretAccessKey.Name,
+		Namespace: namespace,
+	}
+	if isClusterKind && auth.SecretRef.SecretAccessKey.Namespace != nil {
+		ke.Namespace = *auth.SecretRef.SecretAccessKey.Namespace
+	}
+	sakSecret := v1.Secret{}
+	err = kube.Get(ctx, ke, &sakSecret)
+	if err != nil {
+		return nil, fmt.Errorf(errFetchSAKSecret, err)
+	}
+	sak := string(sakSecret.Data[auth.SecretRef.SecretAccessKey.Key])
+	aks := string(akSecret.Data[auth.SecretRef.AccessKeyID.Key])
+	if sak == "" {
+		return nil, fmt.Errorf(errMissingSAK)
+	}
+	if aks == "" {
+		return nil, fmt.Errorf(errMissingAKID)
+	}
+
+	var sessionToken string
+	if auth.SecretRef.SessionToken != nil {
+		ke = kclient.ObjectKey{
+			Name:      auth.SecretRef.SessionToken.Name,
+			Namespace: namespace,
+		}
+		if isClusterKind && auth.SecretRef.SessionToken.Namespace != nil {
+			ke.Namespace = *auth.SecretRef.SessionToken.Namespace
+		}
+		stSecret := v1.Secret{}
+		err = kube.Get(ctx, ke, &stSecret)
+		if err != nil {
+			return nil, fmt.Errorf(errFetchSTSecret, err)
+		}
+		sessionToken = string(stSecret.Data[auth.SecretRef.SessionToken.Key])
+	}
+
+	return credentials.NewStaticCredentials(aks, sak, sessionToken), err
+}
+
+type STSProvider func(*session.Session) stsiface.STSAPI
+
+func DefaultSTSProvider(sess *session.Session) stsiface.STSAPI {
+	return sts.New(sess)
+}
+
+// getAWSSession returns the aws session or an error.
+func GetAWSSession(config *aws.Config) (*session.Session, error) {
+	handlers := defaults.Handlers()
+	handlers.Build.PushBack(request.WithAppendUserAgent("external-secrets"))
+	sess, err := session.NewSessionWithOptions(session.Options{
+		Config:            *config,
+		Handlers:          handlers,
+		SharedConfigState: session.SharedConfigDisable,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return sess, nil
+}

+ 60 - 0
pkg/provider/vault/iamauth/iamauth_test.go

@@ -0,0 +1,60 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package iamauth
+
+import (
+	"context"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	"github.com/external-secrets/external-secrets/pkg/provider/util/fake"
+)
+
+func TestTokenFetcher(t *testing.T) {
+	tf := &authTokenFetcher{
+		ServiceAccount: "foobar",
+		Namespace:      "example",
+		k8sClient:      fake.NewCreateTokenMock().WithToken("FAKETOKEN"),
+	}
+	token, err := tf.FetchToken(context.Background())
+	assert.Nil(t, err)
+	assert.Equal(t, []byte("FAKETOKEN"), token)
+}
+
+func TestResolver(t *testing.T) {
+	tbl := []struct {
+		env     string
+		service string
+		url     string
+	}{
+		{
+			env:     STSEndpointEnv,
+			service: "sts",
+			url:     "http://sts.foo",
+		},
+	}
+
+	for _, item := range tbl {
+		t.Setenv(item.env, item.url)
+	}
+
+	f := ResolveEndpoint()
+
+	for _, item := range tbl {
+		ep, err := f.EndpointFor(item.service, "")
+		assert.Nil(t, err)
+		assert.Equal(t, item.url, ep.URL)
+	}
+}

+ 3 - 0
pkg/provider/vault/util/vault.go

@@ -17,9 +17,12 @@ package util
 import (
 	"context"
 
+	"github.com/aws/aws-sdk-go/aws/credentials"
 	vault "github.com/hashicorp/vault/api"
 )
 
+type JwtProviderFactory func(name, namespace, roleArn string, aud []string, region string) (credentials.Provider, error)
+
 type Auth interface {
 	Login(ctx context.Context, authMethod vault.AuthMethod) (*vault.Secret, error)
 }

+ 192 - 1
pkg/provider/vault/vault.go

@@ -28,9 +28,14 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/aws/aws-sdk-go/aws"
+	"github.com/aws/aws-sdk-go/aws/credentials"
+	"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
 	"github.com/go-logr/logr"
+	"github.com/golang-jwt/jwt/v5"
 	vault "github.com/hashicorp/vault/api"
 	approle "github.com/hashicorp/vault/api/auth/approle"
+	authaws "github.com/hashicorp/vault/api/auth/aws"
 	authkubernetes "github.com/hashicorp/vault/api/auth/kubernetes"
 	authldap "github.com/hashicorp/vault/api/auth/ldap"
 	"github.com/spf13/pflag"
@@ -51,6 +56,7 @@ import (
 	"github.com/external-secrets/external-secrets/pkg/feature"
 	"github.com/external-secrets/external-secrets/pkg/find"
 	"github.com/external-secrets/external-secrets/pkg/provider/metrics"
+	vaultiamauth "github.com/external-secrets/external-secrets/pkg/provider/vault/iamauth"
 	"github.com/external-secrets/external-secrets/pkg/provider/vault/util"
 	"github.com/external-secrets/external-secrets/pkg/utils"
 )
@@ -64,7 +70,9 @@ var (
 )
 
 const (
-	serviceAccTokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
+	serviceAccTokenPath     = "/var/run/secrets/kubernetes.io/serviceaccount/token"
+	defaultAWSRegion        = "us-east-1"
+	defaultAWSAuthMountPath = "aws"
 
 	errVaultStore                   = "received invalid Vault SecretStore resource: %w"
 	errVaultCacheCreate             = "cannot create Vault client cache: %s"
@@ -87,6 +95,11 @@ const (
 	errUnsupportedKvVersion         = "cannot perform find operations with kv version v1"
 	errUnsupportedMetadataKvVersion = "cannot perform metadata fetch operations with kv version v1"
 	errNotFound                     = "secret not found"
+	errIrsaTokenEnvVarNotFoundOnPod = "expected env variable: %s not found on controller's pod"
+	errIrsaTokenFileNotFoundOnPod   = "web ddentity token file not found at %s location: %w"
+	errIrsaTokenFileNotReadable     = "could not read the web identity token from the file %s: %w"
+	errIrsaTokenNotValidJWT         = "could not parse web identity token available at %s. not a valid jwt?: %w"
+	errPodInfoNotFoundOnToken       = "could not find pod identity info on token %s: %w"
 
 	errGetKubeSA             = "cannot get Kubernetes service account %q: %w"
 	errGetKubeSASecrets      = "cannot find secrets bound to service account: %q"
@@ -352,6 +365,29 @@ func (c *Connector) ValidateStore(store esv1beta1.GenericStore) error {
 			return fmt.Errorf(errInvalidTokenRef, err)
 		}
 	}
+	if p.Auth.Iam != nil {
+		if p.Auth.Iam.JWTAuth != nil {
+			if p.Auth.Iam.JWTAuth.ServiceAccountRef != nil {
+				if err := utils.ValidateReferentServiceAccountSelector(store, *p.Auth.Iam.JWTAuth.ServiceAccountRef); err != nil {
+					return fmt.Errorf(errInvalidTokenRef, err)
+				}
+			}
+		}
+
+		if p.Auth.Iam.SecretRef != nil {
+			if err := utils.ValidateReferentSecretSelector(store, p.Auth.Iam.SecretRef.AccessKeyID); err != nil {
+				return fmt.Errorf(errInvalidTokenRef, err)
+			}
+			if err := utils.ValidateReferentSecretSelector(store, p.Auth.Iam.SecretRef.SecretAccessKey); err != nil {
+				return fmt.Errorf(errInvalidTokenRef, err)
+			}
+			if p.Auth.Iam.SecretRef.SessionToken != nil {
+				if err := utils.ValidateReferentSecretSelector(store, *p.Auth.Iam.SecretRef.SessionToken); err != nil {
+					return fmt.Errorf(errInvalidTokenRef, err)
+				}
+			}
+		}
+	}
 	return nil
 }
 
@@ -740,6 +776,15 @@ func isReferentSpec(prov *esv1beta1.VaultProvider) bool {
 	if prov.Auth.Cert != nil && prov.Auth.Cert.SecretRef.Namespace == nil {
 		return true
 	}
+	if prov.Auth.Iam != nil && prov.Auth.Iam.JWTAuth != nil && prov.Auth.Iam.JWTAuth.ServiceAccountRef != nil && prov.Auth.Iam.JWTAuth.ServiceAccountRef.Namespace == nil {
+		return true
+	}
+	if prov.Auth.Iam != nil && prov.Auth.Iam.SecretRef != nil &&
+		(prov.Auth.Iam.SecretRef.AccessKeyID.Namespace == nil ||
+			prov.Auth.Iam.SecretRef.SecretAccessKey.Namespace == nil ||
+			(prov.Auth.Iam.SecretRef.SessionToken != nil && prov.Auth.Iam.SecretRef.SessionToken.Namespace == nil)) {
+		return true
+	}
 	return false
 }
 
@@ -1034,6 +1079,12 @@ func (v *client) setAuth(ctx context.Context, cfg *vault.Config) error {
 		return err
 	}
 
+	tokenExists, err = setIamAuthToken(ctx, v, vaultiamauth.DefaultJWTProvider, vaultiamauth.DefaultSTSProvider)
+	if tokenExists {
+		v.log.V(1).Info("Retrieved new token using IAM auth")
+		return err
+	}
+
 	return errors.New(errAuthFormat)
 }
 
@@ -1110,6 +1161,19 @@ func setCertAuthToken(ctx context.Context, v *client, cfg *vault.Config) (bool,
 	return false, nil
 }
 
+func setIamAuthToken(ctx context.Context, v *client, jwtProvider util.JwtProviderFactory, assumeRoler vaultiamauth.STSProvider) (bool, error) {
+	iamAuth := v.store.Auth.Iam
+	isClusterKind := v.storeKind == esv1beta1.ClusterSecretStoreKind
+	if iamAuth != nil {
+		err := v.requestTokenWithIamAuth(ctx, iamAuth, isClusterKind, v.kube, v.namespace, jwtProvider, assumeRoler)
+		if err != nil {
+			return true, err
+		}
+		return true, nil
+	}
+	return false, nil
+}
+
 func (v *client) secretKeyRefForServiceAccount(ctx context.Context, serviceAccountRef *esmeta.ServiceAccountSelector) (string, error) {
 	serviceAccount := &corev1.ServiceAccount{}
 	ref := types.NamespacedName{
@@ -1407,6 +1471,133 @@ func (v *client) requestTokenWithCertAuth(ctx context.Context, certAuth *esv1bet
 	return nil
 }
 
+func (v *client) requestTokenWithIamAuth(ctx context.Context, iamAuth *esv1beta1.VaultIamAuth, ick bool, k kclient.Client, n string, jwtProvider util.JwtProviderFactory, assumeRoler vaultiamauth.STSProvider) error {
+	jwtAuth := iamAuth.JWTAuth
+	secretRefAuth := iamAuth.SecretRef
+	regionAWS := defaultAWSRegion
+	awsAuthMountPath := defaultAWSAuthMountPath
+	if iamAuth.Region != "" {
+		regionAWS = iamAuth.Region
+	}
+	if iamAuth.Path != "" {
+		awsAuthMountPath = iamAuth.Path
+	}
+	var creds *credentials.Credentials
+	var err error
+	if jwtAuth != nil { // use credentials from a sa explicitly defined and referenced. Highest preference is given to this method/configuration.
+		creds, err = vaultiamauth.CredsFromServiceAccount(ctx, *iamAuth, regionAWS, ick, k, n, jwtProvider)
+		if err != nil {
+			return err
+		}
+	} else if secretRefAuth != nil { // if jwtAuth is not defined, check if secretRef is defined. Second preference.
+		logger.V(1).Info("using credentials from secretRef")
+		creds, err = vaultiamauth.CredsFromSecretRef(ctx, *iamAuth, ick, k, n)
+		if err != nil {
+			return err
+		}
+	}
+
+	// Neither of jwtAuth or secretRefAuth defined. Last preference.
+	// Default to controller pod's identity
+	if jwtAuth == nil && secretRefAuth == nil {
+		// Checking if controller pod's service account is IRSA enabled and Web Identity token is available on pod
+		tknFile, tknFileEnvVarPresent := os.LookupEnv(vaultiamauth.AWSWebIdentityTokenFileEnvVar)
+		if !tknFileEnvVarPresent {
+			return fmt.Errorf(errIrsaTokenEnvVarNotFoundOnPod, vaultiamauth.AWSWebIdentityTokenFileEnvVar) // No Web Identity(IRSA) token found on pod
+		}
+
+		// IRSA enabled service account, let's check that the jwt token filemount and file exists
+		if _, err := os.Stat(tknFile); err != nil {
+			return fmt.Errorf(errIrsaTokenFileNotFoundOnPod, tknFile, err)
+		}
+
+		// everything looks good so far, let's fetch the jwt token from AWS_WEB_IDENTITY_TOKEN_FILE
+		jwtByte, err := os.ReadFile(tknFile)
+		if err != nil {
+			return fmt.Errorf(errIrsaTokenFileNotReadable, tknFile, err)
+		}
+
+		// let's parse the jwt token
+		parser := jwt.NewParser(jwt.WithoutClaimsValidation())
+
+		token, _, err := parser.ParseUnverified(string(jwtByte), jwt.MapClaims{})
+		if err != nil {
+			return fmt.Errorf(errIrsaTokenNotValidJWT, tknFile, err) // JWT token parser error
+		}
+
+		var ns string
+		var sa string
+
+		// let's fetch the namespace and serviceaccount from parsed jwt token
+		if claims, ok := token.Claims.(jwt.MapClaims); ok {
+			ns = claims["kubernetes.io"].(map[string]interface{})["namespace"].(string)
+			sa = claims["kubernetes.io"].(map[string]interface{})["serviceaccount"].(map[string]interface{})["name"].(string)
+		} else {
+			return fmt.Errorf(errPodInfoNotFoundOnToken, tknFile, err)
+		}
+
+		creds, err = vaultiamauth.CredsFromControllerServiceAccount(ctx, sa, ns, regionAWS, k, jwtProvider)
+		if err != nil {
+			return err
+		}
+	}
+
+	config := aws.NewConfig().WithEndpointResolver(vaultiamauth.ResolveEndpoint())
+	if creds != nil {
+		config.WithCredentials(creds)
+	}
+
+	if regionAWS != "" {
+		config.WithRegion(regionAWS)
+	}
+
+	sess, err := vaultiamauth.GetAWSSession(config)
+	if err != nil {
+		return err
+	}
+	if iamAuth.AWSIAMRole != "" {
+		stsclient := assumeRoler(sess)
+		if iamAuth.ExternalID != "" {
+			var setExternalID = func(p *stscreds.AssumeRoleProvider) {
+				p.ExternalID = aws.String(iamAuth.ExternalID)
+			}
+			sess.Config.WithCredentials(stscreds.NewCredentialsWithClient(stsclient, iamAuth.AWSIAMRole, setExternalID))
+		} else {
+			sess.Config.WithCredentials(stscreds.NewCredentialsWithClient(stsclient, iamAuth.AWSIAMRole))
+		}
+	}
+
+	getCreds, err := sess.Config.Credentials.Get()
+	if err != nil {
+		return err
+	}
+	// Set environment variables. These would be fetched by Login
+	os.Setenv("AWS_ACCESS_KEY_ID", getCreds.AccessKeyID)
+	os.Setenv("AWS_SECRET_ACCESS_KEY", getCreds.SecretAccessKey)
+	os.Setenv("AWS_SESSION_TOKEN", getCreds.SessionToken)
+
+	var awsAuthClient *authaws.AWSAuth
+
+	if iamAuth.VaultAWSIAMServerID != "" {
+		awsAuthClient, err = authaws.NewAWSAuth(authaws.WithRegion(regionAWS), authaws.WithIAMAuth(), authaws.WithRole(iamAuth.Role), authaws.WithMountPath(awsAuthMountPath), authaws.WithIAMServerIDHeader(iamAuth.VaultAWSIAMServerID))
+		if err != nil {
+			return err
+		}
+	} else {
+		awsAuthClient, err = authaws.NewAWSAuth(authaws.WithRegion(regionAWS), authaws.WithIAMAuth(), authaws.WithRole(iamAuth.Role), authaws.WithMountPath(awsAuthMountPath))
+		if err != nil {
+			return err
+		}
+	}
+
+	_, err = v.auth.Login(ctx, awsAuthClient)
+	metrics.ObserveAPICall(metrics.ProviderHCVault, metrics.CallHCVaultLogin, err)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
 func init() {
 	var vaultTokenCacheSize int
 	fs := pflag.NewFlagSet("vault", pflag.ExitOnError)

+ 62 - 0
pkg/provider/vault/vault_test.go

@@ -161,6 +161,45 @@ func makeInvalidClusterSecretStoreWithK8sCerts() *esv1beta1.ClusterSecretStore {
 	}
 }
 
+func makeValidSecretStoreWithIamAuthSecret() *esv1beta1.SecretStore {
+	return &esv1beta1.SecretStore{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      "vault-store",
+			Namespace: "default",
+		},
+		Spec: esv1beta1.SecretStoreSpec{
+			Provider: &esv1beta1.SecretStoreProvider{
+				Vault: &esv1beta1.VaultProvider{
+					Server:  "https://vault.example.com:8200",
+					Path:    &secretStorePath,
+					Version: esv1beta1.VaultKVStoreV2,
+					Auth: esv1beta1.VaultAuth{
+						Iam: &esv1beta1.VaultIamAuth{
+							Path:   "aws",
+							Region: "us-east-1",
+							Role:   "vault-role",
+							SecretRef: &esv1beta1.VaultAwsAuthSecretRef{
+								AccessKeyID: esmeta.SecretKeySelector{
+									Name: "vault-iam-creds-secret",
+									Key:  "access-key",
+								},
+								SecretAccessKey: esmeta.SecretKeySelector{
+									Name: "vault-iam-creds-secret",
+									Key:  "secret-access-key",
+								},
+								SessionToken: &esmeta.SecretKeySelector{
+									Name: "vault-iam-creds-secret",
+									Key:  "secret-session-token",
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
 type secretStoreTweakFn func(s *esv1beta1.SecretStore)
 
 func makeSecretStore(tweaks ...secretStoreTweakFn) *esv1beta1.SecretStore {
@@ -335,6 +374,29 @@ MIIFkTCCA3mgAwIBAgIUBEUg3m/WqAsWHG4Q/II3IePFfuowDQYJKoZIhvcNAQELBQAwWDELMAkGA1UE
 				err: fmt.Errorf(errVaultCert, errors.New(`cannot find secret data for key: "cert"`)),
 			},
 		},
+		"SuccessfulVaultStoreWithIamAuthSecret": {
+			reason: "Should return a Vault provider successfully",
+			args: args{
+				store: makeValidSecretStoreWithIamAuthSecret(),
+				ns:    "default",
+				kube: clientfake.NewClientBuilder().WithObjects(&corev1.Secret{
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      "vault-iam-creds-secret",
+						Namespace: "default",
+					},
+					Data: map[string][]byte{
+						"access-key":           []byte("TESTING"),
+						"secret-access-key":    []byte("ABCDEF"),
+						"secret-session-token": []byte("c2VjcmV0LXNlc3Npb24tdG9rZW4K"),
+					},
+				}).Build(),
+				corev1:        utilfake.NewCreateTokenMock().WithToken("ok"),
+				newClientFunc: fake.ClientWithLoginMock,
+			},
+			want: want{
+				err: nil,
+			},
+		},
 		"SuccessfulVaultStoreWithK8sCertConfigMap": {
 			reason: "Should return a Vault prodvider with the cert from k8s",
 			args: args{