Repository: VictoriaMetrics/operator

Issue:
config-reloader: introduce new flag reload-url-auth-key

  VictoriaMetrics compents has an option to protect `/-/reload` endpoints with special `authKey`.
Currently, operator doesn't provide any secure way to config such option with config-reloader container.

It's worth to introduce a new flag, which must be defined as a secret value with a possible on-disk path and env variable definition.

If auth-key is defined, client must switch to `postForm` requests for `/-/reload` API calls. 

auth-key must be refreshed on each reload call.


Current logs:
```
config-reloader 2025-04-28T13:28:08.700Z    info    /go/pkg/mod/github.com/!victoria!metrics/!victoria!metrics@v1.112.0/lib/logger/flag.go:20      -reload-url="http://127.0.0.1:8428/-/reload?authKey=XXXX"
```

Desired logs:

```
config-reloader 2025-04-28T13:28:08.700Z    info    /go/pkg/mod/github.com/!victoria!metrics/!victoria!metrics@v1.112.0/lib/logger/flag.go:20      -reload-url="http://127.0.0.1:8428/-/reload"
config-reloader 2025-04-28T13:28:08.700Z    info    /go/pkg/mod/github.com/!victoria!metrics/!victoria!metrics@v1.112.0/lib/logger/flag.go:20      -reload-url-auth-key="secret"
```

Hints from issue comments:
@f41gh7: Feature was included into [v0.57.0](https://github.com/VictoriaMetrics/operator/releases/tag/v0.57.0) release

Solution patch:
diff --git a/api/operator/v1beta1/vmextra_types.go b/api/operator/v1beta1/vmextra_types.go
index 3fd300a5..458e77df 100644
--- a/api/operator/v1beta1/vmextra_types.go
+++ b/api/operator/v1beta1/vmextra_types.go
@@ -1177,6 +1177,11 @@ type CommonConfigReloaderParams struct {
 	// for example resyncInterval: "30s"
 	// +optional
 	ConfigReloaderExtraArgs map[string]string `json:"configReloaderExtraArgs,omitempty"`
+	// ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.
+	// Given secret reference will be added to the application and vm-config-reloader as volume
+	// available since v0.57.0 version
+	// +optional
+	ConfigReloadAuthKeySecret *v1.SecretKeySelector `json:"configReloadAuthKeySecret,omitempty"`
 }
 
 // CommonApplicationDeploymentParams defines common params
diff --git a/api/operator/v1beta1/zz_generated.deepcopy.go b/api/operator/v1beta1/zz_generated.deepcopy.go
index 932d913a..e1ffe19d 100644
--- a/api/operator/v1beta1/zz_generated.deepcopy.go
+++ b/api/operator/v1beta1/zz_generated.deepcopy.go
@@ -510,6 +510,11 @@ func (in *CommonConfigReloaderParams) DeepCopyInto(out *CommonConfigReloaderPara
 			(*out)[key] = val
 		}
 	}
+	if in.ConfigReloadAuthKeySecret != nil {
+		in, out := &in.ConfigReloadAuthKeySecret, &out.ConfigReloadAuthKeySecret
+		*out = new(v1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CommonConfigReloaderParams.
diff --git a/cmd/config-reloader/main.go b/cmd/config-reloader/main.go
index 85b3bd98..534f1d83 100644
--- a/cmd/config-reloader/main.go
+++ b/cmd/config-reloader/main.go
@@ -11,6 +11,7 @@ import (
 	"io"
 	"net"
 	"net/http"
+	"net/url"
 	"os"
 	"strings"
 	"sync"
@@ -47,7 +48,8 @@ var (
 		"rules-dir", "the same as watched-dir, legacy")
 	reloadURL = flag.String(
 		"reload-url", "http://127.0.0.1:8429/-/reload", "reload URL to trigger config reload")
-	listenAddr = flag.String(
+	reloadURLAuthKey = flagutil.NewPassword("reload-url-auth-key", "authKey for config reload API requests")
+	listenAddr       = flag.String(
 		"http.listenAddr", ":8435", "http server listen addr")
 	useProxyProtocol = flag.Bool(
 		"reload-use-proxy-protocol", false, "enables proxy-protocol for reload connections.")
@@ -82,6 +84,10 @@ func main() {
 	buildinfo.Init()
 	logger.Init()
 	ctx, cancel := context.WithCancel(context.Background())
+	_, err := url.Parse(*reloadURL)
+	if err != nil {
+		logger.Fatalf("incorrect value for reload-url=%q: %s", *reloadURL, err)
+	}
 	logger.Infof("starting config reloader")
 	r := reloader{
 		c: buildHTTPClient(),
@@ -203,17 +209,32 @@ type reloader struct {
 
 func (r *reloader) reload(ctx context.Context) error {
 	configReloadsTotal.Inc()
-	req, err := http.NewRequestWithContext(ctx, *webhookMethod, *reloadURL, nil)
-	if err != nil {
-		return fmt.Errorf("cannot build request for reload api: %w", err)
-	}
-	resp, err := r.c.Do(req)
-	if err != nil {
-		return fmt.Errorf("cannot execute request for reload api: %w", err)
+	authKey := reloadURLAuthKey.Get()
+
+	var resp *http.Response
+	if len(authKey) > 0 {
+		formData := url.Values{
+			"authKey": []string{authKey},
+		}
+		var err error
+		resp, err = r.c.PostForm(*reloadURL, formData)
+		if err != nil {
+			return fmt.Errorf("cannot execute postForm request for reload api: %w", err)
+		}
+	} else {
+		req, err := http.NewRequestWithContext(ctx, *webhookMethod, *reloadURL, nil)
+		if err != nil {
+			return fmt.Errorf("cannot build request for reload api: %w", err)
+		}
+		resp, err = r.c.Do(req)
+		if err != nil {
+			return fmt.Errorf("cannot execute request for reload api: %w", err)
+		}
 	}
 	defer resp.Body.Close()
+	text, _ := io.ReadAll(resp.Body)
 	if resp.StatusCode != 200 && resp.StatusCode != 204 {
-		return fmt.Errorf("unexpected status code: %d for reload api request", resp.StatusCode)
+		return fmt.Errorf("unexpected status code: %d: %s for reload api request", resp.StatusCode, text)
 	}
 	return nil
 }
diff --git a/config/crd/overlay/crd.yaml b/config/crd/overlay/crd.yaml
index a9944508..f3c2870d 100644
--- a/config/crd/overlay/crd.yaml
+++ b/config/crd/overlay/crd.yaml
@@ -1893,6 +1893,32 @@ spec:
                 items:
                   type: string
                 type: array
+              configReloadAuthKeySecret:
+                description: |-
+                  ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.
+                  Given secret reference will be added to the application and vm-config-reloader as volume
+                  available since v0.57.0 version
+                properties:
+                  key:
+                    description: The key of the secret to select from.  Must be a
+                      valid secret key.
+                    type: string
+                  name:
+                    default: ""
+                    description: |-
+                      Name of the referent.
+                      This field is effectively required, but due to backwards compatibility is
+                      allowed to be empty. Instances of this type with an empty value here are
+                      almost certainly wrong.
+                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                    type: string
+                  optional:
+                    description: Specify whether the Secret or its key must be defined
+                    type: boolean
+                required:
+                - key
+                type: object
+                x-kubernetes-map-type: atomic
               configReloaderExtraArgs:
                 additionalProperties:
                   type: string
@@ -10723,6 +10749,32 @@ spec:
                   it helps it to start without secret.
                   priority -> hardcoded ConfigRaw -> ConfigRaw, provided by user -> ConfigSecret.
                 type: string
+              configReloadAuthKeySecret:
+                description: |-
+                  ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.
+                  Given secret reference will be added to the application and vm-config-reloader as volume
+                  available since v0.57.0 version
+                properties:
+                  key:
+                    description: The key of the secret to select from.  Must be a
+                      valid secret key.
+                    type: string
+                  name:
+                    default: ""
+                    description: |-
+                      Name of the referent.
+                      This field is effectively required, but due to backwards compatibility is
+                      allowed to be empty. Instances of this type with an empty value here are
+                      almost certainly wrong.
+                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                    type: string
+                  optional:
+                    description: Specify whether the Secret or its key must be defined
+                    type: boolean
+                required:
+                - key
+                type: object
+                x-kubernetes-map-type: atomic
               configReloaderExtraArgs:
                 additionalProperties:
                   type: string
@@ -12724,6 +12776,32 @@ spec:
                 items:
                   type: string
                 type: array
+              configReloadAuthKeySecret:
+                description: |-
+                  ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.
+                  Given secret reference will be added to the application and vm-config-reloader as volume
+                  available since v0.57.0 version
+                properties:
+                  key:
+                    description: The key of the secret to select from.  Must be a
+                      valid secret key.
+                    type: string
+                  name:
+                    default: ""
+                    description: |-
+                      Name of the referent.
+                      This field is effectively required, but due to backwards compatibility is
+                      allowed to be empty. Instances of this type with an empty value here are
+                      almost certainly wrong.
+                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                    type: string
+                  optional:
+                    description: Specify whether the Secret or its key must be defined
+                    type: boolean
+                required:
+                - key
+                type: object
+                x-kubernetes-map-type: atomic
               configReloaderExtraArgs:
                 additionalProperties:
                   type: string
@@ -14703,6 +14781,32 @@ spec:
                 items:
                   type: string
                 type: array
+              configReloadAuthKeySecret:
+                description: |-
+                  ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.
+                  Given secret reference will be added to the application and vm-config-reloader as volume
+                  available since v0.57.0 version
+                properties:
+                  key:
+                    description: The key of the secret to select from.  Must be a
+                      valid secret key.
+                    type: string
+                  name:
+                    default: ""
+                    description: |-
+                      Name of the referent.
+                      This field is effectively required, but due to backwards compatibility is
+                      allowed to be empty. Instances of this type with an empty value here are
+                      almost certainly wrong.
+                      More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
+                    type: string
+                  optional:
+                    description: Specify whether the Secret or its key must be defined
+                    type: boolean
+                required:
+                - key
+                type: object
+                x-kubernetes-map-type: atomic
               configReloaderExtraArgs:
                 additionalProperties:
                   type: string
diff --git a/config/examples/vmagent_reloadauth.yaml b/config/examples/vmagent_reloadauth.yaml
new file mode 100644
index 00000000..32a7aca4
--- /dev/null
+++ b/config/examples/vmagent_reloadauth.yaml
@@ -0,0 +1,21 @@
+apiVersion: operator.victoriametrics.com/v1beta1
+kind: VMAgent
+metadata:
+  name: example-reload-auth
+spec:
+  selectAllByDefault: true
+  replicaCount: 1
+  useVMConfigReloader: true
+  configReloaderImageTag: victoriametrics/operator:config-reloader-v0.57.0
+  configReloadAuthKeySecret:
+    name: reload-key
+    key: RELOAD_AUTH_KEY
+  remoteWrite:
+    - url: "http://vmsingle-example-vmsingle-pvc.default.svc:8429/api/v1/write"
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: reload-key
+stringData:
+  RELOAD_AUTH_KEY: some-secret-key-value
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index b0e290aa..0b4e229d 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -17,6 +17,8 @@ aliases:
 * Dependency: [vmoperator](https://docs.victoriametrics.com/operator/): Updated default VLogs  [v1.21.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.21.0-victorialogs) version
 * Dependency: [vmoperator](https://docs.victoriametrics.com/operator/): Updated default  alertmanager to [0.28.1](https://github.com/prometheus/alertmanager/releases/tag/v0.28.1) version
 
+* FEATURE: [operator](https://docs.victoriametrics.com/operator): introduce new field `spec.configReloadAuthKeySecret` for `VMAgent`, `VMAlert` and `VMAuth` components. It instructs application to use provided value for `-configReload` auth key. See [this issue](https://github.com/VictoriaMetrics/operator/issues/1323) for details.
+
 * BUGFIX: [operator](https://docs.victoriametrics.com/operator): fix typo in `-remoteWrite.streamAggr.enableWindows` flag when `enableWindows` is set to true in VMAgent resources
 
 ## [v0.56.0](https://github.com/VictoriaMetrics/operator/releases/tag/v0.56.0)
diff --git a/docs/api.md b/docs/api.md
index e5e67e66..69f35987 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -425,6 +425,7 @@ _Appears in:_
 
 | Field | Description |
 | --- | --- |
+| <a href="#commonconfigreloaderparams-configreloadauthkeysecret"><code id="commonconfigreloaderparams-configreloadauthkeysecret">configReloadAuthKeySecret</code></a><br/>_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | _(Optional)_<br/>ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.<br />Given secret reference will be added to the application and vm-config-reloader as volume<br />available since v0.57.0 version |
 | <a href="#commonconfigreloaderparams-configreloaderextraargs"><code id="commonconfigreloaderparams-configreloaderextraargs">configReloaderExtraArgs</code></a><br/>_object (keys:string, values:string)_ | _(Optional)_<br/>ConfigReloaderExtraArgs that will be passed to  VMAuths config-reloader container<br />for example resyncInterval: "30s" |
 | <a href="#commonconfigreloaderparams-configreloaderimagetag"><code id="commonconfigreloaderparams-configreloaderimagetag">configReloaderImageTag</code></a><br/>_string_ | _(Optional)_<br/>ConfigReloaderImageTag defines image:tag for config-reloader container |
 | <a href="#commonconfigreloaderparams-configreloaderresources"><code id="commonconfigreloaderparams-configreloaderresources">configReloaderResources</code></a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>ConfigReloaderResources config-reloader container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
@@ -2835,6 +2836,7 @@ _Appears in:_
 | <a href="#vmagentspec-arbitraryfsaccessthroughsms"><code id="vmagentspec-arbitraryfsaccessthroughsms">arbitraryFSAccessThroughSMs</code></a><br/>_[ArbitraryFSAccessThroughSMsConfig](#arbitraryfsaccessthroughsmsconfig)_ | _(Optional)_<br/>ArbitraryFSAccessThroughSMs configures whether configuration<br />based on EndpointAuth can access arbitrary files on the file system<br />of the VMAgent container e.g. bearer token files, basic auth, tls certs |
 | <a href="#vmagentspec-claimtemplates"><code id="vmagentspec-claimtemplates">claimTemplates</code></a><br/>_[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#persistentvolumeclaim-v1-core) array_ | ClaimTemplates allows adding additional VolumeClaimTemplates for VMAgent in StatefulMode |
 | <a href="#vmagentspec-configmaps"><code id="vmagentspec-configmaps">configMaps</code></a><br/>_string array_ | _(Optional)_<br/>ConfigMaps is a list of ConfigMaps in the same namespace as the Application<br />object, which shall be mounted into the Application container<br />at /etc/vm/configs/CONFIGMAP_NAME folder |
+| <a href="#vmagentspec-configreloadauthkeysecret"><code id="vmagentspec-configreloadauthkeysecret">configReloadAuthKeySecret</code></a><br/>_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | _(Optional)_<br/>ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.<br />Given secret reference will be added to the application and vm-config-reloader as volume<br />available since v0.57.0 version |
 | <a href="#vmagentspec-configreloaderextraargs"><code id="vmagentspec-configreloaderextraargs">configReloaderExtraArgs</code></a><br/>_object (keys:string, values:string)_ | _(Optional)_<br/>ConfigReloaderExtraArgs that will be passed to  VMAuths config-reloader container<br />for example resyncInterval: "30s" |
 | <a href="#vmagentspec-configreloaderimagetag"><code id="vmagentspec-configreloaderimagetag">configReloaderImageTag</code></a><br/>_string_ | _(Optional)_<br/>ConfigReloaderImageTag defines image:tag for config-reloader container |
 | <a href="#vmagentspec-configreloaderresources"><code id="vmagentspec-configreloaderresources">configReloaderResources</code></a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>ConfigReloaderResources config-reloader container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
@@ -3050,6 +3052,7 @@ _Appears in:_
 | --- | --- |
 | <a href="#vmalertspec-affinity"><code id="vmalertspec-affinity">affinity</code></a><br/>_[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#affinity-v1-core)_ | _(Optional)_<br/>Affinity If specified, the pod's scheduling constraints. |
 | <a href="#vmalertspec-configmaps"><code id="vmalertspec-configmaps">configMaps</code></a><br/>_string array_ | _(Optional)_<br/>ConfigMaps is a list of ConfigMaps in the same namespace as the Application<br />object, which shall be mounted into the Application container<br />at /etc/vm/configs/CONFIGMAP_NAME folder |
+| <a href="#vmalertspec-configreloadauthkeysecret"><code id="vmalertspec-configreloadauthkeysecret">configReloadAuthKeySecret</code></a><br/>_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | _(Optional)_<br/>ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.<br />Given secret reference will be added to the application and vm-config-reloader as volume<br />available since v0.57.0 version |
 | <a href="#vmalertspec-configreloaderextraargs"><code id="vmalertspec-configreloaderextraargs">configReloaderExtraArgs</code></a><br/>_object (keys:string, values:string)_ | _(Optional)_<br/>ConfigReloaderExtraArgs that will be passed to  VMAuths config-reloader container<br />for example resyncInterval: "30s" |
 | <a href="#vmalertspec-configreloaderimagetag"><code id="vmalertspec-configreloaderimagetag">configReloaderImageTag</code></a><br/>_string_ | _(Optional)_<br/>ConfigReloaderImageTag defines image:tag for config-reloader container |
 | <a href="#vmalertspec-configreloaderresources"><code id="vmalertspec-configreloaderresources">configReloaderResources</code></a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>ConfigReloaderResources config-reloader container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
@@ -3196,6 +3199,7 @@ _Appears in:_
 | <a href="#vmalertmanagerspec-configmaps"><code id="vmalertmanagerspec-configmaps">configMaps</code></a><br/>_string array_ | _(Optional)_<br/>ConfigMaps is a list of ConfigMaps in the same namespace as the Application<br />object, which shall be mounted into the Application container<br />at /etc/vm/configs/CONFIGMAP_NAME folder |
 | <a href="#vmalertmanagerspec-confignamespaceselector"><code id="vmalertmanagerspec-confignamespaceselector">configNamespaceSelector</code></a><br/>_[LabelSelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#labelselector-v1-meta)_ | _(Optional)_<br/> ConfigNamespaceSelector defines namespace selector for VMAlertmanagerConfig.<br />Works in combination with Selector.<br />NamespaceSelector nil - only objects at VMAlertmanager namespace.<br />Selector nil - only objects at NamespaceSelector namespaces.<br />If both nil - behaviour controlled by selectAllByDefault |
 | <a href="#vmalertmanagerspec-configrawyaml"><code id="vmalertmanagerspec-configrawyaml">configRawYaml</code></a><br/>_string_ | _(Optional)_<br/>ConfigRawYaml - raw configuration for alertmanager,<br />it helps it to start without secret.<br />priority -> hardcoded ConfigRaw -> ConfigRaw, provided by user -> ConfigSecret. |
+| <a href="#vmalertmanagerspec-configreloadauthkeysecret"><code id="vmalertmanagerspec-configreloadauthkeysecret">configReloadAuthKeySecret</code></a><br/>_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | _(Optional)_<br/>ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.<br />Given secret reference will be added to the application and vm-config-reloader as volume<br />available since v0.57.0 version |
 | <a href="#vmalertmanagerspec-configreloaderextraargs"><code id="vmalertmanagerspec-configreloaderextraargs">configReloaderExtraArgs</code></a><br/>_object (keys:string, values:string)_ | _(Optional)_<br/>ConfigReloaderExtraArgs that will be passed to  VMAuths config-reloader container<br />for example resyncInterval: "30s" |
 | <a href="#vmalertmanagerspec-configreloaderimagetag"><code id="vmalertmanagerspec-configreloaderimagetag">configReloaderImageTag</code></a><br/>_string_ | _(Optional)_<br/>ConfigReloaderImageTag defines image:tag for config-reloader container |
 | <a href="#vmalertmanagerspec-configreloaderresources"><code id="vmalertmanagerspec-configreloaderresources">configReloaderResources</code></a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>ConfigReloaderResources config-reloader container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
@@ -3373,6 +3377,7 @@ _Appears in:_
 | --- | --- |
 | <a href="#vmauthspec-affinity"><code id="vmauthspec-affinity">affinity</code></a><br/>_[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#affinity-v1-core)_ | _(Optional)_<br/>Affinity If specified, the pod's scheduling constraints. |
 | <a href="#vmauthspec-configmaps"><code id="vmauthspec-configmaps">configMaps</code></a><br/>_string array_ | _(Optional)_<br/>ConfigMaps is a list of ConfigMaps in the same namespace as the Application<br />object, which shall be mounted into the Application container<br />at /etc/vm/configs/CONFIGMAP_NAME folder |
+| <a href="#vmauthspec-configreloadauthkeysecret"><code id="vmauthspec-configreloadauthkeysecret">configReloadAuthKeySecret</code></a><br/>_[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#secretkeyselector-v1-core)_ | _(Optional)_<br/>ConfigReloadAuthKeySecret defines optional secret reference authKey for /-/reload API requests.<br />Given secret reference will be added to the application and vm-config-reloader as volume<br />available since v0.57.0 version |
 | <a href="#vmauthspec-configreloaderextraargs"><code id="vmauthspec-configreloaderextraargs">configReloaderExtraArgs</code></a><br/>_object (keys:string, values:string)_ | _(Optional)_<br/>ConfigReloaderExtraArgs that will be passed to  VMAuths config-reloader container<br />for example resyncInterval: "30s" |
 | <a href="#vmauthspec-configreloaderimagetag"><code id="vmauthspec-configreloaderimagetag">configReloaderImageTag</code></a><br/>_string_ | _(Optional)_<br/>ConfigReloaderImageTag defines image:tag for config-reloader container |
 | <a href="#vmauthspec-configreloaderresources"><code id="vmauthspec-configreloaderresources">configReloaderResources</code></a><br/>_[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.30/#resourcerequirements-v1-core)_ | _(Optional)_<br/>ConfigReloaderResources config-reloader container resource request and limits, https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/<br />if not defined default resources from operator config will be used |
diff --git a/docs/resources/vmagent.md b/docs/resources/vmagent.md
index f4d64807..d1df556e 100644
--- a/docs/resources/vmagent.md
+++ b/docs/resources/vmagent.md
@@ -770,7 +770,7 @@ spec:
   externalLabels:
     cluster: my-cluster
   remoteWrite:
-    - url: "http://vmsingle-example.default.svc:8428/api/v1/write"
+    - url: "http://vmsingle-example.default.svc:8429/api/v1/write"
   inlineRelabelConfig:
     - action: labeldrop
       regex: "temp.*"
@@ -810,7 +810,7 @@ spec:
   selectAllByDefault: true
   daemonSetMode: true
   remoteWrite:
-    - url: "http://vmsingle-example.default.svc:8428/api/v1/write"
+    - url: "http://vmsingle-example.default.svc:8429/api/v1/write"
 ```
 
  daemonSetMode has the following restrictions and limitations:
diff --git a/internal/config/config.go b/internal/config/config.go
index 0bfa87d7..31742a81 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -105,7 +105,7 @@ type BaseOperatorConf struct {
 	UseCustomConfigReloader bool `default:"false" env:"USECUSTOMCONFIGRELOADER"`
 	// container registry name prefix, e.g. docker.io
 	ContainerRegistry                string `default:"" env:"CONTAINERREGISTRY"`
-	CustomConfigReloaderImage        string `default:"victoriametrics/operator:config-reloader-v0.56.0" env:"CUSTOMCONFIGRELOADERIMAGE"`
+	CustomConfigReloaderImage        string `default:"victoriametrics/operator:config-reloader-v0.57.0" env:"CUSTOMCONFIGRELOADERIMAGE"`
 	parsedConfigReloaderImageVersion *version.Version
 	PSPAutoCreateEnabled             bool `default:"false" env:"PSPAUTOCREATEENABLED"`
 
diff --git a/internal/controller/operator/factory/build/container.go b/internal/controller/operator/factory/build/container.go
index 536b468a..78449e89 100644
--- a/internal/controller/operator/factory/build/container.go
+++ b/internal/controller/operator/factory/build/container.go
@@ -9,6 +9,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/apimachinery/pkg/util/intstr"
+	"k8s.io/utils/ptr"
 )
 
 const probeTimeoutSeconds int32 = 5
@@ -329,3 +330,54 @@ func AddsPortProbesToConfigReloaderContainer(useVMConfigReloader bool, crContain
 		ProbeHandler:        configReloaderContainerProbe,
 	}
 }
+
+const (
+	authKeyAppFlagName      = "reloadAuthKey"
+	authKeyReloaderFlagName = "reload-url-auth-key"
+	authKeyMountPath        = "/etc/vm/config-reload-auth"
+	authKeyMountName        = "vm-config-reload-auth-secret"
+)
+
+// AddConfigReloadAuthKeyVolume conditionally adds volume with config reload auth secret
+func AddConfigReloadAuthKeyVolume(dst []corev1.Volume, spec *vmv1beta1.CommonConfigReloaderParams) []corev1.Volume {
+	if spec.ConfigReloadAuthKeySecret == nil {
+		return dst
+	}
+	dst = append(dst, corev1.Volume{
+		Name: authKeyMountName,
+		VolumeSource: corev1.VolumeSource{
+			Secret: &corev1.SecretVolumeSource{
+				SecretName: spec.ConfigReloadAuthKeySecret.Name,
+			},
+		},
+	})
+	return dst
+}
+
+// AddConfigReloadAuthKeyToApp adds authKey env var to the given application container
+func AddConfigReloadAuthKeyToApp(container *corev1.Container, extraArgs map[string]string, spec *vmv1beta1.CommonConfigReloaderParams) {
+	if spec.ConfigReloadAuthKeySecret == nil {
+		return
+	}
+	container.Args = append(container.Args, fmt.Sprintf("-%s=file://%s/%s", authKeyAppFlagName, authKeyMountPath, spec.ConfigReloadAuthKeySecret.Key))
+	container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
+		Name:      authKeyMountName,
+		MountPath: authKeyMountPath,
+	})
+}
+
+// AddConfigReloadAuthKeyToReloader adds authKey env var to the given config-reloader container
+func AddConfigReloadAuthKeyToReloader(container *corev1.Container, spec *vmv1beta1.CommonConfigReloaderParams) {
+	if spec.ConfigReloadAuthKeySecret == nil {
+		return
+	}
+	useVMConfigReloader := ptr.Deref(spec.UseVMConfigReloader, false)
+	if !useVMConfigReloader {
+		return
+	}
+	container.Args = append(container.Args, fmt.Sprintf("-%s=file://%s/%s", authKeyReloaderFlagName, authKeyMountPath, spec.ConfigReloadAuthKeySecret.Key))
+	container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
+		Name:      authKeyMountName,
+		MountPath: authKeyMountPath,
+	})
+}
diff --git a/internal/controller/operator/factory/vmagent/vmagent.go b/internal/controller/operator/factory/vmagent/vmagent.go
index d31bf10b..760b9c12 100644
--- a/internal/controller/operator/factory/vmagent/vmagent.go
+++ b/internal/controller/operator/factory/vmagent/vmagent.go
@@ -730,6 +730,8 @@ func makeSpecForVMAgent(cr *vmv1beta1.VMAgent, ssCache *scrapesSecretsCache) (*c
 
 	vmagentContainer = build.Probe(vmagentContainer, cr)
 
+	build.AddConfigReloadAuthKeyToApp(&vmagentContainer, cr.Spec.ExtraArgs, &cr.Spec.CommonConfigReloaderParams)
+
 	var operatorContainers []corev1.Container
 	var ic []corev1.Container
 	// conditional add config reloader container
@@ -764,6 +766,7 @@ func makeSpecForVMAgent(cr *vmv1beta1.VMAgent, ssCache *scrapesSecretsCache) (*c
 			}
 		}
 	}
+	volumes = build.AddConfigReloadAuthKeyVolume(volumes, &cr.Spec.CommonConfigReloaderParams)
 
 	return &corev1.PodSpec{
 		Volumes:            volumes,
@@ -1497,7 +1500,7 @@ func buildConfigReloaderContainer(cr *vmv1beta1.VMAgent) corev1.Container {
 		build.AddServiceAccountTokenVolumeMount(&cntr, &cr.Spec.CommonApplicationDeploymentParams)
 	}
 	build.AddsPortProbesToConfigReloaderContainer(useVMConfigReloader, &cntr)
-
+	build.AddConfigReloadAuthKeyToReloader(&cntr, &cr.Spec.CommonConfigReloaderParams)
 	return cntr
 }
 
diff --git a/internal/controller/operator/factory/vmalert/vmalert.go b/internal/controller/operator/factory/vmalert/vmalert.go
index 302e8f5a..2c8d1de1 100644
--- a/internal/controller/operator/factory/vmalert/vmalert.go
+++ b/internal/controller/operator/factory/vmalert/vmalert.go
@@ -364,6 +364,7 @@ func vmAlertSpecGen(cr *vmv1beta1.VMAlert, ruleConfigMapNames []string, remoteSe
 		TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
 	}
 	vmalertContainer = build.Probe(vmalertContainer, cr)
+	build.AddConfigReloadAuthKeyToApp(&vmalertContainer, cr.Spec.ExtraArgs, &cr.Spec.CommonConfigReloaderParams)
 	vmalertContainers = append(vmalertContainers, vmalertContainer)
 
 	vmalertContainers = buildConfigReloaderContainer(vmalertContainers, cr, ruleConfigMapNames)
@@ -388,6 +389,7 @@ func vmAlertSpecGen(cr *vmv1beta1.VMAlert, ruleConfigMapNames []string, remoteSe
 			}
 		}
 	}
+	volumes = build.AddConfigReloadAuthKeyVolume(volumes, &cr.Spec.CommonConfigReloaderParams)
 
 	spec := &appsv1.DeploymentSpec{
 
@@ -970,8 +972,8 @@ func buildConfigReloaderContainer(dst []corev1.Container, cr *vmv1beta1.VMAlert,
 	}
 	if useVMConfigReloader {
 		build.AddsPortProbesToConfigReloaderContainer(useVMConfigReloader, &configReloaderContainer)
-
 	}
+	build.AddConfigReloadAuthKeyToReloader(&configReloaderContainer, &cr.Spec.CommonConfigReloaderParams)
 
 	dst = append(dst, configReloaderContainer)
 	return dst
diff --git a/internal/controller/operator/factory/vmauth/vmauth.go b/internal/controller/operator/factory/vmauth/vmauth.go
index 9a45a6f6..fffe54b7 100644
--- a/internal/controller/operator/factory/vmauth/vmauth.go
+++ b/internal/controller/operator/factory/vmauth/vmauth.go
@@ -309,6 +309,7 @@ func makeSpecForVMAuth(cr *vmv1beta1.VMAuth) (*corev1.PodTemplateSpec, error) {
 		ImagePullPolicy:          cr.Spec.Image.PullPolicy,
 	}
 	vmauthContainer = addVMAuthProbes(cr, vmauthContainer)
+	build.AddConfigReloadAuthKeyToApp(&vmauthContainer, cr.Spec.ExtraArgs, &cr.Spec.CommonConfigReloaderParams)
 
 	// move vmauth container to the 0 index
 	operatorContainers = append([]corev1.Container{vmauthContainer}, operatorContainers...)
@@ -322,6 +323,8 @@ func makeSpecForVMAuth(cr *vmv1beta1.VMAuth) (*corev1.PodTemplateSpec, error) {
 	if useVMConfigReloader {
 		volumes = build.AddServiceAccountTokenVolume(volumes, &cr.Spec.CommonApplicationDeploymentParams)
 	}
+	volumes = build.AddConfigReloadAuthKeyVolume(volumes, &cr.Spec.CommonConfigReloaderParams)
+
 	vmAuthSpec := &corev1.PodTemplateSpec{
 		ObjectMeta: metav1.ObjectMeta{
 			Labels:      cr.PodLabels(),
@@ -570,6 +573,7 @@ func buildVMAuthConfigReloaderContainer(cr *vmv1beta1.VMAuth) corev1.Container {
 	}
 
 	build.AddsPortProbesToConfigReloaderContainer(useVMConfigReloader, &configReloader)
+	build.AddConfigReloadAuthKeyToReloader(&configReloader, &cr.Spec.CommonConfigReloaderParams)
 	return configReloader
 }
 



Test patch:
diff --git a/test/e2e/vmauth_test.go b/test/e2e/vmauth_test.go
index 07f7c567..bb95e128 100644
--- a/test/e2e/vmauth_test.go
+++ b/test/e2e/vmauth_test.go
@@ -217,6 +217,34 @@ var _ = Describe("test vmauth Controller", func() {
 							}, eventualDeploymentPodTimeout).Should(BeEmpty())
 						},
 					},
+					testStep{
+						modify: func(cr *v1beta1vm.VMAuth) {
+							authSecret := corev1.Secret{
+								ObjectMeta: metav1.ObjectMeta{
+									Name:      "reload-auth-key",
+									Namespace: namespace,
+								},
+								StringData: map[string]string{
+									"SECRET_VALUE": "some-auth-value",
+								},
+							}
+							Expect(k8sClient.Create(ctx, &authSecret)).To(Succeed())
+							DeferCleanup(func(ctx SpecContext) {
+								Expect(k8sClient.Delete(ctx, &authSecret)).To(Succeed())
+							})
+							cr.Spec.ConfigReloadAuthKeySecret = &corev1.SecretKeySelector{
+								Key: "SECRET_VALUE",
+								LocalObjectReference: corev1.LocalObjectReference{
+									Name: authSecret.Name,
+								},
+							}
+						},
+						verify: func(cr *v1beta1vm.VMAuth) {
+							Eventually(func() string {
+								return expectPodCount(k8sClient, 1, namespace, cr.SelectorLabels())
+							}, eventualDeploymentPodTimeout).Should(BeEmpty())
+						},
+					},
 				),
 				Entry("by switching to internal listen port", "vm-internal-listen",
 					&v1beta1vm.VMAuth{