Repository: open-telemetry/opentelemetry-operator

Issue:
Collector unable to use TLS Config from Target Allocator with ScrapeConfig
### Component(s)

collector, target allocator

### What happened?

## Description
The OpenTelemetry Collector is unable to use the TLS Configuration values that are specified in a ScrapeConfig CR from the Target Allocator.

## Steps to Reproduce

1. Setup OTel Operator with PrometheusCR to have a collector and target allocator setup.
2. Specify a ScrapeConfig to scrape the nodes in the cluster

```yaml
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:
  name: scrape-config
spec:
  scheme: HTTPS
  kubernetesSDConfigs:
    - role: Node
  authorization:
    type: Bearer
    credentials:
      key: "token"
      name: "opentelemetry-collector"
  tlsConfig:
    ca:
      secret:
        key: "ca.crt"
        name: "opentelemetry-collector"
    insecureSkipVerify: false
```

## Expected Result

Successful scraping of the Kubernetes node.

## Actual Result

Error while reading CA certificate needed to verify communication with Kubernetes node.

### Kubernetes Version

1.31.0

### Operator version

0.118.0

### Collector version

0.118.0

### Environment information

The operator is configured with `--feature-gates=operator.targetallocator.mtls` to allow for the collector to get secret information from the target allocator.

### Log output

The collector logs this error:

```shell
error	scrape/manager.go:258	error reloading scrape pool	{"kind": "receiver", "name": "prometheus", "data_type": "metrics", "error": "error creating HTTP client: unable to read CA cert: unable to read file /etc/prometheus/certs/opentelemetry-collector_ca.crt: open /etc/prometheus/certs/opentelemetry-collector_ca.crt: no such file or directory", "scrape_pool": "scrapeConfig/static-config"}
github.com/prometheus/prometheus/scrape.(*Manager).ApplyConfig
	github.com/prometheus/prometheus@v0.54.1/scrape/manager.go:258
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/targetallocator.(*Manager).applyCfg
	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver@v0.118.0/targetallocator/manager.go:177
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/targetallocator.(*Manager).sync
	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver@v0.118.0/targetallocator/manager.go:156
github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/targetallocator.(*Manager).Start.func1
	github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver@v0.118.0/targetallocator/manager.go:80
```

### Additional context

The scrape config from the Target Allocator looks something like this.

```
curl -s localhost:8080/scrape_configs | jq
{
  "scrapeConfig/static-config": {
    "authorization": {
      "credentials": "<secret>",
      "type": "Bearer"
    },
    "job_name": "scrapeConfig/static-config",
    "kubernetes_sd_configs": [
      {
        "role": "node"
      }
    ],
    "metrics_path": "/metrics",
    "scheme": "https",
    "tls_config": {
      "ca_file": "/etc/prometheus/certs/opentelemetry-collector_ca.crt",
      "insecure_skip_verify": false
    },
    "track_timestamps_staleness": false
  }
}
```

It's possible to have the `ca_file` become just `ca` with the contents of the file being referenced. The change would happen in https://github.com/prometheus-operator/prometheus-operator/blob/8b110a62bb134bad46fc5382776943a9059c4fa0/pkg/prometheus/promcfg.go#L628-L630 similar to how the authorization credentials are given to the collector in https://github.com/prometheus-operator/prometheus-operator/blob/8b110a62bb134bad46fc5382776943a9059c4fa0/pkg/prometheus/promcfg.go#L503-L511

Hints from issue comments:
@CharlieTLe: Probably related to https://github.com/open-telemetry/opentelemetry-operator/issues/3572@CharlieTLe: Now that https://github.com/prometheus-operator/prometheus-operator/pull/7359 is merged, we should be able to set inlineTLSConfig to true in the ConfigGenerator to get the cert details needed for the collector from the TA.@fasher: @CharlieTLe is there any workaround to this issue ? 

Solution patch:
diff --git a/.chloggen/move_instrumentation.yaml b/.chloggen/breaking_drop-kube-124-125.yaml
similarity index 86%
rename from .chloggen/move_instrumentation.yaml
rename to .chloggen/breaking_drop-kube-124-125.yaml
index a4976c60..2fe25daa 100644
--- a/.chloggen/move_instrumentation.yaml
+++ b/.chloggen/breaking_drop-kube-124-125.yaml
@@ -2,13 +2,13 @@
 change_type: breaking
 
 # The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: pkg/instrumentation
+component: operator
 
 # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Move pkg/instrumentation to internal/instrumentation
+note: Drop support for Kubernetes 1.23 and 1.24
 
 # One or more tracking issues related to the change
-issues: [4140]
+issues: [4104]
 
 # (Optional) One or more lines of additional information to render under the primary note.
 # These lines will be padded with 2 spaces and then inserted directly into the document.
diff --git a/.chloggen/enable_webhooks.yaml b/.chloggen/enable_webhooks.yaml
deleted file mode 100644
index d2f96fec..00000000
--- a/.chloggen/enable_webhooks.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: enhancement
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: controller
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Expose the ENABLE_WEBHOOKS env var as part of configuration
-
-# One or more tracking issues related to the change
-issues: [3565]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/fix-must-gather.yaml b/.chloggen/fix-must-gather.yaml
deleted file mode 100644
index 08e02a55..00000000
--- a/.chloggen/fix-must-gather.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: bug_fix
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: target allocator
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Fix OpenShift must-gather for Target Allocator
-
-# One or more tracking issues related to the change
-issues: [4084]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/fix-4082.yaml b/.chloggen/fix-ta-tlsconfig-scrapeconfig.yaml
similarity index 76%
rename from .chloggen/fix-4082.yaml
rename to .chloggen/fix-ta-tlsconfig-scrapeconfig.yaml
index beb4a584..a24a77a6 100644
--- a/.chloggen/fix-4082.yaml
+++ b/.chloggen/fix-ta-tlsconfig-scrapeconfig.yaml
@@ -5,12 +5,13 @@ change_type: bug_fix
 component: target allocator
 
 # A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: ensure stable iteration order of target labels when generating hash
+note: Allow collector to use TLS Config from Target Allocator with ScrapeConfig
 
 # One or more tracking issues related to the change
-issues: [4082]
+issues: [3724]
 
 # (Optional) One or more lines of additional information to render under the primary note.
 # These lines will be padded with 2 spaces and then inserted directly into the document.
 # Use pipe (|) for multiline entries.
-subtext:
+subtext: |
+  This change allows the target allocator to configure TLS Config for a collector using the ScrapeConfig.
diff --git a/.chloggen/fix_opampbridge.yaml b/.chloggen/fix_opampbridge.yaml
deleted file mode 100644
index 68e0ae95..00000000
--- a/.chloggen/fix_opampbridge.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: bug_fix
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: opampbridge
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Do not register the opampbridge webhook if the CRD is not present
-
-# One or more tracking issues related to the change
-issues: [4070]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/harmonize_config.yaml b/.chloggen/harmonize_config.yaml
deleted file mode 100644
index a62bec9f..00000000
--- a/.chloggen/harmonize_config.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: enhancement
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: controller
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Harmonize CLI and env var configuration to allow setting all configuration
-
-# One or more tracking issues related to the change
-issues: [3565]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext: |
-  In order of priority, the default configuration is assigned first, overwritten by environment variables and CLI arguments successively.
-  
diff --git a/.chloggen/issue_4071.yaml b/.chloggen/issue_4071.yaml
deleted file mode 100644
index cda5b43b..00000000
--- a/.chloggen/issue_4071.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: 'enhancement'
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: managementState
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: managementState property on resources is no longer a required field since it has a default value as managed
-
-# One or more tracking issues related to the change
-issues: [4076]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/operator33.yaml b/.chloggen/operator33.yaml
deleted file mode 100644
index 14767bd1..00000000
--- a/.chloggen/operator33.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: 'enhancement'
-
-# The name of the component, or a single word describing the area of concern, (e.g. operator, target allocator, github action)
-component: operator
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Support for Kubernetes `1.33`  version.
-
-# One or more tracking issues related to the change
-issues: [4048]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
\ No newline at end of file
diff --git a/.chloggen/otel-targetallocator-html.yaml b/.chloggen/otel-targetallocator-html.yaml
deleted file mode 100644
index caffeb8b..00000000
--- a/.chloggen/otel-targetallocator-html.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: enhancement
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: target allocator
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: "Adds support for HTML output in the target allocator."
-
-# One or more tracking issues related to the change
-issues: [3622]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/patch-1.yaml b/.chloggen/patch-1.yaml
deleted file mode 100644
index 65d368fe..00000000
--- a/.chloggen/patch-1.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: bug_fix
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: auto-instrumentation
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Fix the bug that k8s.container.name in OTEL_RESOURCE_ATTRIBUTES env is not set correctly for Go the auto-instrumentation when the pod has multiple containers.
-
-# One or more tracking issues related to the change
-issues: [4089]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/remove_invalid_featuregate_refs.yaml b/.chloggen/remove_invalid_featuregate_refs.yaml
deleted file mode 100644
index ae689726..00000000
--- a/.chloggen/remove_invalid_featuregate_refs.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: bug_fix
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: operator
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Remove invalid `operator.observability.prometheus` feature flag references
-
-# One or more tracking issues related to the change
-issues: [4159]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext: |
-  Fixed operator installation failure caused by references to the non-existent `operator.observability.prometheus` feature flag.
-  Removed the flag from the bundle and cleaned up API and documentation references.
diff --git a/.chloggen/remove_stable_featuregate.yaml b/.chloggen/remove_stable_featuregate.yaml
deleted file mode 100644
index 041584f7..00000000
--- a/.chloggen/remove_stable_featuregate.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: breaking
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: targetallocator, collector
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Remove stable feature gate PrometheusOperatorIsAvailable
-
-# One or more tracking issues related to the change
-issues: [4141]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.chloggen/sts-svc-custom-naming.yaml b/.chloggen/sts-svc-custom-naming.yaml
deleted file mode 100644
index 3fb35fe8..00000000
--- a/.chloggen/sts-svc-custom-naming.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: bug_fix
-
-# The name of the component, or a single word describing the area of concern
-component: collector
-
-# A brief description of the change
-note: "Fix the headless service name in StatefulSet mode to ensure consistent DNS resolution. The ServiceName field in the OpenTelemetryCollector spec can be used to customize the StatefulSet's serviceName."
-
-# One or more tracking issues related to the change
-issues: [4029]
-
-# Optional additional information
-subtext: |
-  The ServiceName field in the OpenTelemetryCollector
-  spec can be used to customize the StatefulSet's serviceName if needed, while maintaining
-  the default behavior of using the headless service name.
\ No newline at end of file
diff --git a/.chloggen/support_config_file.yaml b/.chloggen/support_config_file.yaml
deleted file mode 100644
index 6dab741b..00000000
--- a/.chloggen/support_config_file.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
-change_type: enhancement
-
-# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
-component: controller
-
-# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
-note: Support a yaml config file to set all the configuration options exposed by controllers
-
-# One or more tracking issues related to the change
-issues: [3565]
-
-# (Optional) One or more lines of additional information to render under the primary note.
-# These lines will be padded with 2 spaces and then inserted directly into the document.
-# Use pipe (|) for multiline entries.
-subtext:
diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml
index 96c282b5..964ec8bb 100644
--- a/.github/workflows/continuous-integration.yaml
+++ b/.github/workflows/continuous-integration.yaml
@@ -6,6 +6,9 @@ on:
   pull_request:
     branches: [ main ]
 
+permissions:
+  contents: read
+
 concurrency:
   group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
   cancel-in-progress: true
@@ -84,15 +87,15 @@ jobs:
         go-version: "~1.24.4"
 
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
+      uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
       with:
         languages: go
 
     - name: Autobuild
-      uses: github/codeql-action/autobuild@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
+      uses: github/codeql-action/autobuild@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
 
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
+      uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
 
     - name: Govulncheck
       uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1.0.4
diff --git a/.github/workflows/e2e-junit-report.yml b/.github/workflows/e2e-junit-report.yml
index 037be4fc..17ed8d5b 100644
--- a/.github/workflows/e2e-junit-report.yml
+++ b/.github/workflows/e2e-junit-report.yml
@@ -10,12 +10,14 @@ on:
         required: true
 
 permissions:
-  checks: write
-  pull-requests: write
-  actions: read
+  contents: read
 
 jobs:
   report:
+    permissions:
+      checks: write
+      pull-requests: write
+      actions: read
     runs-on: ubuntu-latest
     steps:
       - name: Download Test Report
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 317430fc..50e2abd9 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -59,7 +59,7 @@ jobs:
        # All Kubernetes version in between expose the same APIs, hence the operator
        # should be compatible with them.
        kube-version:
-         - "1.23"
+         - "1.25"
          - "1.33"
        group:
          - e2e
diff --git a/.github/workflows/ossf-scorecard.yml b/.github/workflows/ossf-scorecard.yml
index 69e5b808..472be229 100644
--- a/.github/workflows/ossf-scorecard.yml
+++ b/.github/workflows/ossf-scorecard.yml
@@ -42,6 +42,6 @@ jobs:
       # Upload the results to GitHub's code scanning dashboard (optional).
       # Commenting out will disable upload of results to your repo's Code Scanning dashboard
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@39edc492dbe16b1465b0cafca41432d857bdb31a # v3.29.1
+        uses: github/codeql-action/upload-sarif@181d5eefc20863364f96762470ba6f862bdef56b # v3.29.2
         with:
           sarif_file: results.sarif
diff --git a/.github/workflows/publish-autoinstrumentation-apache-httpd.yaml b/.github/workflows/publish-autoinstrumentation-apache-httpd.yaml
index 096de14c..7b6fd9e7 100644
--- a/.github/workflows/publish-autoinstrumentation-apache-httpd.yaml
+++ b/.github/workflows/publish-autoinstrumentation-apache-httpd.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-autoinstrumentation-dotnet.yaml b/.github/workflows/publish-autoinstrumentation-dotnet.yaml
index 522ecb1e..132dffb4 100644
--- a/.github/workflows/publish-autoinstrumentation-dotnet.yaml
+++ b/.github/workflows/publish-autoinstrumentation-dotnet.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-autoinstrumentation-java.yaml b/.github/workflows/publish-autoinstrumentation-java.yaml
index 03fbf04b..f7176f7e 100644
--- a/.github/workflows/publish-autoinstrumentation-java.yaml
+++ b/.github/workflows/publish-autoinstrumentation-java.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-autoinstrumentation-nodejs.yaml b/.github/workflows/publish-autoinstrumentation-nodejs.yaml
index 76f58b1e..e9fd05c1 100644
--- a/.github/workflows/publish-autoinstrumentation-nodejs.yaml
+++ b/.github/workflows/publish-autoinstrumentation-nodejs.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-autoinstrumentation-php.yaml b/.github/workflows/publish-autoinstrumentation-php.yaml
index a0a21f33..9e8d678e 100644
--- a/.github/workflows/publish-autoinstrumentation-php.yaml
+++ b/.github/workflows/publish-autoinstrumentation-php.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-autoinstrumentation-python.yaml b/.github/workflows/publish-autoinstrumentation-python.yaml
index 6e6ffb7e..f7d4860a 100644
--- a/.github/workflows/publish-autoinstrumentation-python.yaml
+++ b/.github/workflows/publish-autoinstrumentation-python.yaml
@@ -19,12 +19,13 @@ concurrency:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-images.yaml b/.github/workflows/publish-images.yaml
index c2623340..236d2bb6 100644
--- a/.github/workflows/publish-images.yaml
+++ b/.github/workflows/publish-images.yaml
@@ -12,12 +12,13 @@ env:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     name: Publish container images
     runs-on: ubuntu-latest
     steps:
diff --git a/.github/workflows/publish-must-gather.yaml b/.github/workflows/publish-must-gather.yaml
index 7f0f1e2a..e49ee6a2 100644
--- a/.github/workflows/publish-must-gather.yaml
+++ b/.github/workflows/publish-must-gather.yaml
@@ -12,12 +12,13 @@ env:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     name: Publish must-gather container image
     runs-on: ubuntu-latest
     steps:
diff --git a/.github/workflows/publish-operator-bundle.yaml b/.github/workflows/publish-operator-bundle.yaml
index 64d34a82..3aa17b14 100644
--- a/.github/workflows/publish-operator-bundle.yaml
+++ b/.github/workflows/publish-operator-bundle.yaml
@@ -13,12 +13,13 @@ on:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-operator-hub.yaml b/.github/workflows/publish-operator-hub.yaml
index c4a78f11..d032a289 100644
--- a/.github/workflows/publish-operator-hub.yaml
+++ b/.github/workflows/publish-operator-hub.yaml
@@ -3,8 +3,13 @@ on:
   release:
     types: [published]
 
+permissions:
+  contents: read
+
 jobs:
   operator-hub-prod-release:
+    permissions: # required by the reusable workflow
+      contents: write
     uses: ./.github/workflows/reusable-operator-hub-release.yaml
     with:
       org: redhat-openshift-ecosystem
@@ -14,6 +19,8 @@ jobs:
       OPENTELEMETRYBOT_GITHUB_TOKEN: ${{ secrets.OPENTELEMETRYBOT_GITHUB_TOKEN }}
 
   operator-hub-community-release:
+    permissions: # required by the reusable workflow
+      contents: write
     uses: ./.github/workflows/reusable-operator-hub-release.yaml
     with:
       org: k8s-operatorhub
diff --git a/.github/workflows/publish-operator-opamp-bridge.yaml b/.github/workflows/publish-operator-opamp-bridge.yaml
index 37a51b58..3102d663 100644
--- a/.github/workflows/publish-operator-opamp-bridge.yaml
+++ b/.github/workflows/publish-operator-opamp-bridge.yaml
@@ -16,12 +16,13 @@ env:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-target-allocator.yaml b/.github/workflows/publish-target-allocator.yaml
index 7c4f3b03..970d4ef1 100644
--- a/.github/workflows/publish-target-allocator.yaml
+++ b/.github/workflows/publish-target-allocator.yaml
@@ -16,12 +16,13 @@ env:
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
diff --git a/.github/workflows/publish-test-e2e-images.yaml b/.github/workflows/publish-test-e2e-images.yaml
index 2f91f085..d22c7496 100644
--- a/.github/workflows/publish-test-e2e-images.yaml
+++ b/.github/workflows/publish-test-e2e-images.yaml
@@ -5,55 +5,103 @@ on:
     paths:
       - 'tests/test-e2e-apps/**'
       - '.github/workflows/publish-test-e2e-images.yaml'
+      - '.github/workflows/reusable-publish-test-e2e-images.yaml'
     branches:
       - main
   pull_request:
     paths:
       - 'tests/test-e2e-apps/**'
       - '.github/workflows/publish-test-e2e-images.yaml'
+      - '.github/workflows/reusable-publish-test-e2e-images.yaml'
   workflow_dispatch:
 
+permissions:
+  contents: read
+
 concurrency:
   group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
   cancel-in-progress: true
 
 jobs:
   bridge-server:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: bridge-server
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
   golang:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: golang
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
-  python:
+  python-latest:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
+    uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
+    with:
+      path: python
+      platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
+  python-oldest:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: python
+      build-args: 'python_version=3.9'
+      tag-suffix: '-3.9'
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
   java:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: java
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
   apache-httpd:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: apache-httpd
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
   dotnet:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: dotnet
       platforms: linux/arm64,linux/amd64
   nodejs:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: nodejs
       platforms: linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
   metrics-basic-auth:
+    permissions: # required by the reusable workflow
+      packages: write
+      attestations: write
+      id-token: write
     uses: ./.github/workflows/reusable-publish-test-e2e-images.yaml
     with:
       path: metrics-basic-auth
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 2ade347c..7966b67e 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -7,6 +7,9 @@ on:
     paths:
       - 'versions.txt'
 
+permissions:
+  contents: read
+
 jobs:
   get-versions:
     runs-on: ubuntu-latest
diff --git a/.github/workflows/reusable-publish-test-e2e-images.yaml b/.github/workflows/reusable-publish-test-e2e-images.yaml
index 30a74190..3ba50cdd 100644
--- a/.github/workflows/reusable-publish-test-e2e-images.yaml
+++ b/.github/workflows/reusable-publish-test-e2e-images.yaml
@@ -9,15 +9,24 @@ on:
       platforms:
         type: string
         required: true
+      build-args:
+        type: string
+        required: false
+        default: ''
+      tag-suffix:
+        type: string
+        required: false
+        default: ''
 
 permissions:
   contents: read
-  packages: write
-  attestations: write
-  id-token: write
 
 jobs:
   publish-e2e-image:
+    permissions:
+      packages: write
+      attestations: write
+      id-token: write
     runs-on: ubuntu-latest
 
     steps:
@@ -28,9 +37,9 @@ jobs:
         uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
         with:
           images: |
-            ghcr.io/open-telemetry/opentelemetry-operator/e2e-test-app-${{ inputs.path }}
+            ghcr.io/${{ github.repository }}/e2e-test-app-${{ inputs.path }}
           tags: |
-            type=ref,event=branch
+            type=ref,event=branch,suffix=${{ inputs.tag-suffix }}
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
@@ -59,6 +68,7 @@ jobs:
           tags: ${{ steps.meta.outputs.tags }}
           context: tests/test-e2e-apps/${{ inputs.path }}
           platforms: ${{ inputs.platforms }}
+          build-args: ${{ inputs.build-args }}
           push: ${{ github.event_name == 'push' }}
           cache-from: type=local,src=/tmp/.buildx-cache
           cache-to: type=local,dest=/tmp/.buildx-cache
diff --git a/.github/workflows/scorecard.yaml b/.github/workflows/scorecard.yaml
index 073ee438..f3bfd70d 100644
--- a/.github/workflows/scorecard.yaml
+++ b/.github/workflows/scorecard.yaml
@@ -20,7 +20,7 @@ jobs:
     strategy:
       matrix:
         kube-version:
-          - "1.23"
+          - "1.25"
           - "1.33"
 
     steps:
diff --git a/.github/workflows/shellcheck.yaml b/.github/workflows/shellcheck.yaml
index 10b23b23..429c2a16 100644
--- a/.github/workflows/shellcheck.yaml
+++ b/.github/workflows/shellcheck.yaml
@@ -4,7 +4,8 @@ on:
     branches:
       - main
   pull_request:
-permissions: {}
+permissions:
+  contents: read
 
 jobs:
   shellcheck:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 654b9a9e..0d75a1cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,49 @@
 
 <!-- next version -->
 
+## 0.129.1
+
+### 🛑 Breaking changes 🛑
+
+- `pkg/instrumentation`: Move pkg/instrumentation to internal/instrumentation (#4140)
+- `targetallocator, collector`: Remove stable feature gate PrometheusOperatorIsAvailable (#4141)
+
+### 💡 Enhancements 💡
+
+- `controller`: Harmonize CLI and env var configuration to allow setting all configuration (#3565)
+  In order of priority, the default configuration is assigned first, overwritten by environment variables and CLI arguments successively.
+  
+- `managementState`: managementState property on resources is no longer a required field since it has a default value as managed (#4076)
+- `operator`: Support for Kubernetes `1.33`  version. (#4048)
+- `target allocator`: Adds support for HTML output in the target allocator. (#3622)
+- `controller`: Support a yaml config file to set all the configuration options exposed by controllers (#3565)
+
+### 🧰 Bug fixes 🧰
+
+- `target allocator`: ensure stable iteration order of target labels when generating hash (#4082)
+- `target allocator`: Fix OpenShift must-gather for Target Allocator (#4084)
+- `opampbridge`: Do not register the opampbridge webhook if the CRD is not present (#4070)
+- `auto-instrumentation`: Fix the bug that k8s.container.name in OTEL_RESOURCE_ATTRIBUTES env is not set correctly for Go the auto-instrumentation when the pod has multiple containers. (#4089)
+- `collector`: Fix the headless service name in StatefulSet mode to ensure consistent DNS resolution. The ServiceName field in the OpenTelemetryCollector spec can be used to customize the StatefulSet's serviceName. (#4029)
+  The ServiceName field in the OpenTelemetryCollector
+  spec can be used to customize the StatefulSet's serviceName if needed, while maintaining
+  the default behavior of using the headless service name.
+- `operator`: Remove invalid `operator.observability.prometheus` feature flag references (#4159)
+  Fixed operator installation failure caused by references to the non-existent `operator.observability.prometheus` feature flag.
+  Removed the flag from the bundle and cleaned up API and documentation references.
+
+### Components
+
+* [OpenTelemetry Collector - v0.129.0](https://github.com/open-telemetry/opentelemetry-collector/releases/tag/v0.129.0)
+* [OpenTelemetry Contrib - v0.129.0](https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/tag/v0.129.0)
+* [Java auto-instrumentation - v1.33.6](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/tag/v1.33.6)
+* [.NET auto-instrumentation - v1.2.0](https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/tag/v1.2.0)
+* [Node.JS - v0.58.1](https://github.com/open-telemetry/opentelemetry-js/releases/tag/experimental%2Fv0.58.1)
+* [Python - v0.54b1](https://github.com/open-telemetry/opentelemetry-python-contrib/releases/tag/v0.54b1)
+* [Go - v0.21.0](https://github.com/open-telemetry/opentelemetry-go-instrumentation/releases/tag/v0.21.0)
+* [ApacheHTTPD - 1.0.4](https://github.com/open-telemetry/opentelemetry-cpp-contrib/releases/tag/webserver%2Fv1.0.4)
+* [Nginx - 1.0.4](https://github.com/open-telemetry/opentelemetry-cpp-contrib/releases/tag/webserver%2Fv1.0.4)
+
 ## 0.127.0
 
 ### 💡 Enhancements 💡
diff --git a/Makefile b/Makefile
index 0be50055..c1c700ee 100644
--- a/Makefile
+++ b/Makefile
@@ -153,7 +153,7 @@ BUNDLE_DIR = ./bundle/$(BUNDLE_VARIANT)
 MANIFESTS_DIR = config/manifests/$(BUNDLE_VARIANT)
 BUNDLE_BUILD_GEN_FLAGS ?= $(BUNDLE_GEN_FLAGS) --output-dir . --kustomize-dir ../../$(MANIFESTS_DIR)
 
-MIN_KUBERNETES_VERSION ?= 1.23.0
+MIN_KUBERNETES_VERSION ?= 1.25.0
 MIN_OPENSHIFT_VERSION ?= 4.12
 
 ## On MacOS, use gsed instead of sed, to make sed behavior
@@ -679,7 +679,7 @@ operator-sdk: $(LOCALBIN)
 # Generate bundle manifests and metadata, then validate generated files.
 .PHONY: generate-bundle
 generate-bundle: kustomize operator-sdk manifests set-image-controller api-docs
-	sed -e 's/minKubeVersion: .*/minKubeVersion: $(MIN_KUBERNETES_VERSION)/' config/manifests/$(BUNDLE_VARIANT)/bases/opentelemetry-operator.clusterserviceversion.yaml
+	@$(SED_INPLACE) 's/minKubeVersion: .*/minKubeVersion: $(MIN_KUBERNETES_VERSION)/' config/manifests/$(BUNDLE_VARIANT)/bases/opentelemetry-operator.clusterserviceversion.yaml
 
 	$(OPERATOR_SDK) generate kustomize manifests -q --input-dir $(MANIFESTS_DIR) --output-dir $(MANIFESTS_DIR)
 	cd $(BUNDLE_DIR) && cp ../../PROJECT . && $(KUSTOMIZE) build ../../$(MANIFESTS_DIR) | $(OPERATOR_SDK) generate bundle $(BUNDLE_BUILD_GEN_FLAGS) && rm PROJECT
diff --git a/RELEASE.md b/RELEASE.md
index cb796195..66d7e830 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -44,10 +44,10 @@ The operator should be released within a week after the [OpenTelemetry collector
 
 | Version  | Release manager |
 |----------|-----------------|
-| v0.128.0 | @yuriolisa      |  
-| v0.129.0 | @TylerHelmuth   |
-| v0.130.0 | @jaronoff97     |
-| v0.131.0 | @swiatekm       |
-| v0.132.0 | @iblancasa      |
-| v0.133.0 | @frzifus        |
-| v0.134.0 | @pavolloffay    |
+| v0.130.0 | @TylerHelmuth   |
+| v0.131.0 | @jaronoff97     |
+| v0.132.0 | @swiatekm       |
+| v0.133.0 | @iblancasa      |
+| v0.134.0 | @frzifus        |
+| v0.135.0 | @pavolloffay    |
+| v0.136.0 | @yuriolisa      |
diff --git a/autoinstrumentation/nodejs/package.json b/autoinstrumentation/nodejs/package.json
index e661dc86..9611d2af 100644
--- a/autoinstrumentation/nodejs/package.json
+++ b/autoinstrumentation/nodejs/package.json
@@ -13,6 +13,6 @@
     },
     "dependencies": {
         "@opentelemetry/api": "1.9.0",
-        "@opentelemetry/auto-instrumentations-node": "0.60.1"
+        "@opentelemetry/auto-instrumentations-node": "0.61.0"
     }
 }
diff --git a/autoinstrumentation/python/requirements.txt b/autoinstrumentation/python/requirements.txt
index 3536bb71..bd0d2770 100644
--- a/autoinstrumentation/python/requirements.txt
+++ b/autoinstrumentation/python/requirements.txt
@@ -3,7 +3,7 @@ opentelemetry-distro==0.55b1
 # We add an upper limit to urllib3 version else Python 3.8 support is dropped.
 # TODO: Update autoinstrumentation image builds to support all supported Python versions
 #       https://github.com/open-telemetry/opentelemetry-operator/issues/3712
-urllib3 < 2.3.0
+urllib3 <2.5.1
 # We don't use the distro[otlp] option which automatically includes exporters since gRPC is not appropriate for
 # injected auto-instrumentation, where it has a strict dependency on the OS / Python version the artifact is built for.
 opentelemetry-exporter-otlp-proto-http==1.34.1
diff --git a/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
index af279ca8..fec2635c 100644
--- a/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
+++ b/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
@@ -99,13 +99,13 @@ metadata:
     categories: Logging & Tracing,Monitoring
     certified: "false"
     containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
-    createdAt: "2025-06-23T18:50:20Z"
+    createdAt: "2025-07-05T13:19:47Z"
     description: Provides the OpenTelemetry components, including the Collector
     operators.operatorframework.io/builder: operator-sdk-v1.29.0
     operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
     repository: github.com/open-telemetry/opentelemetry-operator
     support: OpenTelemetry Community
-  name: opentelemetry-operator.v0.127.0
+  name: opentelemetry-operator.v0.129.1
   namespace: placeholder
 spec:
   apiservicedefinitions: {}
@@ -518,7 +518,7 @@ spec:
                   valueFrom:
                     fieldRef:
                       fieldPath: spec.serviceAccountName
-                image: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.127.0
+                image: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.129.1
                 livenessProbe:
                   httpGet:
                     path: /healthz
@@ -623,10 +623,10 @@ spec:
   - email: jpkroehling@redhat.com
     name: Juraci Paixão Kröhling
   maturity: alpha
-  minKubeVersion: 1.23.0
+  minKubeVersion: 1.25.0
   provider:
     name: OpenTelemetry Community
-  version: 0.127.0
+  version: 0.129.1
   webhookdefinitions:
   - admissionReviewVersions:
     - v1alpha1
diff --git a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
index c150917e..5cc60031 100644
--- a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
+++ b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
@@ -99,13 +99,13 @@ metadata:
     categories: Logging & Tracing,Monitoring
     certified: "false"
     containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
-    createdAt: "2025-06-23T18:50:22Z"
+    createdAt: "2025-07-05T13:19:48Z"
     description: Provides the OpenTelemetry components, including the Collector
     operators.operatorframework.io/builder: operator-sdk-v1.29.0
     operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
     repository: github.com/open-telemetry/opentelemetry-operator
     support: OpenTelemetry Community
-  name: opentelemetry-operator.v0.127.0
+  name: opentelemetry-operator.v0.129.1
   namespace: placeholder
 spec:
   apiservicedefinitions: {}
@@ -522,7 +522,7 @@ spec:
                   valueFrom:
                     fieldRef:
                       fieldPath: spec.serviceAccountName
-                image: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.127.0
+                image: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator:0.129.1
                 livenessProbe:
                   httpGet:
                     path: /healthz
@@ -638,10 +638,10 @@ spec:
   - email: jpkroehling@redhat.com
     name: Juraci Paixão Kröhling
   maturity: alpha
-  minKubeVersion: 1.23.0
+  minKubeVersion: 1.25.0
   provider:
     name: OpenTelemetry Community
-  version: 0.127.0
+  version: 0.129.1
   webhookdefinitions:
   - admissionReviewVersions:
     - v1alpha1
diff --git a/cmd/otel-allocator/internal/collector/collector.go b/cmd/otel-allocator/internal/collector/collector.go
index 787dd209..79453477 100644
--- a/cmd/otel-allocator/internal/collector/collector.go
+++ b/cmd/otel-allocator/internal/collector/collector.go
@@ -14,7 +14,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/client-go/informers"
 	"k8s.io/client-go/kubernetes"
-	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/cache"
 
 	"github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/internal/allocation"
@@ -33,12 +32,7 @@ type Watcher struct {
 	collectorsDiscovered         metric.Int64Gauge
 }
 
-func NewCollectorWatcher(logger logr.Logger, kubeConfig *rest.Config, collectorNotReadyGracePeriod time.Duration) (*Watcher, error) {
-	clientset, err := kubernetes.NewForConfig(kubeConfig)
-	if err != nil {
-		return &Watcher{}, err
-	}
-
+func NewCollectorWatcher(logger logr.Logger, client kubernetes.Interface, collectorNotReadyGracePeriod time.Duration) (*Watcher, error) {
 	meter := otel.GetMeterProvider().Meter("targetallocator")
 	collectorsDiscovered, err := meter.Int64Gauge("opentelemetry_allocator_collectors_discovered", metric.WithDescription("Number of collectors discovered."))
 	if err != nil {
@@ -46,7 +40,7 @@ func NewCollectorWatcher(logger logr.Logger, kubeConfig *rest.Config, collectorN
 	}
 	return &Watcher{
 		log:                          logger.WithValues("component", "opentelemetry-targetallocator"),
-		k8sClient:                    clientset,
+		k8sClient:                    client,
 		close:                        make(chan struct{}),
 		minUpdateInterval:            defaultMinUpdateInterval,
 		collectorNotReadyGracePeriod: collectorNotReadyGracePeriod,
@@ -69,7 +63,7 @@ func (k *Watcher) Watch(
 	}
 	informerFactory := informers.NewSharedInformerFactoryWithOptions(
 		k.k8sClient,
-		time.Second*30,
+		2*k.minUpdateInterval,
 		informers.WithNamespace(collectorNamespace),
 		informers.WithTweakListOptions(listOptionsFunc))
 	informer := informerFactory.Core().V1().Pods().Informer()
diff --git a/cmd/otel-allocator/internal/watcher/promOperator.go b/cmd/otel-allocator/internal/watcher/promOperator.go
index 4ea16f7b..abf9e283 100644
--- a/cmd/otel-allocator/internal/watcher/promOperator.go
+++ b/cmd/otel-allocator/internal/watcher/promOperator.go
@@ -39,23 +39,20 @@ const (
 	minEventInterval = time.Second * 5
 )
 
-func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocatorconfig.Config) (*PrometheusCRWatcher, error) {
+func NewPrometheusCRWatcher(
+	ctx context.Context,
+	logger logr.Logger,
+	client kubernetes.Interface,
+	monitoringclient monitoringclient.Interface,
+	cfg allocatorconfig.Config,
+) (*PrometheusCRWatcher, error) {
 	promLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelWarn}))
 	slogger := slog.New(logr.ToSlogHandler(logger))
 	var resourceSelector *prometheus.ResourceSelector
-	mClient, err := monitoringclient.NewForConfig(cfg.ClusterConfig)
-	if err != nil {
-		return nil, err
-	}
-
-	clientset, err := kubernetes.NewForConfig(cfg.ClusterConfig)
-	if err != nil {
-		return nil, err
-	}
 
 	allowList, denyList := cfg.PrometheusCR.GetAllowDenyLists()
 
-	factory := informers.NewMonitoringInformerFactories(allowList, denyList, mClient, allocatorconfig.DefaultResyncTime, nil)
+	factory := informers.NewMonitoringInformerFactories(allowList, denyList, monitoringclient, allocatorconfig.DefaultResyncTime, nil)
 
 	monitoringInformers, err := getInformers(factory)
 	if err != nil {
@@ -89,17 +86,17 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
 		},
 	}
 
-	generator, err := prometheus.NewConfigGenerator(promLogger, prom, prometheus.WithEndpointSliceSupport())
+	generator, err := prometheus.NewConfigGenerator(promLogger, prom, prometheus.WithEndpointSliceSupport(), prometheus.WithInlineTLSConfig())
 
 	if err != nil {
 		return nil, err
 	}
 
-	store := assets.NewStoreBuilder(clientset.CoreV1(), clientset.CoreV1())
+	store := assets.NewStoreBuilder(client.CoreV1(), client.CoreV1())
 	promRegisterer := prometheusgoclient.NewRegistry()
 	operatorMetrics := operator.NewMetrics(promRegisterer)
 	eventRecorderFactory := operator.NewEventRecorderFactory(false)
-	eventRecorder := eventRecorderFactory(clientset, "target-allocator")
+	eventRecorder := eventRecorderFactory(client, "target-allocator")
 
 	var nsMonInf cache.SharedIndexInformer
 	getNamespaceInformerErr := retry.OnError(retry.DefaultRetry,
@@ -107,7 +104,7 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
 			logger.Error(err, "Retrying namespace informer creation in promOperator CRD watcher")
 			return true
 		}, func() error {
-			nsMonInf, err = getNamespaceInformer(ctx, allowList, denyList, promLogger, clientset, operatorMetrics)
+			nsMonInf, err = getNamespaceInformer(ctx, allowList, denyList, promLogger, client, operatorMetrics)
 			return err
 		})
 	if getNamespaceInformerErr != nil {
@@ -122,8 +119,8 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
 
 	return &PrometheusCRWatcher{
 		logger:                          slogger,
-		kubeMonitoringClient:            mClient,
-		k8sClient:                       clientset,
+		kubeMonitoringClient:            monitoringclient,
+		k8sClient:                       client,
 		informers:                       monitoringInformers,
 		nsInformer:                      nsMonInf,
 		stopChannel:                     make(chan struct{}),
diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go
index c6ec692c..bbef6ec7 100644
--- a/cmd/otel-allocator/main.go
+++ b/cmd/otel-allocator/main.go
@@ -11,6 +11,7 @@ import (
 	"syscall"
 
 	"github.com/oklog/run"
+	monitoringclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/prometheus/discovery"
 	"go.opentelemetry.io/otel"
@@ -18,6 +19,7 @@ import (
 	otelprom "go.opentelemetry.io/otel/exporters/prometheus"
 	"go.opentelemetry.io/otel/metric"
 	sdkmetric "go.opentelemetry.io/otel/sdk/metric"
+	"k8s.io/client-go/kubernetes"
 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
 	ctrl "sigs.k8s.io/controller-runtime"
 
@@ -67,6 +69,17 @@ func main() {
 	ctx := context.Background()
 	log := ctrl.Log.WithName("allocator")
 
+	k8sClient, err := kubernetes.NewForConfig(cfg.ClusterConfig)
+	if err != nil {
+		setupLog.Error(err, "Unable to initialize kubernetes client")
+		os.Exit(1)
+	}
+	monitoringClient, err := monitoringclient.NewForConfig(cfg.ClusterConfig)
+	if err != nil {
+		setupLog.Error(err, "Unable to initialize monitoring client")
+		os.Exit(1)
+	}
+
 	metricExporter, promErr := otelprom.New()
 	if promErr != nil {
 		panic(promErr)
@@ -107,7 +120,7 @@ func main() {
 	if targetErr != nil {
 		panic(targetErr)
 	}
-	collectorWatcher, collectorWatcherErr := collector.NewCollectorWatcher(log, cfg.ClusterConfig, cfg.CollectorNotReadyGracePeriod)
+	collectorWatcher, collectorWatcherErr := collector.NewCollectorWatcher(log, k8sClient, cfg.CollectorNotReadyGracePeriod)
 	if collectorWatcherErr != nil {
 		setupLog.Error(collectorWatcherErr, "Unable to initialize collector watcher")
 		os.Exit(1)
@@ -116,7 +129,8 @@ func main() {
 	defer close(interrupts)
 
 	if cfg.PrometheusCR.Enabled {
-		promWatcher, allocErr := allocatorWatcher.NewPrometheusCRWatcher(ctx, setupLog.WithName("prometheus-cr-watcher"), *cfg)
+		promWatcher, allocErr := allocatorWatcher.NewPrometheusCRWatcher(
+			ctx, setupLog.WithName("prometheus-cr-watcher"), k8sClient, monitoringClient, *cfg)
 		if allocErr != nil {
 			setupLog.Error(allocErr, "Can't start the prometheus watcher")
 			os.Exit(1)
@@ -160,8 +174,8 @@ func main() {
 		func() error {
 			// Initial loading of the config file's scrape config
 			if cfg.PromConfig != nil && len(cfg.PromConfig.ScrapeConfigs) > 0 {
-				err := targetDiscoverer.ApplyConfig(allocatorWatcher.EventSourceConfigMap, cfg.PromConfig.ScrapeConfigs)
-				if err != nil {
+				applyErr := targetDiscoverer.ApplyConfig(allocatorWatcher.EventSourceConfigMap, cfg.PromConfig.ScrapeConfigs)
+				if applyErr != nil {
 					setupLog.Error(err, "Unable to apply initial configuration")
 					return err
 				}
@@ -169,9 +183,9 @@ func main() {
 				setupLog.Info("Prometheus config empty, skipping initial discovery configuration")
 			}
 
-			err := targetDiscoverer.Run()
+			tErr := targetDiscoverer.Run()
 			setupLog.Info("Target discoverer exited")
-			return err
+			return tErr
 		},
 		func(_ error) {
 			setupLog.Info("Closing target discoverer")
@@ -179,9 +193,9 @@ func main() {
 		})
 	runGroup.Add(
 		func() error {
-			err := collectorWatcher.Watch(cfg.CollectorNamespace, cfg.CollectorSelector, allocator.SetCollectors)
+			watchErr := collectorWatcher.Watch(cfg.CollectorNamespace, cfg.CollectorSelector, allocator.SetCollectors)
 			setupLog.Info("Collector watcher exited")
-			return err
+			return watchErr
 		},
 		func(_ error) {
 			setupLog.Info("Closing collector watcher")
@@ -189,9 +203,9 @@ func main() {
 		})
 	runGroup.Add(
 		func() error {
-			err := srv.Start()
+			startErr := srv.Start()
 			setupLog.Info("Server failed to start")
-			return err
+			return startErr
 		},
 		func(_ error) {
 			setupLog.Info("Closing server")
@@ -202,9 +216,9 @@ func main() {
 	if cfg.HTTPS.Enabled {
 		runGroup.Add(
 			func() error {
-				err := srv.StartHTTPS()
+				startErr := srv.StartHTTPS()
 				setupLog.Info("HTTPS Server failed to start")
-				return err
+				return startErr
 			},
 			func(_ error) {
 				setupLog.Info("Closing HTTPS server")
diff --git a/config/manifests/community/bases/opentelemetry-operator.clusterserviceversion.yaml b/config/manifests/community/bases/opentelemetry-operator.clusterserviceversion.yaml
index 0356c4f5..d44009e5 100644
--- a/config/manifests/community/bases/opentelemetry-operator.clusterserviceversion.yaml
+++ b/config/manifests/community/bases/opentelemetry-operator.clusterserviceversion.yaml
@@ -227,7 +227,7 @@ spec:
   - email: jpkroehling@redhat.com
     name: Juraci Paixão Kröhling
   maturity: alpha
-  minKubeVersion: 1.23.0
+  minKubeVersion: 1.25.0
   provider:
     name: OpenTelemetry Community
   version: 0.0.0
diff --git a/config/manifests/openshift/bases/opentelemetry-operator.clusterserviceversion.yaml b/config/manifests/openshift/bases/opentelemetry-operator.clusterserviceversion.yaml
index 0356c4f5..d44009e5 100644
--- a/config/manifests/openshift/bases/opentelemetry-operator.clusterserviceversion.yaml
+++ b/config/manifests/openshift/bases/opentelemetry-operator.clusterserviceversion.yaml
@@ -227,7 +227,7 @@ spec:
   - email: jpkroehling@redhat.com
     name: Juraci Paixão Kröhling
   maturity: alpha
-  minKubeVersion: 1.23.0
+  minKubeVersion: 1.25.0
   provider:
     name: OpenTelemetry Community
   version: 0.0.0
diff --git a/docs/compatibility.md b/docs/compatibility.md
index aa83c7aa..1a241980 100644
--- a/docs/compatibility.md
+++ b/docs/compatibility.md
@@ -46,6 +46,7 @@ The OpenTelemetry Operator _might_ work on versions outside of the given range,
 
 | OpenTelemetry Operator | Kubernetes     | Cert-Manager | Prometheus-Operator |
 |------------------------|----------------|--------------|---------------------|
+| v0.129.1               | v1.23 to v1.33 | v1           | v0.81.0             |
 | v0.127.0               | v1.23 to v1.32 | v1           | v0.81.0             |
 | v0.126.0               | v1.23 to v1.32 | v1           | v0.80.1             |
 | v0.125.0               | v1.23 to v1.32 | v1           | v0.80.1             |
@@ -70,7 +71,6 @@ The OpenTelemetry Operator _might_ work on versions outside of the given range,
 | v0.106.0               | v1.23 to v1.30 | v1           | v0.75.0             |
 | v0.105.0               | v1.23 to v1.30 | v1           | v0.74.0             |
 | v0.104.0               | v1.23 to v1.30 | v1           | v0.74.0             |
-| v0.103.0               | v1.23 to v1.30 | v1           | v0.74.0             |
 
 [kubernetes_releases]: https://kubernetes.io/releases/
 [openshift_support]: https://access.redhat.com/support/policy/updates/openshift
diff --git a/go.mod b/go.mod
index 62da0433..11774991 100644
--- a/go.mod
+++ b/go.mod
@@ -34,7 +34,7 @@ require (
 	github.com/shirou/gopsutil v3.21.11+incompatible
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
-	go.opentelemetry.io/collector/featuregate v1.34.0
+	go.opentelemetry.io/collector/featuregate v1.35.0
 	go.opentelemetry.io/otel v1.37.0
 	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0
 	go.opentelemetry.io/otel/exporters/prometheus v0.59.0
@@ -77,7 +77,7 @@ require (
 	github.com/bytedance/sonic v1.11.6 // indirect
 	github.com/bytedance/sonic/loader v0.1.1 // indirect
 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect
-	github.com/cert-manager/cert-manager v1.18.1
+	github.com/cert-manager/cert-manager v1.18.2
 	github.com/cloudwego/base64x v0.1.4 // indirect
 	github.com/cloudwego/iasm v0.2.0 // indirect
 	github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect
@@ -199,7 +199,7 @@ require (
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0
 	go.opentelemetry.io/otel/trace v1.37.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.7.0 // indirect
-	go.uber.org/atomic v1.11.0 // indirect
+	go.uber.org/atomic v1.11.0
 	golang.org/x/arch v0.8.0 // indirect
 	golang.org/x/crypto v0.39.0 // indirect
 	golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
diff --git a/go.sum b/go.sum
index fcc5f7d9..1765df37 100644
--- a/go.sum
+++ b/go.sum
@@ -71,8 +71,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8=
 github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
-github.com/cert-manager/cert-manager v1.18.1 h1:5qa3UNrgkNc5Zpn0CyAVMyRIchfF3/RHji4JrazYmWw=
-github.com/cert-manager/cert-manager v1.18.1/go.mod h1:icDJx4kG9BCNpGjBvrmsFd99d+lXUvWdkkcrSSQdIiw=
+github.com/cert-manager/cert-manager v1.18.2 h1:H2P75ycGcTMauV3gvpkDqLdS3RSXonWF2S49QGA1PZE=
+github.com/cert-manager/cert-manager v1.18.2/go.mod h1:icDJx4kG9BCNpGjBvrmsFd99d+lXUvWdkkcrSSQdIiw=
 github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -537,8 +537,8 @@ go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793Sqyh
 go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/collector/featuregate v1.34.0 h1:zqDHpEYy1UeudrfUCvlcJL2t13dXywrC6lwpNZ5DrCU=
-go.opentelemetry.io/collector/featuregate v1.34.0/go.mod h1:Y/KsHbvREENKvvN9RlpiWk/IGBK+CATBYzIIpU7nccc=
+go.opentelemetry.io/collector/featuregate v1.35.0 h1:c/XRtA35odgxVc4VgOF/PTIk7ajw1wYdQ6QI562gzd4=
+go.opentelemetry.io/collector/featuregate v1.35.0/go.mod h1:Y/KsHbvREENKvvN9RlpiWk/IGBK+CATBYzIIpU7nccc=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
 go.opentelemetry.io/contrib/otelconf v0.16.0 h1:mTYGRlZtpc/zDaTaUQSnsZ1hyoRONaS4Od/Ny5++lhE=
diff --git a/kind-1.23.yaml b/kind-1.23.yaml
deleted file mode 100644
index cbbdccb8..00000000
--- a/kind-1.23.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-kind: Cluster
-apiVersion: kind.x-k8s.io/v1alpha4
-networking:
-  ipFamily: dual
-nodes:
-  - role: control-plane
-    image: kindest/node:v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3
-    kubeadmConfigPatches:
-      - |
-        kind: InitConfiguration
-        nodeRegistration:
-          kubeletExtraArgs:
-            node-labels: "ingress-ready=true"
-    extraPortMappings:
-      - containerPort: 80
-        hostPort: 80
-        protocol: TCP
-      - containerPort: 443
-        hostPort: 443
-        protocol: TCP
\ No newline at end of file
diff --git a/kind-1.24.yaml b/kind-1.24.yaml
deleted file mode 100644
index 0bd5672b..00000000
--- a/kind-1.24.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-kind: Cluster
-apiVersion: kind.x-k8s.io/v1alpha4
-networking:
-  ipFamily: dual
-nodes:
-  - role: control-plane
-    image: kindest/node:v1.24.15@sha256:7db4f8bea3e14b82d12e044e25e34bd53754b7f2b0e9d56df21774e6f66a70ab
-    kubeadmConfigPatches:
-      - |
-        kind: InitConfiguration
-        nodeRegistration:
-          kubeletExtraArgs:
-            node-labels: "ingress-ready=true"
-    extraPortMappings:
-      - containerPort: 80
-        hostPort: 80
-        protocol: TCP
-      - containerPort: 443
-        hostPort: 443
-        protocol: TCP
diff --git a/versions.txt b/versions.txt
index 2149f54e..873d514d 100644
--- a/versions.txt
+++ b/versions.txt
@@ -2,16 +2,16 @@
 # by default with the OpenTelemetry Operator. This would usually be the latest
 # stable OpenTelemetry version. When you update this file, make sure to update the
 # the docs as well.
-opentelemetry-collector=0.127.0
+opentelemetry-collector=0.129.1
 
 # Represents the current release of the OpenTelemetry Operator.
-operator=0.127.0
+operator=0.129.1
 
 # Represents the current release of the Target Allocator.
-targetallocator=0.127.0
+targetallocator=0.129.1
 
 # Represents the current release of the Operator OpAMP Bridge.
-operator-opamp-bridge=0.127.0
+operator-opamp-bridge=0.129.1
 
 # Represents the current release of Java instrumentation.
 # Should match autoinstrumentation/java/version.txt



Test patch:
diff --git a/cmd/otel-allocator/internal/collector/collector_test.go b/cmd/otel-allocator/internal/collector/collector_test.go
index 9442084b..df4e8cdb 100644
--- a/cmd/otel-allocator/internal/collector/collector_test.go
+++ b/cmd/otel-allocator/internal/collector/collector_test.go
@@ -42,7 +42,7 @@ func (r *reportingGauge) Record(_ context.Context, value int64, _ ...metric.Reco
 
 func getTestPodWatcher(collectorNotReadyGracePeriod time.Duration) Watcher {
 	podWatcher := Watcher{
-		k8sClient:                    fake.NewSimpleClientset(),
+		k8sClient:                    fake.NewClientset(),
 		close:                        make(chan struct{}),
 		log:                          logger,
 		minUpdateInterval:            time.Millisecond,
diff --git a/cmd/otel-allocator/internal/watcher/promOperator_test.go b/cmd/otel-allocator/internal/watcher/promOperator_test.go
index d284d240..7ce879cb 100644
--- a/cmd/otel-allocator/internal/watcher/promOperator_test.go
+++ b/cmd/otel-allocator/internal/watcher/promOperator_test.go
@@ -1251,7 +1251,7 @@ func getTestPrometheusCRWatcher(
 
 	promOperatorLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelWarn}))
 
-	generator, err := prometheus.NewConfigGenerator(promOperatorLogger, prom, prometheus.WithEndpointSliceSupport())
+	generator, err := prometheus.NewConfigGenerator(promOperatorLogger, prom, prometheus.WithEndpointSliceSupport(), prometheus.WithInlineTLSConfig())
 	if err != nil {
 		t.Fatal(t, err)
 	}
diff --git a/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-assert.yaml b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-assert.yaml
new file mode 100644
index 00000000..81bed598
--- /dev/null
+++ b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-assert.yaml
@@ -0,0 +1,16 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: prometheus-cr-v1beta1-targetallocator
+status:
+  observedGeneration: 1
+  readyReplicas: 1
+  replicas: 1
+---
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: prometheus-cr-v1beta1-collector
+status:
+  readyReplicas: 1
+  replicas: 1
diff --git a/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-install.yaml b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-install.yaml
new file mode 100644
index 00000000..72f6ae7e
--- /dev/null
+++ b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/00-install.yaml
@@ -0,0 +1,208 @@
+apiVersion: v1
+automountServiceAccountToken: true
+kind: ServiceAccount
+metadata:
+  name: ta
+---
+apiVersion: v1
+automountServiceAccountToken: true
+kind: ServiceAccount
+metadata:
+  name: collector
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: collector
+  annotations:
+    kubernetes.io/service-account.name: collector
+type: kubernetes.io/service-account-token
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: (join('-', ['ta', $namespace]))
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - pods
+  - nodes
+  - services
+  - endpoints
+  - configmaps
+  - secrets
+  - namespaces
+  verbs:
+  - get
+  - watch
+  - list
+- apiGroups:
+  - apps
+  resources:
+  - statefulsets
+  - services
+  - endpoints
+  verbs:
+  - get
+  - watch
+  - list
+- apiGroups:
+  - discovery.k8s.io
+  resources:
+  - endpointslices
+  verbs:
+  - get
+  - watch
+  - list
+- apiGroups:
+  - networking.k8s.io
+  resources:
+  - ingresses
+  verbs:
+  - get
+  - watch
+  - list
+- apiGroups:
+  - monitoring.coreos.com
+  resources:
+  - servicemonitors
+  - podmonitors
+  - scrapeconfigs
+  - probes
+  verbs:
+  - get
+  - watch
+  - list
+- nonResourceURLs:
+  - /metrics
+  verbs:
+  - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: (join('-', ['collector', $namespace]))
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - pods
+  - nodes
+  - nodes/proxy
+  - nodes/metrics
+  - services
+  - endpoints
+  - namespaces
+  verbs:
+  - get
+  - watch
+  - list
+- apiGroups:
+  - networking.k8s.io
+  resources:
+  - ingresses
+  verbs:
+  - get
+  - watch
+  - list
+- nonResourceURLs:
+  - /metrics
+  - /metrics/cadvisor
+  verbs:
+  - get
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name:  (join('-', ['opentelemetry-operator-controller-manager-cert-manager-role', $namespace]))
+rules:
+- apiGroups:
+  - cert-manager.io
+  resources:
+  - issuers
+  - certificaterequests
+  - certificates
+  verbs:
+  - create
+  - get
+  - list
+  - watch
+  - update
+  - patch
+  - delete
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: (join('-', ['opentelemetry-operator-controller-manager-cert-manager-role', $namespace]))
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: (join('-', ['opentelemetry-operator-controller-manager-cert-manager-role', $namespace]))
+subjects:
+- kind: ServiceAccount
+  name: opentelemetry-operator-controller-manager
+  namespace: opentelemetry-operator-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: (join('-', ['ta', $namespace]))
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: (join('-', ['ta', $namespace]))
+subjects:
+- kind: ServiceAccount
+  name: ta
+  namespace: ($namespace)
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: (join('-', ['collector', $namespace]))
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: (join('-', ['collector', $namespace]))
+subjects:
+- kind: ServiceAccount
+  name: collector
+  namespace: ($namespace)
+---
+apiVersion: opentelemetry.io/v1beta1
+kind: OpenTelemetryCollector
+metadata:
+  name: prometheus-cr-v1beta1
+spec:
+  config:
+    receivers:
+      prometheus:
+        config:
+          scrape_configs: []
+
+    processors:
+
+    exporters:
+      prometheus:
+        endpoint: 0.0.0.0:9090
+    service:
+      pipelines:
+        metrics:
+          receivers: [prometheus]
+          exporters: [prometheus]
+      telemetry:
+        logs:
+          level: "DEBUG"
+          development: true
+          encoding: "json"
+  mode: statefulset
+  serviceAccount: collector
+  targetAllocator:
+    enabled: true
+    prometheusCR:
+      enabled: true
+      scrapeInterval: 1s
+      scrapeConfigSelector: {}
+    serviceAccount: ta
diff --git a/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-assert.yaml b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-assert.yaml
new file mode 100644
index 00000000..43042eb8
--- /dev/null
+++ b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-assert.yaml
@@ -0,0 +1,13 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: check-ta-scrape-config-v1beta1
+status:
+  succeeded: 1
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: check-ta-jobs-scrape-configs-v1beta1
+status:
+  succeeded: 1
diff --git a/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-install.yaml b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-install.yaml
new file mode 100644
index 00000000..ec24f4f0
--- /dev/null
+++ b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/01-install.yaml
@@ -0,0 +1,37 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: check-ta-scrape-config-v1beta1
+spec:
+  template:
+    metadata:
+      labels:
+        checker: "true"
+    spec:
+      restartPolicy: OnFailure
+      containers:
+        - name: check-metrics
+          image: curlimages/curl
+          args:
+            - /bin/sh
+            - -c
+            - curl -s http://prometheus-cr-v1beta1-targetallocator/scrape_configs | grep "scrape-config-cr"
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: check-ta-jobs-scrape-configs-v1beta1
+spec:
+  template:
+    metadata:
+      labels:
+        checker: "true"
+    spec:
+      restartPolicy: OnFailure
+      containers:
+        - name: check-metrics
+          image: curlimages/curl
+          args:
+            - /bin/sh
+            - -c
+            - curl -s http://prometheus-cr-v1beta1-targetallocator/jobs | grep "scrape-config-cr"
diff --git a/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/chainsaw-test.yaml b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/chainsaw-test.yaml
new file mode 100755
index 00000000..e7028fa8
--- /dev/null
+++ b/tests/e2e-ta-collector-mtls/ta-collector-mtls-scrapeconfig-node/chainsaw-test.yaml
@@ -0,0 +1,90 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+  name: ta-collector-mtls-scrapeconfig-node
+spec:
+  steps:
+  - name: step-00
+    try:
+    - apply:
+        file: 00-install.yaml
+    - assert:
+        file: 00-assert.yaml
+    catch:
+    - podLogs:
+        selector: app.kubernetes.io/managed-by=opentelemetry-operator
+    - podLogs:
+        selector: checker=true
+  - name: step-01
+    try:
+      - create:
+          template: false
+          resource:
+            apiVersion: monitoring.coreos.com/v1alpha1
+            kind: ScrapeConfig
+            metadata:
+              name: scrape-config-cr
+            spec:
+              kubernetesSDConfigs:
+                - role: Node
+              relabelings:
+                - action: labelmap
+                  regex: __meta_kubernetes_node_label_(.+)
+                  replacement: $1
+                  separator: ;
+                - action: replace
+                  regex: (.*)
+                  replacement: kubernetes.default.svc:443
+                  separator: ;
+                  targetLabel: __address__
+                - action: replace
+                  regex: (.+)
+                  replacement: /api/v1/nodes/$1/proxy/metrics
+                  separator: ;
+                  sourceLabels:
+                    - __meta_kubernetes_node_name
+                  targetLabel: __metrics_path__
+              scheme: HTTPS
+              authorization:
+                type: Bearer
+                credentials:
+                  key: "token"
+                  name: "collector"
+              tlsConfig:
+                ca:
+                  secret:
+                    key: "ca.crt"
+                    name: "collector"
+                insecureSkipVerify: false
+      - apply:
+          template: true
+          bindings:
+            - name: namespace
+              value: ($namespace)
+          file: 01-install.yaml
+      - assert:
+          file: 01-assert.yaml
+      - script:
+          timeout: 1m
+          content: |
+            #!/bin/bash
+            # Wait for the scrape config to be used by the collector to scrape nodes. It can take 30s for the collector to start scraping nodes.
+            while ! kubectl get --raw /api/v1/namespaces/${NAMESPACE}/pods/prometheus-cr-v1beta1-collector-0:9090/proxy/metrics | grep up{ | grep "job=\"scrapeConfig/${NAMESPACE}/scrape-config-cr\""; do
+              sleep 1
+            done
+          outputs:
+            - name: metrics
+              value: ($stdout)
+          check:
+            ($error == null): true
+      - assert:
+          timeout: 1s
+          resource:
+            ((x_metrics_decode($metrics))):
+              ([?as_string(metric.__name__) == 'up' && as_string(metric.job) == join('/', ['scrapeConfig', $namespace, 'scrape-config-cr'])].value): [ 1 ]
+    catch:
+      - podLogs:
+          selector: app.kubernetes.io/managed-by=opentelemetry-operator
+      - podLogs:
+          selector: checker=true
diff --git a/tests/e2e-targetallocator/targetallocator-metrics/chainsaw-test.yaml b/tests/e2e-targetallocator/targetallocator-metrics/chainsaw-test.yaml
index 1a9880ce..92632631 100644
--- a/tests/e2e-targetallocator/targetallocator-metrics/chainsaw-test.yaml
+++ b/tests/e2e-targetallocator/targetallocator-metrics/chainsaw-test.yaml
@@ -10,17 +10,15 @@ spec:
             file: 00-install.yaml
     - name: Wait for OpenTelemetryCollector and Target Allocator pods to be ready
       try:
-        - sleep:
-            duration: 10s 
         - wait:
-            apiVersion: v1
-            kind: Pod
+            apiVersion: opentelemetry.io/v1beta1
+            kind: OpenTelemetryCollector
             namespace: ($namespace)
             timeout: 1m
             for:
-              condition:
-                name: ready
-                value: 'true'
+              jsonPath:
+                path: '{.status.scale.statusReplicas}'
+                value: '1/1'
         - assert:
             file: 00-assert.yaml
     - name: Assert Collector metrics
@@ -77,7 +75,9 @@ spec:
                 value: ($podName)
             content: |
               #!/bin/bash
-              kubectl get --raw /api/v1/namespaces/${NAMESPACE}/pods/${podName}:9090/proxy/metrics
+              while ! kubectl get --raw /api/v1/namespaces/${NAMESPACE}/pods/${podName}:9090/proxy/metrics; do
+                sleep 1
+              done
             outputs:
               - name: metrics
                 value: (x_metrics_decode($stdout))
diff --git a/tests/e2e/prometheus-config-validation/00-promreceiver-allocatorconfig.yaml b/tests/e2e/prometheus-config-validation/00-promreceiver-allocatorconfig.yaml
index 4b6093c7..9e8dfccc 100644
--- a/tests/e2e/prometheus-config-validation/00-promreceiver-allocatorconfig.yaml
+++ b/tests/e2e/prometheus-config-validation/00-promreceiver-allocatorconfig.yaml
@@ -32,12 +32,12 @@ subjects:
   name: ta
   namespace: ($namespace)
 ---
-apiVersion: opentelemetry.io/v1alpha1
+apiVersion: opentelemetry.io/v1beta1
 kind: OpenTelemetryCollector
 metadata:
   name: promreceiver-allocatorconfig
 spec:
-  config: |
+  config:
     receivers:
       jaeger:
           protocols:
@@ -56,8 +56,6 @@ spec:
           interval: 30s
           collector_id: ${POD_NAME}
 
-    processors:
-
     exporters:
       debug:
     extensions:
@@ -66,7 +64,12 @@ spec:
     service:
       telemetry:
         metrics:
-          address: :8888
+          readers:
+            - pull:
+                exporter:
+                  prometheus:
+                    host: 0.0.0.0
+                    port: 8888
       extensions:
         - health_check
       pipelines:
diff --git a/tests/e2e/prometheus-config-validation/02-promreceiver-allocatorconfig-extra.yaml b/tests/e2e/prometheus-config-validation/02-promreceiver-allocatorconfig-extra.yaml
index 457a9aae..5e119a40 100644
--- a/tests/e2e/prometheus-config-validation/02-promreceiver-allocatorconfig-extra.yaml
+++ b/tests/e2e/prometheus-config-validation/02-promreceiver-allocatorconfig-extra.yaml
@@ -1,5 +1,5 @@
 ---
-apiVersion: opentelemetry.io/v1alpha1
+apiVersion: opentelemetry.io/v1beta1
 kind: OpenTelemetryCollector
 metadata:
   name: promreceiver-allocatorconfig-extra
@@ -11,7 +11,7 @@ spec:
     prometheusCR:
       enabled: true
 
-  config: |
+  config:
     receivers:
       jaeger:
           protocols:
@@ -32,8 +32,6 @@ spec:
           http_sd_config:
             refresh_interval: 10s
 
-    processors:
-
     exporters:
       debug:
     extensions:
@@ -42,7 +40,12 @@ spec:
     service:
       telemetry:
         metrics:
-          address: :8888
+          readers:
+            - pull:
+                exporter:
+                  prometheus:
+                    host: 0.0.0.0
+                    port: 8888
       extensions:
         - health_check
       pipelines:
diff --git a/tests/e2e/prometheus-config-validation/03-promreceiver-nopromconfig.yaml b/tests/e2e/prometheus-config-validation/03-promreceiver-nopromconfig.yaml
index fc8b465d..23184bed 100644
--- a/tests/e2e/prometheus-config-validation/03-promreceiver-nopromconfig.yaml
+++ b/tests/e2e/prometheus-config-validation/03-promreceiver-nopromconfig.yaml
@@ -1,5 +1,5 @@
 ---
-apiVersion: opentelemetry.io/v1alpha1
+apiVersion: opentelemetry.io/v1beta1
 kind: OpenTelemetryCollector
 metadata:
   name: promreceiver-nopromconfig
@@ -11,7 +11,7 @@ spec:
     prometheusCR:
       enabled: true
 
-  config: |
+  config:
     receivers:
       jaeger:
           protocols:
@@ -27,8 +27,6 @@ spec:
           http_sd_config:
             refresh_interval: 10s
 
-    processors:
-
     exporters:
       debug:
     extensions:
@@ -37,7 +35,12 @@ spec:
     service:
       telemetry:
         metrics:
-          address: :8888
+          readers:
+            - pull:
+                exporter:
+                  prometheus:
+                    host: 0.0.0.0
+                    port: 8888
       extensions:
         - health_check
       pipelines:
diff --git a/tests/test-e2e-apps/python/Dockerfile b/tests/test-e2e-apps/python/Dockerfile
index 20e72e85..ec783b2f 100644
--- a/tests/test-e2e-apps/python/Dockerfile
+++ b/tests/test-e2e-apps/python/Dockerfile
@@ -1,4 +1,6 @@
-FROM python:alpine3.18
+ARG python_version=3.13
+
+FROM python:${python_version}-alpine3.22
 
 WORKDIR /app