Explorar el Código

feat: adds sts session token generator

Signed-off-by: Gustavo Carvalho <gustavo.carvalho@container-solutions.com>
Gustavo Carvalho hace 2 semanas
padre
commit
625fc7efaf
Se han modificado 33 ficheros con 1815 adiciones y 13 borrados
  1. 13 0
      AGENTS.md
  2. 1 1
      apis/externalsecrets/v1/externalsecret_types.go
  3. 1 1
      apis/externalsecrets/v1beta1/externalsecret_types.go
  4. 3 0
      apis/generators/v1alpha1/register.go
  5. 4 1
      apis/generators/v1alpha1/types_cluster.go
  6. 81 0
      apis/generators/v1alpha1/types_stsassumerole.go
  7. 109 0
      apis/generators/v1alpha1/zz_generated.deepcopy.go
  8. 4 0
      config/crds/bases/external-secrets.io_clusterexternalsecrets.yaml
  9. 1 0
      config/crds/bases/external-secrets.io_clusterpushsecrets.yaml
  10. 4 0
      config/crds/bases/external-secrets.io_externalsecrets.yaml
  11. 1 0
      config/crds/bases/external-secrets.io_pushsecrets.yaml
  12. 165 0
      config/crds/bases/generators.external-secrets.io_clustergenerators.yaml
  13. 215 0
      config/crds/bases/generators.external-secrets.io_stsassumeroletokens.yaml
  14. 1 0
      config/crds/bases/kustomization.yaml
  15. 1 0
      deploy/charts/external-secrets/templates/rbac.yaml
  16. 377 0
      deploy/crds/bundle.yaml
  17. 48 0
      docs/api/generator/stsassumerole.md
  18. 14 0
      docs/snippets/generator-stsassumerole-example.yaml
  19. 39 0
      docs/snippets/generator-stsassumerole.yaml
  20. 95 0
      generators/v1/stsassumerole/go.mod
  21. 211 0
      generators/v1/stsassumerole/go.sum
  22. 154 0
      generators/v1/stsassumerole/stsassumerole.go
  23. 222 0
      generators/v1/stsassumerole/stsassumerole_test.go
  24. 2 0
      go.mod
  25. 1 0
      hack/api-docs/mkdocs.yml
  26. 2 0
      pkg/register/generators.go
  27. 11 0
      runtime/esutils/resolvers/generator.go
  28. 2 2
      tests/__snapshot__/clusterexternalsecret-v1.yaml
  29. 2 2
      tests/__snapshot__/clusterexternalsecret-v1beta1.yaml
  30. 26 1
      tests/__snapshot__/clustergenerator-v1alpha1.yaml
  31. 2 2
      tests/__snapshot__/externalsecret-v1.yaml
  32. 2 2
      tests/__snapshot__/externalsecret-v1beta1.yaml
  33. 1 1
      tests/__snapshot__/pushsecret-v1alpha1.yaml

+ 13 - 0
AGENTS.md

@@ -221,3 +221,16 @@ pattern, but expect to be the first.
 - Docs page + snippets.
 - mkdocs nav entry.
 - After adding the module to `go.work`, run `go work use` to reconcile the `go` directive version.
+
+## Expected Flow
+- Do your best to implement all the changes needed as provided by the user
+- After finishing your implementations; Show the user your changes so they can review and COMPREHEND THEM
+- Confirm the user understood the implementation. If they confirmed they understood the implementation, and any gotchas you might be aware of,
+only then, wait for the user to commit the changes.
+- After that is done, add the needed git notes to that hash.
+- Ask the user to push the changes / notes. (never do the commit or push yourself
+
+## Restrictions
+- NEVER update v1beta1. It is deprecated and maintained for compatibility purposes only -- new features are never added there
+- NEVER run `git commit`, `git push`, or any variation thereof. All commits and pushes are done manually by the user.
+- NEVER stage commits!

+ 1 - 1
apis/externalsecrets/v1/externalsecret_types.go

@@ -593,7 +593,7 @@ type GeneratorRef struct {
 	APIVersion string `json:"apiVersion,omitempty"`
 
 	// Specify the Kind of the generator resource
-	// +kubebuilder:validation:Enum=ACRAccessToken;ClusterGenerator;CloudsmithAccessToken;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana;MFA
+	// +kubebuilder:validation:Enum=ACRAccessToken;ClusterGenerator;CloudsmithAccessToken;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSAssumeRoleToken;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana;MFA
 	Kind string `json:"kind"`
 
 	// Specify the name of the generator resource

+ 1 - 1
apis/externalsecrets/v1beta1/externalsecret_types.go

@@ -480,7 +480,7 @@ type GeneratorRef struct {
 	APIVersion string `json:"apiVersion,omitempty"`
 
 	// Specify the Kind of the generator resource
-	// +kubebuilder:validation:Enum=ACRAccessToken;ClusterGenerator;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana
+	// +kubebuilder:validation:Enum=ACRAccessToken;ClusterGenerator;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSAssumeRoleToken;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana
 	Kind string `json:"kind"`
 
 	// Specify the name of the generator resource

+ 3 - 0
apis/generators/v1alpha1/register.go

@@ -73,6 +73,8 @@ var (
 	ClusterGeneratorKind = reflect.TypeFor[ClusterGenerator]().Name()
 	// CloudsmithAccessTokenKind is the kind name for CloudsmithAccessToken resource.
 	CloudsmithAccessTokenKind = reflect.TypeFor[CloudsmithAccessToken]().Name()
+	// STSAssumeRoleTokenKind is the kind name for STSAssumeRoleToken resource.
+	STSAssumeRoleTokenKind = reflect.TypeFor[STSAssumeRoleToken]().Name()
 )
 
 func init() {
@@ -103,6 +105,7 @@ func init() {
 	SchemeBuilder.Register(&QuayAccessToken{}, &QuayAccessTokenList{})
 	SchemeBuilder.Register(&Password{}, &PasswordList{})
 	SchemeBuilder.Register(&SSHKey{}, &SSHKeyList{})
+	SchemeBuilder.Register(&STSAssumeRoleToken{}, &STSAssumeRoleTokenList{})
 	SchemeBuilder.Register(&STSSessionToken{}, &STSSessionTokenList{})
 	SchemeBuilder.Register(&UUID{}, &UUIDList{})
 	SchemeBuilder.Register(&VaultDynamicSecret{}, &VaultDynamicSecretList{})

+ 4 - 1
apis/generators/v1alpha1/types_cluster.go

@@ -30,7 +30,7 @@ type ClusterGeneratorSpec struct {
 }
 
 // GeneratorKind represents a kind of generator.
-// +kubebuilder:validation:Enum=ACRAccessToken;CloudsmithAccessToken;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana
+// +kubebuilder:validation:Enum=ACRAccessToken;CloudsmithAccessToken;ECRAuthorizationToken;Fake;GCRAccessToken;GithubAccessToken;QuayAccessToken;Password;SSHKey;STSAssumeRoleToken;STSSessionToken;UUID;VaultDynamicSecret;Webhook;Grafana
 type GeneratorKind string
 
 const (
@@ -50,6 +50,8 @@ const (
 	GeneratorKindPassword GeneratorKind = "Password"
 	// GeneratorKindSSHKey represents an SSH key generator.
 	GeneratorKindSSHKey GeneratorKind = "SSHKey"
+	// GeneratorKindSTSAssumeRoleToken represents an AWS STS AssumeRole token generator.
+	GeneratorKindSTSAssumeRoleToken GeneratorKind = "STSAssumeRoleToken"
 	// GeneratorKindSTSSessionToken represents an AWS STS session token generator.
 	GeneratorKindSTSSessionToken GeneratorKind = "STSSessionToken"
 	// GeneratorKindUUID represents a UUID generator.
@@ -79,6 +81,7 @@ type GeneratorSpec struct {
 	QuayAccessTokenSpec       *QuayAccessTokenSpec       `json:"quayAccessTokenSpec,omitempty"`
 	PasswordSpec              *PasswordSpec              `json:"passwordSpec,omitempty"`
 	SSHKeySpec                *SSHKeySpec                `json:"sshKeySpec,omitempty"`
+	STSAssumeRoleTokenSpec    *STSAssumeRoleTokenSpec    `json:"stsAssumeRoleTokenSpec,omitempty"`
 	STSSessionTokenSpec       *STSSessionTokenSpec       `json:"stsSessionTokenSpec,omitempty"`
 	UUIDSpec                  *UUIDSpec                  `json:"uuidSpec,omitempty"`
 	VaultDynamicSecretSpec    *VaultDynamicSecretSpec    `json:"vaultDynamicSecretSpec,omitempty"`

+ 81 - 0
apis/generators/v1alpha1/types_stsassumerole.go

@@ -0,0 +1,81 @@
+/*
+Copyright © The ESO Authors
+
+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
+
+    https://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 v1alpha1
+
+import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// AssumeRoleRequestParameters contains parameters for the STS AssumeRole call.
+type AssumeRoleRequestParameters struct {
+	// SessionDuration The duration, in seconds, of the role session.
+	// The value can range from 900 seconds (15 minutes) to the maximum session
+	// duration setting for the role. If not specified, the default is 1 hour.
+	// +optional
+	SessionDuration *int32 `json:"sessionDuration,omitempty"`
+
+	// ExternalID is a unique identifier that might be required when you assume a
+	// role in another account. If the administrator of the account to which the
+	// role belongs provided you with an external ID, then provide that value.
+	// +optional
+	ExternalID *string `json:"externalID,omitempty"`
+}
+
+// STSAssumeRoleTokenSpec defines the desired state to generate temporary AWS credentials
+// via sts:AssumeRole. Unlike STSSessionToken, this generator works with both long-term
+// credentials and temporary credentials (e.g. IRSA / pod identity).
+type STSAssumeRoleTokenSpec struct {
+	// Region specifies the AWS region to operate in.
+	Region string `json:"region"`
+
+	// Role is the ARN of the IAM role to assume.
+	// +kubebuilder:validation:MinLength=1
+	Role string `json:"role"`
+
+	// Auth defines how to authenticate with AWS.
+	// +optional
+	Auth AWSAuth `json:"auth,omitempty"`
+
+	// RequestParameters contains optional parameters for the AssumeRole call.
+	// +optional
+	RequestParameters *AssumeRoleRequestParameters `json:"requestParameters,omitempty"`
+}
+
+// STSAssumeRoleToken uses sts:AssumeRole to obtain temporary AWS credentials.
+// Unlike STSSessionToken (which calls GetSessionToken), this generator works with
+// both long-term IAM credentials and temporary credentials such as IRSA pod identity,
+// making it suitable for any environment including on-premises clusters.
+// +kubebuilder:object:root=true
+// +kubebuilder:storageversion
+// +kubebuilder:subresource:status
+// +kubebuilder:metadata:labels="external-secrets.io/component=controller"
+// +kubebuilder:resource:scope=Namespaced,categories={external-secrets, external-secrets-generators}
+type STSAssumeRoleToken struct {
+	metav1.TypeMeta   `json:",inline"`
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	Spec STSAssumeRoleTokenSpec `json:"spec,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// STSAssumeRoleTokenList contains a list of STSAssumeRoleToken resources.
+type STSAssumeRoleTokenList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []STSAssumeRoleToken `json:"items"`
+}

+ 109 - 0
apis/generators/v1alpha1/zz_generated.deepcopy.go

@@ -199,6 +199,31 @@ func (in *AWSJWTAuth) DeepCopy() *AWSJWTAuth {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AssumeRoleRequestParameters) DeepCopyInto(out *AssumeRoleRequestParameters) {
+	*out = *in
+	if in.SessionDuration != nil {
+		in, out := &in.SessionDuration, &out.SessionDuration
+		*out = new(int32)
+		**out = **in
+	}
+	if in.ExternalID != nil {
+		in, out := &in.ExternalID, &out.ExternalID
+		*out = new(string)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssumeRoleRequestParameters.
+func (in *AssumeRoleRequestParameters) DeepCopy() *AssumeRoleRequestParameters {
+	if in == nil {
+		return nil
+	}
+	out := new(AssumeRoleRequestParameters)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AuthorizationProtocol) DeepCopyInto(out *AuthorizationProtocol) {
 	*out = *in
@@ -789,6 +814,11 @@ func (in *GeneratorSpec) DeepCopyInto(out *GeneratorSpec) {
 		*out = new(SSHKeySpec)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.STSAssumeRoleTokenSpec != nil {
+		in, out := &in.STSAssumeRoleTokenSpec, &out.STSAssumeRoleTokenSpec
+		*out = new(STSAssumeRoleTokenSpec)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.STSSessionTokenSpec != nil {
 		in, out := &in.STSSessionTokenSpec, &out.STSSessionTokenSpec
 		*out = new(STSSessionTokenSpec)
@@ -1627,6 +1657,85 @@ func (in *SSHKeySpec) DeepCopy() *SSHKeySpec {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *STSAssumeRoleToken) DeepCopyInto(out *STSAssumeRoleToken) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new STSAssumeRoleToken.
+func (in *STSAssumeRoleToken) DeepCopy() *STSAssumeRoleToken {
+	if in == nil {
+		return nil
+	}
+	out := new(STSAssumeRoleToken)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *STSAssumeRoleToken) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *STSAssumeRoleTokenList) DeepCopyInto(out *STSAssumeRoleTokenList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]STSAssumeRoleToken, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new STSAssumeRoleTokenList.
+func (in *STSAssumeRoleTokenList) DeepCopy() *STSAssumeRoleTokenList {
+	if in == nil {
+		return nil
+	}
+	out := new(STSAssumeRoleTokenList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *STSAssumeRoleTokenList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *STSAssumeRoleTokenSpec) DeepCopyInto(out *STSAssumeRoleTokenSpec) {
+	*out = *in
+	in.Auth.DeepCopyInto(&out.Auth)
+	if in.RequestParameters != nil {
+		in, out := &in.RequestParameters, &out.RequestParameters
+		*out = new(AssumeRoleRequestParameters)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new STSAssumeRoleTokenSpec.
+func (in *STSAssumeRoleTokenSpec) DeepCopy() *STSAssumeRoleTokenSpec {
+	if in == nil {
+		return nil
+	}
+	out := new(STSAssumeRoleTokenSpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *STSSessionToken) DeepCopyInto(out *STSSessionToken) {
 	*out = *in

+ 4 - 0
config/crds/bases/external-secrets.io_clusterexternalsecrets.yaml

@@ -177,6 +177,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -443,6 +444,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -1059,6 +1061,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -1263,6 +1266,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret

+ 1 - 0
config/crds/bases/external-secrets.io_clusterpushsecrets.yaml

@@ -437,6 +437,7 @@ spec:
                             - QuayAccessToken
                             - Password
                             - SSHKey
+                            - STSAssumeRoleToken
                             - STSSessionToken
                             - UUID
                             - VaultDynamicSecret

+ 4 - 0
config/crds/bases/external-secrets.io_externalsecrets.yaml

@@ -162,6 +162,7 @@ spec:
                               - QuayAccessToken
                               - Password
                               - SSHKey
+                              - STSAssumeRoleToken
                               - STSSessionToken
                               - UUID
                               - VaultDynamicSecret
@@ -426,6 +427,7 @@ spec:
                               - QuayAccessToken
                               - Password
                               - SSHKey
+                              - STSAssumeRoleToken
                               - STSSessionToken
                               - UUID
                               - VaultDynamicSecret
@@ -910,6 +912,7 @@ spec:
                               - QuayAccessToken
                               - Password
                               - SSHKey
+                              - STSAssumeRoleToken
                               - STSSessionToken
                               - UUID
                               - VaultDynamicSecret
@@ -1113,6 +1116,7 @@ spec:
                               - QuayAccessToken
                               - Password
                               - SSHKey
+                              - STSAssumeRoleToken
                               - STSSessionToken
                               - UUID
                               - VaultDynamicSecret

+ 1 - 0
config/crds/bases/external-secrets.io_pushsecrets.yaml

@@ -360,6 +360,7 @@ spec:
                         - QuayAccessToken
                         - Password
                         - SSHKey
+                        - STSAssumeRoleToken
                         - STSSessionToken
                         - UUID
                         - VaultDynamicSecret

+ 165 - 0
config/crds/bases/generators.external-secrets.io_clustergenerators.yaml

@@ -1006,6 +1006,170 @@ spec:
                         - ed25519
                         type: string
                     type: object
+                  stsAssumeRoleTokenSpec:
+                    description: |-
+                      STSAssumeRoleTokenSpec defines the desired state to generate temporary AWS credentials
+                      via sts:AssumeRole. Unlike STSSessionToken, this generator works with both long-term
+                      credentials and temporary credentials (e.g. IRSA / pod identity).
+                    properties:
+                      auth:
+                        description: Auth defines how to authenticate with AWS.
+                        properties:
+                          jwt:
+                            description: AWSJWTAuth provides configuration to authenticate
+                              against AWS using service account tokens.
+                            properties:
+                              serviceAccountRef:
+                                description: ServiceAccountSelector is 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.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      Namespace of the resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                          secretRef:
+                            description: |-
+                              AWSAuthSecretRef holds secret references for AWS credentials
+                              both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                            properties:
+                              accessKeyIDSecretRef:
+                                description: The AccessKeyID is used for authentication
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                              secretAccessKeySecretRef:
+                                description: The SecretAccessKey is used for authentication
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    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: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            type: object
+                        type: object
+                      region:
+                        description: Region specifies the AWS region to operate in.
+                        type: string
+                      requestParameters:
+                        description: RequestParameters contains optional parameters
+                          for the AssumeRole call.
+                        properties:
+                          externalID:
+                            description: |-
+                              ExternalID is a unique identifier that might be required when you assume a
+                              role in another account. If the administrator of the account to which the
+                              role belongs provided you with an external ID, then provide that value.
+                            type: string
+                          sessionDuration:
+                            description: |-
+                              SessionDuration The duration, in seconds, of the role session.
+                              The value can range from 900 seconds (15 minutes) to the maximum session
+                              duration setting for the role. If not specified, the default is 1 hour.
+                            format: int32
+                            type: integer
+                        type: object
+                      role:
+                        description: Role is the ARN of the IAM role to assume.
+                        minLength: 1
+                        type: string
+                    required:
+                    - region
+                    - role
+                    type: object
                   stsSessionTokenSpec:
                     description: STSSessionTokenSpec defines the desired state to
                       generate an AWS STS session token.
@@ -2391,6 +2555,7 @@ spec:
                 - QuayAccessToken
                 - Password
                 - SSHKey
+                - STSAssumeRoleToken
                 - STSSessionToken
                 - UUID
                 - VaultDynamicSecret

+ 215 - 0
config/crds/bases/generators.external-secrets.io_stsassumeroletokens.yaml

@@ -0,0 +1,215 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    external-secrets.io/component: controller
+  name: stsassumeroletokens.generators.external-secrets.io
+spec:
+  group: generators.external-secrets.io
+  names:
+    categories:
+    - external-secrets
+    - external-secrets-generators
+    kind: STSAssumeRoleToken
+    listKind: STSAssumeRoleTokenList
+    plural: stsassumeroletokens
+    singular: stsassumeroletoken
+  scope: Namespaced
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        description: |-
+          STSAssumeRoleToken uses sts:AssumeRole to obtain temporary AWS credentials.
+          Unlike STSSessionToken (which calls GetSessionToken), this generator works with
+          both long-term IAM credentials and temporary credentials such as IRSA pod identity,
+          making it suitable for any environment including on-premises clusters.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: |-
+              STSAssumeRoleTokenSpec defines the desired state to generate temporary AWS credentials
+              via sts:AssumeRole. Unlike STSSessionToken, this generator works with both long-term
+              credentials and temporary credentials (e.g. IRSA / pod identity).
+            properties:
+              auth:
+                description: Auth defines how to authenticate with AWS.
+                properties:
+                  jwt:
+                    description: AWSJWTAuth provides configuration to authenticate
+                      against AWS using service account tokens.
+                    properties:
+                      serviceAccountRef:
+                        description: ServiceAccountSelector is 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.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace of the resource being referred to.
+                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                        required:
+                        - name
+                        type: object
+                    type: object
+                  secretRef:
+                    description: |-
+                      AWSAuthSecretRef holds secret references for AWS credentials
+                      both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                    properties:
+                      accessKeyIDSecretRef:
+                        description: The AccessKeyID is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              A key in the referenced Secret.
+                              Some instances of this field may be defaulted, in others it may be required.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace of the Secret resource being referred to.
+                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                        type: object
+                      secretAccessKeySecretRef:
+                        description: The SecretAccessKey is used for authentication
+                        properties:
+                          key:
+                            description: |-
+                              A key in the referenced Secret.
+                              Some instances of this field may be defaulted, in others it may be required.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace of the Secret resource being referred to.
+                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            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: |-
+                              A key in the referenced Secret.
+                              Some instances of this field may be defaulted, in others it may be required.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the Secret resource being referred
+                              to.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace of the Secret resource being referred to.
+                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                        type: object
+                    type: object
+                type: object
+              region:
+                description: Region specifies the AWS region to operate in.
+                type: string
+              requestParameters:
+                description: RequestParameters contains optional parameters for the
+                  AssumeRole call.
+                properties:
+                  externalID:
+                    description: |-
+                      ExternalID is a unique identifier that might be required when you assume a
+                      role in another account. If the administrator of the account to which the
+                      role belongs provided you with an external ID, then provide that value.
+                    type: string
+                  sessionDuration:
+                    description: |-
+                      SessionDuration The duration, in seconds, of the role session.
+                      The value can range from 900 seconds (15 minutes) to the maximum session
+                      duration setting for the role. If not specified, the default is 1 hour.
+                    format: int32
+                    type: integer
+                type: object
+              role:
+                description: Role is the ARN of the IAM role to assume.
+                minLength: 1
+                type: string
+            required:
+            - region
+            - role
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}

+ 1 - 0
config/crds/bases/kustomization.yaml

@@ -21,6 +21,7 @@ resources:
   - generators.external-secrets.io_passwords.yaml
   - generators.external-secrets.io_quayaccesstokens.yaml
   - generators.external-secrets.io_sshkeys.yaml
+  - generators.external-secrets.io_stsassumeroletokens.yaml
   - generators.external-secrets.io_stssessiontokens.yaml
   - generators.external-secrets.io_uuids.yaml
   - generators.external-secrets.io_vaultdynamicsecrets.yaml

+ 1 - 0
deploy/charts/external-secrets/templates/rbac.yaml

@@ -107,6 +107,7 @@ rules:
     - "quayaccesstokens"
     - "passwords"
     - "sshkeys"
+    - "stsassumeroletokens"
     - "stssessiontokens"
     - "uuids"
     - "vaultdynamicsecrets"

+ 377 - 0
deploy/crds/bundle.yaml

@@ -166,6 +166,7 @@ spec:
                                       - QuayAccessToken
                                       - Password
                                       - SSHKey
+                                      - STSAssumeRoleToken
                                       - STSSessionToken
                                       - UUID
                                       - VaultDynamicSecret
@@ -415,6 +416,7 @@ spec:
                                       - QuayAccessToken
                                       - Password
                                       - SSHKey
+                                      - STSAssumeRoleToken
                                       - STSSessionToken
                                       - UUID
                                       - VaultDynamicSecret
@@ -985,6 +987,7 @@ spec:
                                       - QuayAccessToken
                                       - Password
                                       - SSHKey
+                                      - STSAssumeRoleToken
                                       - STSSessionToken
                                       - UUID
                                       - VaultDynamicSecret
@@ -1178,6 +1181,7 @@ spec:
                                       - QuayAccessToken
                                       - Password
                                       - SSHKey
+                                      - STSAssumeRoleToken
                                       - STSSessionToken
                                       - UUID
                                       - VaultDynamicSecret
@@ -1985,6 +1989,7 @@ spec:
                                 - QuayAccessToken
                                 - Password
                                 - SSHKey
+                                - STSAssumeRoleToken
                                 - STSSessionToken
                                 - UUID
                                 - VaultDynamicSecret
@@ -12701,6 +12706,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -12950,6 +12956,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -13406,6 +13413,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -13599,6 +13607,7 @@ spec:
                                   - QuayAccessToken
                                   - Password
                                   - SSHKey
+                                  - STSAssumeRoleToken
                                   - STSSessionToken
                                   - UUID
                                   - VaultDynamicSecret
@@ -14233,6 +14242,7 @@ spec:
                             - QuayAccessToken
                             - Password
                             - SSHKey
+                            - STSAssumeRoleToken
                             - STSSessionToken
                             - UUID
                             - VaultDynamicSecret
@@ -26064,6 +26074,163 @@ spec:
                             - ed25519
                           type: string
                       type: object
+                    stsAssumeRoleTokenSpec:
+                      description: |-
+                        STSAssumeRoleTokenSpec defines the desired state to generate temporary AWS credentials
+                        via sts:AssumeRole. Unlike STSSessionToken, this generator works with both long-term
+                        credentials and temporary credentials (e.g. IRSA / pod identity).
+                      properties:
+                        auth:
+                          description: Auth defines how to authenticate with AWS.
+                          properties:
+                            jwt:
+                              description: AWSJWTAuth provides configuration to authenticate against AWS using service account tokens.
+                              properties:
+                                serviceAccountRef:
+                                  description: ServiceAccountSelector is 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.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                      type: string
+                                    namespace:
+                                      description: |-
+                                        Namespace of the resource being referred to.
+                                        Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                      maxLength: 63
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                      type: string
+                                  required:
+                                    - name
+                                  type: object
+                              type: object
+                            secretRef:
+                              description: |-
+                                AWSAuthSecretRef holds secret references for AWS credentials
+                                both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                              properties:
+                                accessKeyIDSecretRef:
+                                  description: The AccessKeyID is used for authentication
+                                  properties:
+                                    key:
+                                      description: |-
+                                        A key in the referenced Secret.
+                                        Some instances of this field may be defaulted, in others it may be required.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[-._a-zA-Z0-9]+$
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                      type: string
+                                    namespace:
+                                      description: |-
+                                        The namespace of the Secret resource being referred to.
+                                        Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                      maxLength: 63
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                      type: string
+                                  type: object
+                                secretAccessKeySecretRef:
+                                  description: The SecretAccessKey is used for authentication
+                                  properties:
+                                    key:
+                                      description: |-
+                                        A key in the referenced Secret.
+                                        Some instances of this field may be defaulted, in others it may be required.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[-._a-zA-Z0-9]+$
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                      type: string
+                                    namespace:
+                                      description: |-
+                                        The namespace of the Secret resource being referred to.
+                                        Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                      maxLength: 63
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                      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: |-
+                                        A key in the referenced Secret.
+                                        Some instances of this field may be defaulted, in others it may be required.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[-._a-zA-Z0-9]+$
+                                      type: string
+                                    name:
+                                      description: The name of the Secret resource being referred to.
+                                      maxLength: 253
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                      type: string
+                                    namespace:
+                                      description: |-
+                                        The namespace of the Secret resource being referred to.
+                                        Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                      maxLength: 63
+                                      minLength: 1
+                                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                      type: string
+                                  type: object
+                              type: object
+                          type: object
+                        region:
+                          description: Region specifies the AWS region to operate in.
+                          type: string
+                        requestParameters:
+                          description: RequestParameters contains optional parameters for the AssumeRole call.
+                          properties:
+                            externalID:
+                              description: |-
+                                ExternalID is a unique identifier that might be required when you assume a
+                                role in another account. If the administrator of the account to which the
+                                role belongs provided you with an external ID, then provide that value.
+                              type: string
+                            sessionDuration:
+                              description: |-
+                                SessionDuration The duration, in seconds, of the role session.
+                                The value can range from 900 seconds (15 minutes) to the maximum session
+                                duration setting for the role. If not specified, the default is 1 hour.
+                              format: int32
+                              type: integer
+                          type: object
+                        role:
+                          description: Role is the ARN of the IAM role to assume.
+                          minLength: 1
+                          type: string
+                      required:
+                        - region
+                        - role
+                      type: object
                     stsSessionTokenSpec:
                       description: STSSessionTokenSpec defines the desired state to generate an AWS STS session token.
                       properties:
@@ -27373,6 +27540,7 @@ spec:
                     - QuayAccessToken
                     - Password
                     - SSHKey
+                    - STSAssumeRoleToken
                     - STSSessionToken
                     - UUID
                     - VaultDynamicSecret
@@ -28636,6 +28804,215 @@ spec:
 ---
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    external-secrets.io/component: controller
+  name: stsassumeroletokens.generators.external-secrets.io
+spec:
+  group: generators.external-secrets.io
+  names:
+    categories:
+      - external-secrets
+      - external-secrets-generators
+    kind: STSAssumeRoleToken
+    listKind: STSAssumeRoleTokenList
+    plural: stsassumeroletokens
+    singular: stsassumeroletoken
+  scope: Namespaced
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          description: |-
+            STSAssumeRoleToken uses sts:AssumeRole to obtain temporary AWS credentials.
+            Unlike STSSessionToken (which calls GetSessionToken), this generator works with
+            both long-term IAM credentials and temporary credentials such as IRSA pod identity,
+            making it suitable for any environment including on-premises clusters.
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+              type: string
+            metadata:
+              type: object
+            spec:
+              description: |-
+                STSAssumeRoleTokenSpec defines the desired state to generate temporary AWS credentials
+                via sts:AssumeRole. Unlike STSSessionToken, this generator works with both long-term
+                credentials and temporary credentials (e.g. IRSA / pod identity).
+              properties:
+                auth:
+                  description: Auth defines how to authenticate with AWS.
+                  properties:
+                    jwt:
+                      description: AWSJWTAuth provides configuration to authenticate against AWS using service account tokens.
+                      properties:
+                        serviceAccountRef:
+                          description: ServiceAccountSelector is 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.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                              type: string
+                            namespace:
+                              description: |-
+                                Namespace of the resource being referred to.
+                                Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                              maxLength: 63
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                              type: string
+                          required:
+                            - name
+                          type: object
+                      type: object
+                    secretRef:
+                      description: |-
+                        AWSAuthSecretRef holds secret references for AWS credentials
+                        both AccessKeyID and SecretAccessKey must be defined in order to properly authenticate.
+                      properties:
+                        accessKeyIDSecretRef:
+                          description: The AccessKeyID is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                A key in the referenced Secret.
+                                Some instances of this field may be defaulted, in others it may be required.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[-._a-zA-Z0-9]+$
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                              type: string
+                            namespace:
+                              description: |-
+                                The namespace of the Secret resource being referred to.
+                                Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                              maxLength: 63
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                              type: string
+                          type: object
+                        secretAccessKeySecretRef:
+                          description: The SecretAccessKey is used for authentication
+                          properties:
+                            key:
+                              description: |-
+                                A key in the referenced Secret.
+                                Some instances of this field may be defaulted, in others it may be required.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[-._a-zA-Z0-9]+$
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                              type: string
+                            namespace:
+                              description: |-
+                                The namespace of the Secret resource being referred to.
+                                Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                              maxLength: 63
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                              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: |-
+                                A key in the referenced Secret.
+                                Some instances of this field may be defaulted, in others it may be required.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[-._a-zA-Z0-9]+$
+                              type: string
+                            name:
+                              description: The name of the Secret resource being referred to.
+                              maxLength: 253
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                              type: string
+                            namespace:
+                              description: |-
+                                The namespace of the Secret resource being referred to.
+                                Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                              maxLength: 63
+                              minLength: 1
+                              pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                              type: string
+                          type: object
+                      type: object
+                  type: object
+                region:
+                  description: Region specifies the AWS region to operate in.
+                  type: string
+                requestParameters:
+                  description: RequestParameters contains optional parameters for the AssumeRole call.
+                  properties:
+                    externalID:
+                      description: |-
+                        ExternalID is a unique identifier that might be required when you assume a
+                        role in another account. If the administrator of the account to which the
+                        role belongs provided you with an external ID, then provide that value.
+                      type: string
+                    sessionDuration:
+                      description: |-
+                        SessionDuration The duration, in seconds, of the role session.
+                        The value can range from 900 seconds (15 minutes) to the maximum session
+                        duration setting for the role. If not specified, the default is 1 hour.
+                      format: int32
+                      type: integer
+                  type: object
+                role:
+                  description: Role is the ARN of the IAM role to assume.
+                  minLength: 1
+                  type: string
+              required:
+                - region
+                - role
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
 metadata:
   annotations:
     controller-gen.kubebuilder.io/version: v0.19.0

+ 48 - 0
docs/api/generator/stsassumerole.md

@@ -0,0 +1,48 @@
+STSAssumeRoleToken uses `sts:AssumeRole` to obtain temporary AWS credentials.
+
+Unlike [`STSSessionToken`](sts.md) (which calls `GetSessionToken`), this generator works with **any** type of AWS credentials — including temporary session credentials from IRSA / pod identity — making it suitable for on-premises clusters, EKS with IRSA, or any environment where the caller already holds temporary credentials.
+
+## When to use STSAssumeRoleToken vs STSSessionToken
+
+| Scenario | Generator |
+|---|---|
+| Long-term IAM credentials, need MFA enforcement | `STSSessionToken` |
+| Long-term IAM credentials, need to assume a role | `STSAssumeRoleToken` |
+| IRSA / pod identity (temporary credentials) + role assumption | `STSAssumeRoleToken` |
+| IRSA / pod identity, no additional role assumption needed | Use [`ECRAuthorizationToken`](ecr.md) or provider directly |
+
+## Output Keys and Values
+
+| Key               | Description                                                                         |
+|-------------------|-------------------------------------------------------------------------------------|
+| access_key_id     | The access key ID of the assumed role credentials.                                  |
+| secret_access_key | The secret access key of the assumed role credentials.                              |
+| session_token     | The session token required to use the temporary credentials.                        |
+| expiration        | Unix timestamp (seconds) at which the credentials expire. Absent if unknown.        |
+
+## Authentication
+
+You can use either:
+
+* **Static credentials** via `spec.auth.secretRef` — a Kubernetes Secret containing your long-term IAM access key and secret.
+* **IRSA / service account token** via `spec.auth.jwt` — uses the pod's projected service account token to call `AssumeRoleWithWebIdentity`, then chains an additional `AssumeRole` to the target role.
+
+If neither is specified, the AWS SDK default credential chain is used (environment variables, EC2 instance metadata, etc.).
+
+## Request Parameters
+
+| Field                         | Description                                                                                     |
+|-------------------------------|-------------------------------------------------------------------------------------------------|
+| `requestParameters.sessionDuration` | Duration in seconds for the assumed role session. Range: 900–43200. Default: 3600 (1 hour). |
+| `requestParameters.externalID`      | External ID for cross-account role assumption. Required when the role trust policy enforces it. |
+
+## Example Manifest
+
+```yaml
+{% include 'generator-stsassumerole.yaml' %}
+```
+
+Example `ExternalSecret` that references the STSAssumeRoleToken generator:
+```yaml
+{% include 'generator-stsassumerole-example.yaml' %}
+```

+ 14 - 0
docs/snippets/generator-stsassumerole-example.yaml

@@ -0,0 +1,14 @@
+apiVersion: external-secrets.io/v1
+kind: ExternalSecret
+metadata:
+  name: "sts-assumerole-secret"
+spec:
+  refreshInterval: "1h0m0s"
+  target:
+    name: sts-assumerole-secret
+  dataFrom:
+  - sourceRef:
+      generatorRef:
+        apiVersion: generators.external-secrets.io/v1alpha1
+        kind: STSAssumeRoleToken
+        name: "sts-assumerole-gen"

+ 39 - 0
docs/snippets/generator-stsassumerole.yaml

@@ -0,0 +1,39 @@
+apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+metadata:
+  name: sts-assumerole-gen
+spec:
+
+  # specify aws region (mandatory)
+  region: eu-west-1
+
+  # role ARN to assume (mandatory)
+  role: "arn:aws:iam::123456789012:role/my-role"
+
+  # choose an authentication strategy
+  # if no auth strategy is defined it falls back to using
+  # credentials from the environment of the controller (including IRSA).
+  auth:
+
+    # static credentials:
+    # point to a secret that contains long-term IAM credentials.
+    secretRef:
+      accessKeyIDSecretRef:
+        name: "my-aws-creds"
+        key: "access-key-id"
+      secretAccessKeySecretRef:
+        name: "my-aws-creds"
+        key: "secret-access-key"
+
+    # IRSA / service account token:
+    # uses the pod's projected service account token to call AssumeRoleWithWebIdentity.
+    # jwt:
+    #   serviceAccountRef:
+    #     name: "my-service-account"
+
+  # optional parameters for the AssumeRole call
+  requestParameters:
+    # duration in seconds (900–43200, default: 3600)
+    sessionDuration: 3600
+    # externalID required by the role trust policy, if any
+    # externalID: "my-external-id"

+ 95 - 0
generators/v1/stsassumerole/go.mod

@@ -0,0 +1,95 @@
+module github.com/external-secrets/external-secrets/generators/v1/stsassumerole
+
+go 1.26.3
+
+require (
+	github.com/aws/aws-sdk-go-v2 v1.39.6
+	github.com/aws/aws-sdk-go-v2/credentials v1.18.23
+	github.com/aws/aws-sdk-go-v2/service/sts v1.40.1
+	github.com/external-secrets/external-secrets/apis v0.0.0
+	github.com/external-secrets/external-secrets/providers/v1/aws v0.0.0-20251103072335-a9b233b6936f
+	k8s.io/api v0.35.0
+	k8s.io/apiextensions-apiserver v0.35.0
+	k8s.io/apimachinery v0.35.0
+	sigs.k8s.io/controller-runtime v0.23.1
+	sigs.k8s.io/yaml v1.6.0
+)
+
+require (
+	github.com/aws/aws-sdk-go-v2/config v1.31.19 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 // indirect
+	github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.12 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.30.2 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.6 // indirect
+	github.com/aws/smithy-go v1.23.2 // indirect
+	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/emicklei/go-restful/v3 v3.13.0 // indirect
+	github.com/evanphx/json-patch/v5 v5.9.11 // indirect
+	github.com/external-secrets/external-secrets/runtime v0.0.0 // indirect
+	github.com/fsnotify/fsnotify v1.9.0 // indirect
+	github.com/fxamacker/cbor/v2 v2.9.0 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
+	github.com/go-openapi/jsonpointer v0.22.4 // indirect
+	github.com/go-openapi/jsonreference v0.21.4 // indirect
+	github.com/go-openapi/swag v0.25.4 // indirect
+	github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
+	github.com/go-openapi/swag/conv v0.25.4 // indirect
+	github.com/go-openapi/swag/fileutils v0.25.4 // indirect
+	github.com/go-openapi/swag/jsonname v0.25.4 // indirect
+	github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
+	github.com/go-openapi/swag/loading v0.25.4 // indirect
+	github.com/go-openapi/swag/mangling v0.25.4 // indirect
+	github.com/go-openapi/swag/netutils v0.25.4 // indirect
+	github.com/go-openapi/swag/stringutils v0.25.4 // indirect
+	github.com/go-openapi/swag/typeutils v0.25.4 // indirect
+	github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
+	github.com/google/btree v1.1.3 // indirect
+	github.com/google/gnostic-models v0.7.1 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
+	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/prometheus/client_golang v1.23.2 // indirect
+	github.com/prometheus/client_model v0.6.2 // indirect
+	github.com/prometheus/common v0.67.5 // indirect
+	github.com/prometheus/procfs v0.19.2 // indirect
+	github.com/spf13/pflag v1.0.10 // indirect
+	github.com/x448/float16 v0.8.4 // indirect
+	go.yaml.in/yaml/v2 v2.4.3 // indirect
+	go.yaml.in/yaml/v3 v3.0.4 // indirect
+	golang.org/x/net v0.49.0 // indirect
+	golang.org/x/oauth2 v0.34.0 // indirect
+	golang.org/x/sync v0.19.0 // indirect
+	golang.org/x/sys v0.40.0 // indirect
+	golang.org/x/term v0.39.0 // indirect
+	golang.org/x/text v0.33.0 // indirect
+	golang.org/x/time v0.14.0 // indirect
+	gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
+	google.golang.org/protobuf v1.36.11 // indirect
+	gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
+	gopkg.in/inf.v0 v0.9.1 // indirect
+	k8s.io/client-go v0.35.0 // indirect
+	k8s.io/klog/v2 v2.130.1 // indirect
+	k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect
+	k8s.io/utils v0.0.0-20260108192941-914a6e750570 // indirect
+	sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
+	sigs.k8s.io/randfill v1.0.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
+)
+
+replace (
+	github.com/external-secrets/external-secrets/apis => ../../../apis
+	github.com/external-secrets/external-secrets/runtime => ../../../runtime
+)
+
+replace github.com/external-secrets/external-secrets/providers/v1/aws => ../../../providers/v1/aws

+ 211 - 0
generators/v1/stsassumerole/go.sum

@@ -0,0 +1,211 @@
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/aws/aws-sdk-go-v2 v1.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk=
+github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE=
+github.com/aws/aws-sdk-go-v2/config v1.31.19 h1:qdUtOw4JhZr2YcKO3g0ho/IcFXfXrrb8xlX05Y6EvSw=
+github.com/aws/aws-sdk-go-v2/config v1.31.19/go.mod h1:tMJ8bur01t8eEm0atLadkIIFA154OJ4JCKZeQ+o+R7k=
+github.com/aws/aws-sdk-go-v2/credentials v1.18.23 h1:IQILcxVgMO2BVLaJ2aAv21dKWvE1MduNrbvuK43XL2Q=
+github.com/aws/aws-sdk-go-v2/credentials v1.18.23/go.mod h1:JRodHszhVdh5TPUknxDzJzrMiznG+M+FfR3WSWKgCI8=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.12 h1:xN4mw6Gqim0jMwjmlNST+yXVShFPwSAjt4gXqi43W6I=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.39.12/go.mod h1:QgVIY03/XoQs2iFr0MbQuQ/Tf1RwlkOvuySWMh1wph4=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.2 h1:/p6MxkbQoCzaGQT3WO0JwG0FlQyG9RD8VmdmoKc5xqU=
+github.com/aws/aws-sdk-go-v2/service/sso v1.30.2/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.6 h1:0dES42T2dhICCbVB3JSTTn7+Bz93wfJEK1b7jksZIyQ=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.6/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo=
+github.com/aws/aws-sdk-go-v2/service/sts v1.40.1 h1:5sbIM57lHLaEaNWdIx23JH30LNBsSDkjN/QXGcRLAFc=
+github.com/aws/aws-sdk-go-v2/service/sts v1.40.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk=
+github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM=
+github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
+github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
+github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
+github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
+github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
+github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
+github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
+github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
+github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
+github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
+github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
+github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
+github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
+github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
+github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
+github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
+github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
+github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
+github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
+github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
+github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
+github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
+github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
+github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
+github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
+github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
+github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
+github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
+github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
+github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
+github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
+github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
+github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
+github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
+github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
+github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
+github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
+github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
+github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
+github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
+github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
+github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
+github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
+github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
+github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
+github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
+github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
+github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
+github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
+github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
+github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
+github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
+go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
+golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
+golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
+golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
+golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
+golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
+golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
+golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
+golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
+golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
+golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
+golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
+gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
+gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
+gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
+k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
+k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4=
+k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU=
+k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8=
+k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
+k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE=
+k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o=
+k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
+k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
+k8s.io/utils v0.0.0-20260108192941-914a6e750570 h1:JT4W8lsdrGENg9W+YwwdLJxklIuKWdRm+BC+xt33FOY=
+k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
+sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE=
+sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
+sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

+ 154 - 0
generators/v1/stsassumerole/stsassumerole.go

@@ -0,0 +1,154 @@
+/*
+Copyright © The ESO Authors
+
+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
+
+    https://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 stsassumerole implements a generator for AWS STS AssumeRole credentials
+package stsassumerole
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strconv"
+	"time"
+
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
+	"github.com/aws/aws-sdk-go-v2/service/sts"
+	apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/yaml"
+
+	esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
+	genv1alpha1 "github.com/external-secrets/external-secrets/apis/generators/v1alpha1"
+	awsauth "github.com/external-secrets/external-secrets/providers/v1/aws/auth"
+)
+
+// Generator implements a generator for AWS STS AssumeRole credentials.
+type Generator struct{}
+
+const (
+	errNoSpec     = "no config spec provided"
+	errNoRole     = "role must be specified"
+	errParseSpec  = "unable to parse spec: %w"
+	errCreateSess = "unable to create aws session: %w"
+	errGetCreds   = "unable to retrieve credentials: %w"
+)
+
+// credsProviderFactory creates an aws.CredentialsProvider that calls sts:AssumeRole.
+// Injected as a parameter to allow mocking in tests.
+type credsProviderFactory func(cfg *aws.Config, roleARN string, optFns ...func(*stscreds.AssumeRoleOptions)) aws.CredentialsProvider
+
+func defaultCredsProviderFactory(cfg *aws.Config, roleARN string, optFns ...func(*stscreds.AssumeRoleOptions)) aws.CredentialsProvider {
+	return stscreds.NewAssumeRoleProvider(sts.NewFromConfig(*cfg), roleARN, optFns...)
+}
+
+// Generate creates AWS credentials by assuming the configured IAM role.
+func (g *Generator) Generate(ctx context.Context, jsonSpec *apiextensions.JSON, kube client.Client, namespace string) (map[string][]byte, genv1alpha1.GeneratorProviderState, error) {
+	return g.generate(ctx, jsonSpec, kube, namespace, defaultCredsProviderFactory)
+}
+
+func (g *Generator) generate(
+	ctx context.Context,
+	jsonSpec *apiextensions.JSON,
+	kube client.Client,
+	namespace string,
+	factory credsProviderFactory,
+) (map[string][]byte, genv1alpha1.GeneratorProviderState, error) {
+	if jsonSpec == nil {
+		return nil, nil, errors.New(errNoSpec)
+	}
+	res, err := parseSpec(jsonSpec.Raw)
+	if err != nil {
+		return nil, nil, fmt.Errorf(errParseSpec, err)
+	}
+	if res.Spec.Role == "" {
+		return nil, nil, errors.New(errNoRole)
+	}
+
+	// Build base AWS config from credentials only (no role assumption here).
+	// We perform the AssumeRole ourselves so we can pass duration and externalID.
+	cfg, err := awsauth.NewGeneratorSession(
+		ctx,
+		esv1.AWSAuth{
+			SecretRef: (*esv1.AWSAuthSecretRef)(res.Spec.Auth.SecretRef),
+			JWTAuth:   (*esv1.AWSJWTAuth)(res.Spec.Auth.JWTAuth),
+		},
+		"", // role handled below
+		res.Spec.Region,
+		kube,
+		namespace,
+		awsauth.DefaultSTSProvider,
+		awsauth.DefaultJWTProvider)
+	if err != nil {
+		return nil, nil, fmt.Errorf(errCreateSess, err)
+	}
+
+	// Build AssumeRole options from request parameters.
+	var optFns []func(*stscreds.AssumeRoleOptions)
+	if res.Spec.RequestParameters != nil {
+		params := res.Spec.RequestParameters
+		if params.SessionDuration != nil {
+			d := time.Duration(*params.SessionDuration) * time.Second
+			optFns = append(optFns, func(o *stscreds.AssumeRoleOptions) {
+				o.Duration = d
+			})
+		}
+		if params.ExternalID != nil {
+			eid := *params.ExternalID
+			optFns = append(optFns, func(o *stscreds.AssumeRoleOptions) {
+				o.ExternalID = aws.String(eid)
+			})
+		}
+	}
+
+	cfg.Credentials = factory(cfg, res.Spec.Role, optFns...)
+
+	creds, err := cfg.Credentials.Retrieve(ctx)
+	if err != nil {
+		return nil, nil, fmt.Errorf(errGetCreds, err)
+	}
+
+	result := map[string][]byte{
+		"access_key_id":     []byte(creds.AccessKeyID),
+		"secret_access_key": []byte(creds.SecretAccessKey),
+		"session_token":     []byte(creds.SessionToken),
+	}
+	if !creds.Expires.IsZero() {
+		result["expiration"] = []byte(strconv.FormatInt(creds.Expires.Unix(), 10))
+	}
+	return result, nil, nil
+}
+
+// Cleanup is a no-op — AssumeRole credentials are not revocable.
+func (g *Generator) Cleanup(_ context.Context, _ *apiextensions.JSON, _ genv1alpha1.GeneratorProviderState, _ client.Client, _ string) error {
+	return nil
+}
+
+func parseSpec(data []byte) (*genv1alpha1.STSAssumeRoleToken, error) {
+	var spec genv1alpha1.STSAssumeRoleToken
+	err := yaml.Unmarshal(data, &spec)
+	return &spec, err
+}
+
+// NewGenerator creates a new Generator instance.
+func NewGenerator() genv1alpha1.Generator {
+	return &Generator{}
+}
+
+// Kind returns the generator kind.
+func Kind() string {
+	return string(genv1alpha1.GeneratorKindSTSAssumeRoleToken)
+}

+ 222 - 0
generators/v1/stsassumerole/stsassumerole_test.go

@@ -0,0 +1,222 @@
+/*
+Copyright © The ESO Authors
+
+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
+
+    https://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 stsassumerole
+
+import (
+	"context"
+	"errors"
+	"reflect"
+	"testing"
+	"time"
+
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
+	v1 "k8s.io/api/core/v1"
+	apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
+)
+
+type fakeCredsProvider struct {
+	creds aws.Credentials
+	err   error
+}
+
+func (f *fakeCredsProvider) Retrieve(_ context.Context) (aws.Credentials, error) {
+	return f.creds, f.err
+}
+
+func makeFactory(creds aws.Credentials, err error) credsProviderFactory {
+	return func(_ *aws.Config, _ string, _ ...func(*stscreds.AssumeRoleOptions)) aws.CredentialsProvider {
+		return &fakeCredsProvider{creds: creds, err: err}
+	}
+}
+
+func TestGenerate(t *testing.T) {
+	exp := time.Unix(9999, 0).UTC()
+
+	type args struct {
+		ctx       context.Context
+		jsonSpec  *apiextensions.JSON
+		kube      client.Client
+		namespace string
+		factory   credsProviderFactory
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    map[string][]byte
+		wantErr bool
+	}{
+		{
+			name: "nil spec returns error",
+			args: args{
+				ctx:      context.Background(),
+				jsonSpec: nil,
+			},
+			wantErr: true,
+		},
+		{
+			name: "invalid yaml returns error",
+			args: args{
+				ctx:      context.Background(),
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`{invalid`)},
+				factory:  makeFactory(aws.Credentials{}, nil),
+			},
+			wantErr: true,
+		},
+		{
+			name: "missing role returns error",
+			args: args{
+				ctx:       context.Background(),
+				namespace: "ns",
+				kube:      clientfake.NewClientBuilder().Build(),
+				factory:   makeFactory(aws.Credentials{}, nil),
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+spec:
+  region: us-east-1`)},
+			},
+			wantErr: true,
+		},
+		{
+			name: "assume role error is propagated",
+			args: args{
+				ctx:       context.Background(),
+				namespace: "ns",
+				kube:      clientfake.NewClientBuilder().Build(),
+				factory: func(_ *aws.Config, _ string, _ ...func(*stscreds.AssumeRoleOptions)) aws.CredentialsProvider {
+					return &fakeCredsProvider{err: errors.New("access denied")}
+				},
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+spec:
+  region: us-east-1
+  role: arn:aws:iam::123456789012:role/my-role`)},
+			},
+			wantErr: true,
+		},
+		{
+			name: "happy path with secretRef and role",
+			args: args{
+				ctx:       context.Background(),
+				namespace: "testns",
+				kube: clientfake.NewClientBuilder().WithObjects(&v1.Secret{
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      "aws-creds",
+						Namespace: "testns",
+					},
+					Data: map[string][]byte{
+						"access-key-id":     []byte("AKIAIOSFODNN7EXAMPLE"),
+						"secret-access-key": []byte("wJalrXUtnFEMI/K7MDENG"),
+					},
+				}).Build(),
+				factory: makeFactory(aws.Credentials{
+					AccessKeyID:     "ASSUMED-ACCESS-KEY",
+					SecretAccessKey: "ASSUMED-SECRET",
+					SessionToken:    "ASSUMED-SESSION-TOKEN",
+					Expires:         exp,
+				}, nil),
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+spec:
+  region: eu-west-1
+  role: arn:aws:iam::123456789012:role/my-role
+  auth:
+    secretRef:
+      accessKeyIDSecretRef:
+        name: aws-creds
+        key: access-key-id
+      secretAccessKeySecretRef:
+        name: aws-creds
+        key: secret-access-key`)},
+			},
+			want: map[string][]byte{
+				"access_key_id":     []byte("ASSUMED-ACCESS-KEY"),
+				"secret_access_key": []byte("ASSUMED-SECRET"),
+				"session_token":     []byte("ASSUMED-SESSION-TOKEN"),
+				"expiration":        []byte("9999"),
+			},
+		},
+		{
+			name: "happy path with requestParameters",
+			args: args{
+				ctx:       context.Background(),
+				namespace: "testns",
+				kube:      clientfake.NewClientBuilder().Build(),
+				factory: makeFactory(aws.Credentials{
+					AccessKeyID:     "KEY",
+					SecretAccessKey: "SECRET",
+					SessionToken:    "TOKEN",
+					Expires:         exp,
+				}, nil),
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+spec:
+  region: us-east-1
+  role: arn:aws:iam::123456789012:role/cross-account
+  requestParameters:
+    sessionDuration: 7200
+    externalID: my-external-id`)},
+			},
+			want: map[string][]byte{
+				"access_key_id":     []byte("KEY"),
+				"secret_access_key": []byte("SECRET"),
+				"session_token":     []byte("TOKEN"),
+				"expiration":        []byte("9999"),
+			},
+		},
+		{
+			name: "no expiration when expires is zero",
+			args: args{
+				ctx:       context.Background(),
+				namespace: "testns",
+				kube:      clientfake.NewClientBuilder().Build(),
+				factory: makeFactory(aws.Credentials{
+					AccessKeyID:     "KEY",
+					SecretAccessKey: "SECRET",
+					SessionToken:    "TOKEN",
+				}, nil),
+				jsonSpec: &apiextensions.JSON{Raw: []byte(`apiVersion: generators.external-secrets.io/v1alpha1
+kind: STSAssumeRoleToken
+spec:
+  region: us-east-1
+  role: arn:aws:iam::123456789012:role/my-role`)},
+			},
+			want: map[string][]byte{
+				"access_key_id":     []byte("KEY"),
+				"secret_access_key": []byte("SECRET"),
+				"session_token":     []byte("TOKEN"),
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			g := &Generator{}
+			got, _, err := g.generate(tt.args.ctx, tt.args.jsonSpec, tt.args.kube, tt.args.namespace, tt.args.factory)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("Generator.generate() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("Generator.generate() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}

+ 2 - 0
go.mod

@@ -16,6 +16,7 @@ replace (
 	github.com/external-secrets/external-secrets/generators/v1/quay => ./generators/v1/quay
 	github.com/external-secrets/external-secrets/generators/v1/sshkey => ./generators/v1/sshkey
 	github.com/external-secrets/external-secrets/generators/v1/sts => ./generators/v1/sts
+	github.com/external-secrets/external-secrets/generators/v1/stsassumerole => ./generators/v1/stsassumerole
 	github.com/external-secrets/external-secrets/generators/v1/uuid => ./generators/v1/uuid
 	github.com/external-secrets/external-secrets/generators/v1/vault => ./generators/v1/vault
 	github.com/external-secrets/external-secrets/generators/v1/webhook => ./generators/v1/webhook
@@ -129,6 +130,7 @@ require (
 	github.com/external-secrets/external-secrets/generators/v1/quay v0.0.0-00010101000000-000000000000
 	github.com/external-secrets/external-secrets/generators/v1/sshkey v0.0.0-00010101000000-000000000000
 	github.com/external-secrets/external-secrets/generators/v1/sts v0.0.0-00010101000000-000000000000
+	github.com/external-secrets/external-secrets/generators/v1/stsassumerole v0.0.0-00010101000000-000000000000
 	github.com/external-secrets/external-secrets/generators/v1/uuid v0.0.0-00010101000000-000000000000
 	github.com/external-secrets/external-secrets/generators/v1/vault v0.0.0-00010101000000-000000000000
 	github.com/external-secrets/external-secrets/generators/v1/webhook v0.0.0-00010101000000-000000000000

+ 1 - 0
hack/api-docs/mkdocs.yml

@@ -74,6 +74,7 @@ nav:
           - "api/generator/index.md"
           - Azure Container Registry: api/generator/acr.md
           - AWS Elastic Container Registry: api/generator/ecr.md
+          - AWS STS AssumeRole Token: api/generator/stsassumerole.md
           - AWS STS Session Token: api/generator/sts.md
           - Cloudsmith: api/generator/cloudsmith.md
           - Cluster Generator: api/generator/cluster.md

+ 2 - 0
pkg/register/generators.go

@@ -30,6 +30,7 @@ import (
 	quay "github.com/external-secrets/external-secrets/generators/v1/quay"
 	sshkey "github.com/external-secrets/external-secrets/generators/v1/sshkey"
 	sts "github.com/external-secrets/external-secrets/generators/v1/sts"
+	stsassumerole "github.com/external-secrets/external-secrets/generators/v1/stsassumerole"
 	uuid "github.com/external-secrets/external-secrets/generators/v1/uuid"
 	vaultgen "github.com/external-secrets/external-secrets/generators/v1/vault"
 	webhookgen "github.com/external-secrets/external-secrets/generators/v1/webhook"
@@ -49,6 +50,7 @@ func init() {
 	genv1alpha1.Register(quay.Kind(), quay.NewGenerator())
 	genv1alpha1.Register(sshkey.Kind(), sshkey.NewGenerator())
 	genv1alpha1.Register(sts.Kind(), sts.NewGenerator())
+	genv1alpha1.Register(stsassumerole.Kind(), stsassumerole.NewGenerator())
 	genv1alpha1.Register(uuid.Kind(), uuid.NewGenerator())
 	genv1alpha1.Register(vaultgen.Kind(), vaultgen.NewGenerator())
 	genv1alpha1.Register(webhookgen.Kind(), webhookgen.NewGenerator())

+ 11 - 0
runtime/esutils/resolvers/generator.go

@@ -236,6 +236,17 @@ func clusterGeneratorToVirtual(gen *genv1alpha1.ClusterGenerator) (client.Object
 			},
 			Spec: *gen.Spec.Generator.SSHKeySpec,
 		}, nil
+	case genv1alpha1.GeneratorKindSTSAssumeRoleToken:
+		if gen.Spec.Generator.STSAssumeRoleTokenSpec == nil {
+			return nil, fmt.Errorf("when kind is %s, STSAssumeRoleTokenSpec must be set", gen.Spec.Kind)
+		}
+		return &genv1alpha1.STSAssumeRoleToken{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: genv1alpha1.SchemeGroupVersion.String(),
+				Kind:       genv1alpha1.STSAssumeRoleTokenKind,
+			},
+			Spec: *gen.Spec.Generator.STSAssumeRoleTokenSpec,
+		}, nil
 	case genv1alpha1.GeneratorKindSTSSessionToken:
 		if gen.Spec.Generator.STSSessionTokenSpec == nil {
 			return nil, fmt.Errorf("when kind is %s, STSSessionTokenSpec must be set", gen.Spec.Kind)

+ 2 - 2
tests/__snapshot__/clusterexternalsecret-v1.yaml

@@ -20,7 +20,7 @@ spec:
       sourceRef:
         generatorRef:
           apiVersion: external-secrets.io/v1
-          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
+          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
           name: string
         storeRef:
           kind: "SecretStore" # "SecretStore", "ClusterSecretStore"
@@ -57,7 +57,7 @@ spec:
       sourceRef:
         generatorRef:
           apiVersion: external-secrets.io/v1
-          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
+          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
           name: string
         storeRef:
           kind: "SecretStore" # "SecretStore", "ClusterSecretStore"

+ 2 - 2
tests/__snapshot__/clusterexternalsecret-v1beta1.yaml

@@ -19,7 +19,7 @@ spec:
       sourceRef:
         generatorRef:
           apiVersion: external-secrets.io/v1beta1
-          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
+          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
           name: string
         storeRef:
           kind: "SecretStore" # "SecretStore", "ClusterSecretStore"
@@ -48,7 +48,7 @@ spec:
       sourceRef:
         generatorRef:
           apiVersion: external-secrets.io/v1beta1
-          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
+          kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
           name: string
         storeRef:
           kind: "SecretStore" # "SecretStore", "ClusterSecretStore"

+ 26 - 1
tests/__snapshot__/clustergenerator-v1alpha1.yaml

@@ -148,6 +148,31 @@ spec:
       comment: string
       keySize: 256
       keyType: "rsa"
+    stsAssumeRoleTokenSpec:
+      auth:
+        jwt:
+          serviceAccountRef:
+            audiences: [] # minItems 0 of type string
+            name: string
+            namespace: string
+        secretRef:
+          accessKeyIDSecretRef:
+            key: string
+            name: string
+            namespace: string
+          secretAccessKeySecretRef:
+            key: string
+            name: string
+            namespace: string
+          sessionTokenSecretRef:
+            key: string
+            name: string
+            namespace: string
+      region: string
+      requestParameters:
+        externalID: string
+        sessionDuration: 1
+      role: string
     stsSessionTokenSpec:
       auth:
         jwt:
@@ -354,4 +379,4 @@ spec:
           name: string
       timeout: string
       url: string
-  kind: "ACRAccessToken" # "ACRAccessToken", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
+  kind: "ACRAccessToken" # "ACRAccessToken", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"

+ 2 - 2
tests/__snapshot__/externalsecret-v1.yaml

@@ -15,7 +15,7 @@ spec:
     sourceRef:
       generatorRef:
         apiVersion: external-secrets.io/v1
-        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
+        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
         name: string
       storeRef:
         kind: "SecretStore" # "SecretStore", "ClusterSecretStore"
@@ -52,7 +52,7 @@ spec:
     sourceRef:
       generatorRef:
         apiVersion: external-secrets.io/v1
-        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
+        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
         name: string
       storeRef:
         kind: "SecretStore" # "SecretStore", "ClusterSecretStore"

+ 2 - 2
tests/__snapshot__/externalsecret-v1beta1.yaml

@@ -14,7 +14,7 @@ spec:
     sourceRef:
       generatorRef:
         apiVersion: external-secrets.io/v1beta1
-        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
+        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
         name: string
       storeRef:
         kind: "SecretStore" # "SecretStore", "ClusterSecretStore"
@@ -43,7 +43,7 @@ spec:
     sourceRef:
       generatorRef:
         apiVersion: external-secrets.io/v1beta1
-        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
+        kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana"
         name: string
       storeRef:
         kind: "SecretStore" # "SecretStore", "ClusterSecretStore"

+ 1 - 1
tests/__snapshot__/pushsecret-v1alpha1.yaml

@@ -45,7 +45,7 @@ spec:
   selector:
     generatorRef:
       apiVersion: external-secrets.io/v1alpha1
-      kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
+      kind: "ACRAccessToken" # "ACRAccessToken", "ClusterGenerator", "CloudsmithAccessToken", "ECRAuthorizationToken", "Fake", "GCRAccessToken", "GithubAccessToken", "QuayAccessToken", "Password", "SSHKey", "STSAssumeRoleToken", "STSSessionToken", "UUID", "VaultDynamicSecret", "Webhook", "Grafana", "MFA"
       name: string
     secret:
       name: string