diff --git a/api/v1alpha1/observatorium_types.go b/api/v1alpha1/observatorium_types.go
index 3ca202f0..109d1dd0 100644
--- a/api/v1alpha1/observatorium_types.go
+++ b/api/v1alpha1/observatorium_types.go
@@ -320,6 +320,31 @@ type RuleConfig struct {
 	Key string `json:"key"`
 }
 
+type VolumeMountType string
+
+var (
+	VolumeMountTypeConfigMap VolumeMountType = "configMap"
+	VolumeMountTypeSecret    VolumeMountType = "secret"
+)
+
+type VolumeMount struct {
+	// Voume mount type, configMap or secret
+	Type VolumeMountType `json:"type"`
+	// Volume mount path in the pod
+	MountPath string `json:"mountPath"`
+	// Resource name for the volume mount source
+	Name string `json:"name"`
+	// File name for the mount
+	Key string `json:"key"`
+}
+
+type AlertmanagerConfigFile struct {
+	// Alertmanager ConfigMap Name
+	Name string `json:"name"`
+	// Alertmanager ConfigMap key
+	Key string `json:"key"`
+}
+
 type RuleSpec struct {
 	// Number of Rule replicas.
 	Replicas *int32 `json:"replicas,omitempty"`
@@ -331,6 +356,12 @@ type RuleSpec struct {
 	// AlertmanagerURLs
 	// +optional
 	AlertmanagerURLs []string `json:"alertmanagerURLs,omitempty"`
+	// ExtraVolumeMounts
+	// +optional
+	ExtraVolumeMounts []VolumeMount `json:"extraVolumeMounts,omitempty"`
+	// AlertmanagerConfigFile
+	// +optional
+	AlertmanagerConfigFile AlertmanagerConfigFile `json:"alertmanagerConfigFile,omitempty"`
 	// ReloaderImage is an image of configmap reloader
 	// +optional
 	ReloaderImage string `json:"reloaderImage,omitempty"`
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 8644b86b..79794554 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -109,6 +109,21 @@ func (in *APITenant) DeepCopy() *APITenant {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *AlertmanagerConfigFile) DeepCopyInto(out *AlertmanagerConfigFile) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlertmanagerConfigFile.
+func (in *AlertmanagerConfigFile) DeepCopy() *AlertmanagerConfigFile {
+	if in == nil {
+		return nil
+	}
+	out := new(AlertmanagerConfigFile)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *CompactSpec) DeepCopyInto(out *CompactSpec) {
 	*out = *in
@@ -564,6 +579,12 @@ func (in *RuleSpec) DeepCopyInto(out *RuleSpec) {
 		*out = make([]string, len(*in))
 		copy(*out, *in)
 	}
+	if in.ExtraVolumeMounts != nil {
+		in, out := &in.ExtraVolumeMounts, &out.ExtraVolumeMounts
+		*out = make([]VolumeMount, len(*in))
+		copy(*out, *in)
+	}
+	out.AlertmanagerConfigFile = in.AlertmanagerConfigFile
 	in.Resources.DeepCopyInto(&out.Resources)
 	in.ReloaderResources.DeepCopyInto(&out.ReloaderResources)
 }
@@ -713,3 +734,18 @@ func (in *VolumeClaimTemplate) DeepCopy() *VolumeClaimTemplate {
 	in.DeepCopyInto(out)
 	return out
 }
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VolumeMount) DeepCopyInto(out *VolumeMount) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeMount.
+func (in *VolumeMount) DeepCopy() *VolumeMount {
+	if in == nil {
+		return nil
+	}
+	out := new(VolumeMount)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/example/main.jsonnet b/example/main.jsonnet
index b936a3fc..53a673ad 100644
--- a/example/main.jsonnet
+++ b/example/main.jsonnet
@@ -163,6 +163,6 @@ local dex = (import 'github.com/observatorium/deployments/components/dex.libsonn
       volumeClaimTemplate: obs.loki.config.volumeClaimTemplate,
     },
     securityContext: {
-    }
+    },
   },
 }
diff --git a/jsonnet/jsonnetfile.json b/jsonnet/jsonnetfile.json
index 481a9397..a0a6139d 100644
--- a/jsonnet/jsonnetfile.json
+++ b/jsonnet/jsonnetfile.json
@@ -13,22 +13,21 @@
     {
       "source": {
         "git": {
-          "remote": "https://github.com/thanos-io/kube-thanos.git",
+          "remote": "https://github.com/open-cluster-management/kube-thanos.git",
           "subdir": "jsonnet/kube-thanos"
         }
-      }, 
-      "version": "main",
-      "name": "upstream-kube-thanos"
+      },
+      "version": "release-2.3"
     },
     {
       "source": {
         "git": {
-          "remote": "https://github.com/open-cluster-management/kube-thanos.git",
+          "remote": "https://github.com/thanos-io/kube-thanos.git",
           "subdir": "jsonnet/kube-thanos"
         }
       },
-      "version": "release-2.3",
-      "name": "kube-thanos"
+      "version": "main",
+      "name": "upstream-kube-thanos"
     }
   ],
   "legacyImports": true
diff --git a/jsonnet/jsonnetfile.lock.json b/jsonnet/jsonnetfile.lock.json
index c1da4f5f..6e35e374 100644
--- a/jsonnet/jsonnetfile.lock.json
+++ b/jsonnet/jsonnetfile.lock.json
@@ -51,8 +51,8 @@
           "subdir": "jsonnet/kube-thanos"
         }
       },
-      "version": "e9fb845c5229f7972e70da1be2ae240467c91523",
-      "sum": "SnDBgbjieU2jfiA9C+KuLgAg5gC/rbvC5xrMMpoh83o="
+      "version": "ae9971c285449364854d0ad4aab8b8258e4b7638",
+      "sum": "Ih4YDcFrAuARANPUzFBtxpTZb8on1dOeE9SseXWaLLU="
     },
     {
       "source": {
@@ -61,8 +61,8 @@
           "subdir": "jsonnet/kube-thanos"
         }
       },
-      "version": "c288ec08feb24be5da0174f39b96d7c224857926",
-      "sum": "CItqZ740EF1q6L2YU+66pmx8nKX4mxzXWlYMXSvLoFg=",
+      "version": "f53ad9856c6f765989ea76ba8eff8dd1e77186b7",
+      "sum": "1wMHM/+NvluUAxS5cBW2c6APEKQNQYLYnv1ZCE1R3/A=",
       "name": "upstream-kube-thanos"
     }
   ],
diff --git a/jsonnet/obs-operator.jsonnet b/jsonnet/obs-operator.jsonnet
index 78630ff0..177e928b 100644
--- a/jsonnet/obs-operator.jsonnet
+++ b/jsonnet/obs-operator.jsonnet
@@ -36,18 +36,18 @@ local operatorObs = obs {
     stores+:: {
       local deleteDelay = if std.objectHas(cr.spec.thanos, 'compact') && std.objectHas(cr.spec.thanos.compact, 'deleteDelay') then cr.spec.thanos.compact.deleteDelay else obs.thanos.compact.config.deleteDelay,
       securityContext: if std.objectHas(cr.spec, 'securityContext') then cr.spec.securityContext else obs.thanos.stores.config.securityContext,
-      ignoreDeletionMarksDelay: std.parseInt(std.substr(deleteDelay, 0, std.length(deleteDelay)-1))/2 + std.substr(deleteDelay, std.length(deleteDelay)-1, std.length(deleteDelay)),
+      ignoreDeletionMarksDelay: std.parseInt(std.substr(deleteDelay, 0, std.length(deleteDelay) - 1)) / 2 + std.substr(deleteDelay, std.length(deleteDelay) - 1, std.length(deleteDelay)),
     } + if std.objectHas(cr.spec.thanos, 'store') then cr.spec.thanos.store else {},
 
     storeCache+:: (if std.objectHas(cr.spec.thanos, 'store') && std.objectHas(cr.spec.thanos.store, 'cache') then cr.spec.thanos.store.cache else {}) + {
       memoryLimitMb: if std.objectHas(cr.spec.thanos.store, 'cache') && std.objectHas(cr.spec.thanos.store.cache, 'memoryLimitMb') then cr.spec.thanos.store.cache.memoryLimitMb else obs.thanos.storeCache.config.memoryLimitMb,
       resources+: (
         if std.objectHas(cr.spec.thanos.store.cache, 'resources') then {
-          memcached: cr.spec.thanos.store.cache.resources
+          memcached: cr.spec.thanos.store.cache.resources,
         } else {}
       ) + (
         if std.objectHas(cr.spec.thanos.store.cache, 'exporterResources') then {
-          exporter: cr.spec.thanos.store.cache.exporterResources
+          exporter: cr.spec.thanos.store.cache.exporterResources,
         } else {}
       ),
       securityContext: if std.objectHas(cr.spec, 'securityContext') then cr.spec.securityContext else obs.thanos.storeCache.config.securityContext,
@@ -65,26 +65,26 @@ local operatorObs = obs {
       memoryLimitMb: if std.objectHas(cr.spec.thanos.queryFrontend, 'cache') && std.objectHas(cr.spec.thanos.queryFrontend.cache, 'memoryLimitMb') then cr.spec.thanos.queryFrontend.cache.memoryLimitMb else obs.thanos.queryFrontendCache.config.memoryLimitMb,
       resources+: (
         if std.objectHas(cr.spec.thanos.queryFrontend.cache, 'resources') then {
-          memcached: cr.spec.thanos.queryFrontend.cache.resources
+          memcached: cr.spec.thanos.queryFrontend.cache.resources,
         } else {}
       ) + (
         if std.objectHas(cr.spec.thanos.queryFrontend.cache, 'exporterResources') then {
-          exporter: cr.spec.thanos.queryFrontend.cache.exporterResources
+          exporter: cr.spec.thanos.queryFrontend.cache.exporterResources,
         } else {}
       ),
       securityContext: if std.objectHas(cr.spec, 'securityContext') then cr.spec.securityContext else obs.thanos.queryFrontendCache.config.securityContext,
-    }
+    },
   }),
 
   loki:: if std.objectHas(cr.spec, 'loki') then loki(obs.loki.config {
-      local cfg = self,
-      name: cr.metadata.name + '-' + cfg.commonLabels['app.kubernetes.io/name'],
-      namespace: cr.metadata.namespace,
-      image: if std.objectHas(cr.spec.loki, 'image') then cr.spec.loki.image else obs.loki.config.image,
-      replicas: if std.objectHas(cr.spec.loki, 'replicas') then cr.spec.loki.replicas else obs.loki.config.replicas,
-      version: if std.objectHas(cr.spec.loki, 'version') then cr.spec.loki.version else obs.loki.config.version,
-      objectStorageConfig: if cr.spec.objectStorageConfig.loki != null then cr.spec.objectStorageConfig.loki else obs.loki.config.objectStorageConfig,
-    }) else {},
+    local cfg = self,
+    name: cr.metadata.name + '-' + cfg.commonLabels['app.kubernetes.io/name'],
+    namespace: cr.metadata.namespace,
+    image: if std.objectHas(cr.spec.loki, 'image') then cr.spec.loki.image else obs.loki.config.image,
+    replicas: if std.objectHas(cr.spec.loki, 'replicas') then cr.spec.loki.replicas else obs.loki.config.replicas,
+    version: if std.objectHas(cr.spec.loki, 'version') then cr.spec.loki.version else obs.loki.config.version,
+    objectStorageConfig: if cr.spec.objectStorageConfig.loki != null then cr.spec.objectStorageConfig.loki else obs.loki.config.objectStorageConfig,
+  }) else {},
 
   gubernator:: {},
 
@@ -151,14 +151,14 @@ local operatorObs = obs {
     ) + (
       if (v.kind == 'StatefulSet' || v.kind == 'Deployment') then {
         template+: {
-          spec+:{
+          spec+: {
             affinity: {
               podAntiAffinity: {
                 preferredDuringSchedulingIgnoredDuringExecution: [
                   {
                     podAffinityTerm: {
                       labelSelector: {
-                        matchExpressions:[
+                        matchExpressions: [
                           {
                             key: 'app.kubernetes.io/name',
                             operator: 'In',
@@ -175,14 +175,14 @@ local operatorObs = obs {
                           },
                         ],
                       },
-                      topologyKey: "kubernetes.io/hostname",
+                      topologyKey: 'kubernetes.io/hostname',
                     },
                     weight: 30,
                   },
                   {
                     podAffinityTerm: {
                       labelSelector: {
-                        matchExpressions:[
+                        matchExpressions: [
                           {
                             key: 'app.kubernetes.io/name',
                             operator: 'In',
@@ -199,7 +199,7 @@ local operatorObs = obs {
                           },
                         ],
                       },
-                      topologyKey: "topology.kubernetes.io/zone",
+                      topologyKey: 'topology.kubernetes.io/zone',
                     },
                     weight: 70,
                   },
@@ -220,7 +220,7 @@ local operatorObs = obs {
     ) + (
       if (std.objectHas(cr.spec, 'tolerations') && (v.kind == 'StatefulSet' || v.kind == 'Deployment')) then {
         template+: {
-          spec+:{
+          spec+: {
             tolerations: cr.spec.tolerations,
           },
         },
@@ -228,7 +228,7 @@ local operatorObs = obs {
     ) + (
       if (std.objectHas(cr.spec.thanos.rule, 'reloaderResources') && (v.kind == 'StatefulSet') && v.metadata.name == obs.config.name + '-thanos-rule') then {
         template+: {
-          spec+:{
+          spec+: {
             containers: [
               if c.name == 'configmap-reloader' then c {
                 resources: cr.spec.thanos.rule.reloaderResources,
diff --git a/jsonnet/vendor/github.com/open-cluster-management/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet b/jsonnet/vendor/github.com/open-cluster-management/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
index 1c2cd560..17238738 100644
--- a/jsonnet/vendor/github.com/open-cluster-management/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
+++ b/jsonnet/vendor/github.com/open-cluster-management/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
@@ -15,6 +15,8 @@ local defaults = {
   retention: '48h',
   blockDuration: '2h',
   alertmanagersURLs: [],
+  alertmanagerConfigFile: {},
+  extraVolumeMounts: [],
   queriers: [],
   logLevel: 'info',
   logFormat: 'logfmt',
@@ -53,6 +55,8 @@ function(params) {
   // Safety checks for combined config of defaults and params
   assert std.isNumber(tr.config.replicas) && tr.config.replicas >= 0 : 'thanos rule replicas has to be number >= 0',
   assert std.isArray(tr.config.ruleFiles),
+  assert std.isObject(tr.config.alertmanagerConfigFile),
+  assert std.isArray(tr.config.extraVolumeMounts),
   assert std.isArray(tr.config.rulesConfig),
   assert std.isArray(tr.config.alertmanagersURLs),
   assert std.isObject(tr.config.resources),
@@ -118,6 +122,11 @@ function(params) {
         (['--rule-file=%s' % path for path in tr.config.ruleFiles]) +
         (['--alertmanagers.url=%s' % url for url in tr.config.alertmanagersURLs]) +
         (
+          if tr.config.alertmanagerConfigFile != {} then [
+            '--alertmanagers.config-file=/etc/thanos/config/' + tr.config.alertmanagerConfigFile.name + '/' + tr.config.alertmanagerConfigFile.key
+          ]
+          else []
+        ) + (
           if std.length(tr.config.rulesConfig) > 0 then [
             '--rule-file=/etc/thanos/rules/' + ruleConfig.name + '/' + ruleConfig.key
             for ruleConfig in tr.config.rulesConfig
@@ -150,6 +159,15 @@ function(params) {
           { name: ruleConfig.name, mountPath: '/etc/thanos/rules/' + ruleConfig.name }
           for ruleConfig in tr.config.rulesConfig
         ] else []
+      ) + (
+        if std.length(tr.config.extraVolumeMounts) > 0 then [
+          { name: volumeMount.name, mountPath: volumeMount.mountPath }
+          for volumeMount in tr.config.extraVolumeMounts
+        ] else []
+      ) + (
+        if tr.config.alertmanagerConfigFile != {} then [
+          { name: tr.config.alertmanagerConfigFile.name, mountPath: '/etc/thanos/config/' + tr.config.alertmanagerConfigFile.name }
+        ] else []
       ),
       livenessProbe: { failureThreshold: 24, periodSeconds: 5, httpGet: {
         scheme: 'HTTP',
@@ -173,11 +191,32 @@ function(params) {
         [
           '-webhook-url=http://localhost:' + tr.service.spec.ports[1].port + '/-/reload',
         ] +
-        (['-volume-dir=/etc/thanos/rules/' + ruleConfig.name for ruleConfig in tr.config.rulesConfig]),
+        (
+          if std.length(tr.config.rulesConfig) > 0 then [
+            '-volume-dir=/etc/thanos/rules/' + ruleConfig.name for ruleConfig in tr.config.rulesConfig
+          ] else []
+        ) + (
+          if std.length(tr.config.extraVolumeMounts) > 0 then [
+            '-volume-dir=' + volumeMount.mountPath for volumeMount in tr.config.extraVolumeMounts
+          ] else []
+        ) + (
+          if tr.config.alertmanagerConfigFile != {} then [
+            '-volume-dir=/etc/thanos/config/' + tr.config.alertmanagerConfigFile.name
+          ] else []
+        ),
       volumeMounts: [
         { name: ruleConfig.name, mountPath: '/etc/thanos/rules/' + ruleConfig.name }
         for ruleConfig in tr.config.rulesConfig
-      ],
+      ] + (
+        if std.length(tr.config.extraVolumeMounts) > 0 then [
+          { name: volumeMount.name, mountPath: volumeMount.mountPath }
+          for volumeMount in tr.config.extraVolumeMounts
+        ] else []
+      ) + (
+        if tr.config.alertmanagerConfigFile != {} then [
+          { name: tr.config.alertmanagerConfigFile.name, mountPath: '/etc/thanos/config/' + tr.config.alertmanagerConfigFile.name }
+        ] else []
+      ),
     };
 
     {
@@ -200,11 +239,35 @@ function(params) {
             serviceAccountName: tr.serviceAccount.metadata.name,
             securityContext: tr.config.securityContext,
             containers: [c] +
-                        (if std.length(tr.config.rulesConfig) > 0 then [reloadContainer] else []),
-            volumes: [
-              { name: ruleConfig.name, configMap: { name: ruleConfig.name } }
-              for ruleConfig in tr.config.rulesConfig
-            ],
+                        (if std.length(tr.config.rulesConfig) > 0 || std.length(tr.config.extraVolumeMounts) > 0 || tr.config.alertmanagerConfigFile != {} then [
+                          reloadContainer
+                        ] else []),
+            volumes: [] +
+            (
+              if std.length(tr.config.rulesConfig) > 0 then [
+                { name: ruleConfig.name, configMap: { name: ruleConfig.name } }
+                for ruleConfig in tr.config.rulesConfig
+              ] else []
+            ) +
+            (
+              if std.length(tr.config.extraVolumeMounts) > 0 then [
+                { name: volumeMount.name, } +
+                (
+                  if volumeMount.type == "configMap" then {
+                    configMap : { name: volumeMount.name }
+                  }
+                  else {
+                    secret : { name: volumeMount.name }
+                  }
+                )
+                for volumeMount in tr.config.extraVolumeMounts
+              ] else []
+            ) +
+            (
+              if tr.config.alertmanagerConfigFile != {} then [{
+                name: tr.config.alertmanagerConfigFile.name, configMap: { name: tr.config.alertmanagerConfigFile.name }
+              }] else []
+            ),
           },
         },
         volumeClaimTemplates: if std.length(tr.config.volumeClaimTemplate) > 0 then [tr.config.volumeClaimTemplate {
diff --git a/jsonnet/vendor/github.com/thanos-io/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet b/jsonnet/vendor/github.com/thanos-io/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
index 0d817c95..922cf7a4 100644
--- a/jsonnet/vendor/github.com/thanos-io/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
+++ b/jsonnet/vendor/github.com/thanos-io/kube-thanos/jsonnet/kube-thanos/kube-thanos-rule.libsonnet
@@ -17,6 +17,8 @@ local defaults = {
   logLevel: 'info',
   logFormat: 'logfmt',
   resources: {},
+  retention: '48h',
+  blockDuration: '2h',
   serviceMonitor: false,
   ports: {
     grpc: 10901,
@@ -109,6 +111,8 @@ function(params) {
           '--data-dir=/var/thanos/rule',
           '--label=rule_replica="$(NAME)"',
           '--alert.label-drop=rule_replica',
+          '--tsdb.retention=' + tr.config.retention,
+          '--tsdb.block-duration=' + tr.config.blockDuration,
         ] +
         (['--query=%s' % querier for querier in tr.config.queriers]) +
         (['--rule-file=%s' % path for path in tr.config.ruleFiles]) +
diff --git a/manifests/crds/core.observatorium.io_observatoria.yaml b/manifests/crds/core.observatorium.io_observatoria.yaml
index a3a5a8f5..20c00761 100644
--- a/manifests/crds/core.observatorium.io_observatoria.yaml
+++ b/manifests/crds/core.observatorium.io_observatoria.yaml
@@ -1284,6 +1284,19 @@ spec:
                   rule:
                     description: Thanos RulerSpec
                     properties:
+                      alertmanagerConfigFile:
+                        description: AlertmanagerConfigFile
+                        properties:
+                          key:
+                            description: Alertmanager ConfigMap key
+                            type: string
+                          name:
+                            description: Alertmanager ConfigMap Name
+                            type: string
+                        required:
+                        - key
+                        - name
+                        type: object
                       alertmanagerURLs:
                         description: AlertmanagerURLs
                         items:
@@ -1292,6 +1305,29 @@ spec:
                       blockDuration:
                         description: Block duration for TSDB block
                         type: string
+                      extraVolumeMounts:
+                        description: ExtraVolumeMounts
+                        items:
+                          properties:
+                            key:
+                              description: File name for the mount
+                              type: string
+                            mountPath:
+                              description: Volume mount path in the pod
+                              type: string
+                            name:
+                              description: Resource name for the volume mount source
+                              type: string
+                            type:
+                              description: Voume mount type, configMap or secret
+                              type: string
+                          required:
+                          - key
+                          - mountPath
+                          - name
+                          - type
+                          type: object
+                        type: array
                       reloaderImage:
                         description: ReloaderImage is an image of configmap reloader
                         type: string