소스 검색

Merge branch 'main' into mj-design-oopp

Moritz Johner 3 달 전
부모
커밋
bafc2a4926
100개의 변경된 파일3229개의 추가작업 그리고 1176개의 파일을 삭제
  1. 2 3
      .github/actions/e2e/action.yml
  2. 126 25
      .github/actions/sign/action.yml
  3. 23 47
      .github/workflows/ci.yml
  4. 4 4
      .github/workflows/codeql.yml
  5. 2 2
      .github/workflows/crds.yml
  6. 3 3
      .github/workflows/dependabot-approve.yml
  7. 3 3
      .github/workflows/dependency-review.yml
  8. 4 4
      .github/workflows/dlc.yml
  9. 6 3
      .github/workflows/docs.yml
  10. 23 23
      .github/workflows/e2e-managed.yml
  11. 5 6
      .github/workflows/e2e.yml
  12. 15 13
      .github/workflows/helm.yml
  13. 3 3
      .github/workflows/lgtm.yml
  14. 3 3
      .github/workflows/ok-to-test-managed.yml
  15. 3 3
      .github/workflows/ok-to-test.yml
  16. 20 13
      .github/workflows/publish.yml
  17. 6 4
      .github/workflows/pull-request-label.yml
  18. 2 2
      .github/workflows/rebuild-image.yml
  19. 59 13
      .github/workflows/release.yml
  20. 28 7
      .github/workflows/release_esoctl.yml
  21. 5 4
      .github/workflows/scorecard.yml
  22. 2 2
      .github/workflows/stale.yml
  23. 8 7
      .github/workflows/update-deps.yml
  24. 3 3
      .github/workflows/zizmor.yml
  25. 8 0
      .golangci.yaml
  26. 2 0
      ADOPTERS.md
  27. 0 2
      CODEOWNERS.md
  28. 1 1
      Dockerfile
  29. 3 6
      Dockerfile.standalone
  30. 8 11
      Dockerfile.ubi
  31. 40 51
      Makefile
  32. 4 2
      Tiltfile
  33. 3 3
      apis/externalsecrets/v1/externalsecret_types.go
  34. 10 12
      apis/externalsecrets/v1/externalsecret_validator.go
  35. 2 4
      apis/externalsecrets/v1/externalsecret_validator_test.go
  36. 1 2
      apis/externalsecrets/v1/externalsecret_webhook.go
  37. 1 1
      apis/externalsecrets/v1/fakes/pushremoteref.go
  38. 4 3
      apis/externalsecrets/v1/provider_schema_maintenance.go
  39. 11 0
      apis/externalsecrets/v1/secretsstore_infisical_types.go
  40. 10 1
      apis/externalsecrets/v1/secretsstore_secretserver_types.go
  41. 0 52
      apis/externalsecrets/v1/secretstore_alibaba_types.go
  42. 4 1
      apis/externalsecrets/v1/secretstore_azurekv_types.go
  43. 49 0
      apis/externalsecrets/v1/secretstore_barbican_types.go
  44. 4 0
      apis/externalsecrets/v1/secretstore_beyondtrust_types.go
  45. 0 42
      apis/externalsecrets/v1/secretstore_device42_types.go
  46. 25 2
      apis/externalsecrets/v1/secretstore_doppler_types.go
  47. 56 0
      apis/externalsecrets/v1/secretstore_dvls_types.go
  48. 3 0
      apis/externalsecrets/v1/secretstore_ibm_types.go
  49. 62 0
      apis/externalsecrets/v1/secretstore_nebius_types.go
  50. 25 0
      apis/externalsecrets/v1/secretstore_onepassword_sdk_types.go
  51. 17 11
      apis/externalsecrets/v1/secretstore_types.go
  52. 35 19
      apis/externalsecrets/v1/secretstore_validator.go
  53. 5 1
      apis/externalsecrets/v1/secretstore_validator_test.go
  54. 43 3
      apis/externalsecrets/v1/secretstore_vault_types.go
  55. 3 5
      apis/externalsecrets/v1/secretstore_webhook.go
  56. 301 120
      apis/externalsecrets/v1/zz_generated.deepcopy.go
  57. 1 1
      apis/externalsecrets/v1alpha1/pushsecret_types.go
  58. 3 3
      apis/externalsecrets/v1beta1/externalsecret_types.go
  59. 13 12
      apis/externalsecrets/v1beta1/externalsecret_validator.go
  60. 2 4
      apis/externalsecrets/v1beta1/externalsecret_validator_test.go
  61. 1 2
      apis/externalsecrets/v1beta1/externalsecret_webhook.go
  62. 4 0
      apis/externalsecrets/v1beta1/secretstore_beyondtrust_types.go
  63. 5 5
      apis/externalsecrets/v1beta1/secretstore_types.go
  64. 26 20
      apis/externalsecrets/v1beta1/secretstore_validator.go
  65. 5 1
      apis/externalsecrets/v1beta1/secretstore_validator_test.go
  66. 3 5
      apis/externalsecrets/v1beta1/secretstore_webhook.go
  67. 15 0
      apis/externalsecrets/v1beta1/zz_generated.deepcopy.go
  68. 2 1
      apis/generators/v1alpha1/types_mfa.go
  69. 7 0
      apis/generators/v1alpha1/types_password.go
  70. 4 3
      apis/generators/v1alpha1/types_sshkey.go
  71. 5 0
      apis/generators/v1alpha1/zz_generated.deepcopy.go
  72. 45 37
      apis/go.mod
  73. 106 120
      apis/go.sum
  74. 2 1
      cmd/controller/certcontroller.go
  75. 23 16
      cmd/controller/root.go
  76. 4 0
      cmd/esoctl/.goreleaser.yaml
  77. 1 1
      cmd/esoctl/Makefile
  78. 67 7
      cmd/esoctl/generator/bootstrap.go
  79. 6 6
      config/crds/bases/external-secrets.io_clusterexternalsecrets.yaml
  80. 1 1
      config/crds/bases/external-secrets.io_clusterpushsecrets.yaml
  81. 636 151
      config/crds/bases/external-secrets.io_clustersecretstores.yaml
  82. 6 6
      config/crds/bases/external-secrets.io_externalsecrets.yaml
  83. 1 1
      config/crds/bases/external-secrets.io_pushsecrets.yaml
  84. 636 151
      config/crds/bases/external-secrets.io_secretstores.yaml
  85. 154 2
      config/crds/bases/generators.external-secrets.io_clustergenerators.yaml
  86. 8 0
      config/crds/bases/generators.external-secrets.io_passwords.yaml
  87. 4 2
      config/crds/bases/generators.external-secrets.io_sshkeys.yaml
  88. 137 0
      config/crds/bases/generators.external-secrets.io_vaultdynamicsecrets.yaml
  89. 3 3
      deploy/charts/external-secrets/Chart.lock
  90. 3 3
      deploy/charts/external-secrets/Chart.yaml
  91. 30 13
      deploy/charts/external-secrets/README.md
  92. 8 2
      deploy/charts/external-secrets/templates/_helpers.tpl
  93. 46 11
      deploy/charts/external-secrets/templates/cert-controller-deployment.yaml
  94. 1 1
      deploy/charts/external-secrets/templates/cert-controller-service.yaml
  95. 49 9
      deploy/charts/external-secrets/templates/deployment.yaml
  96. 1 0
      deploy/charts/external-secrets/templates/validatingwebhook.yaml
  97. 7 0
      deploy/charts/external-secrets/templates/webhook-certificate.yaml
  98. 36 9
      deploy/charts/external-secrets/templates/webhook-deployment.yaml
  99. 9 6
      deploy/charts/external-secrets/tests/__snapshot__/cert_controller_test.yaml.snap
  100. 5 5
      deploy/charts/external-secrets/tests/__snapshot__/controller_test.yaml.snap

+ 2 - 3
.github/actions/e2e/action.yml

@@ -47,10 +47,9 @@ runs:
         name: external-secrets
 
     - name: Setup Docker Buildx
-      # https://github.com/docker/setup-buildx-action/releases/tag/v2.10.0
-      uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55 # v2.10.0
+      # https://github.com/docker/setup-buildx-action/releases/tag/v3.12.0
+      uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
       with:
-        version: ${{ env.DOCKER_BUILDX_VERSION }}
         install: true
 
     - name: Run e2e Tests

+ 126 - 25
.github/actions/sign/action.yml

@@ -18,14 +18,16 @@ runs:
   steps:
 
     - name: Install cosign
-      # https://github.com/sigstore/cosign-installer/releases/tag/v2.8.1
-      uses: sigstore/cosign-installer@c85d0e205a72a294fe064f618a87dbac13084086 # v2.8.1
+      # https://github.com/sigstore/cosign-installer/releases/tag/v4.0.0
+      uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
       with:
-        cosign-release: v1.13.6
+        cosign-release: 'v3.0.2'
 
     - name: Install Syft
-      # https://github.com/anchore/sbom-action/releases/tag/v0.7.0
-      uses: anchore/sbom-action/download-syft@ce4a7cf05d7b684693d7b6bba97bfbee56806edb # v0.7.0
+      # https://github.com/anchore/sbom-action/releases/tag/v0.22.2
+      uses: anchore/sbom-action/download-syft@28d71544de8eaf1b958d335707167c5f783590ad # v0.22.2
+      with:
+        syft-version: v1.41.2
 
     - name: Check Cosign install
       shell: bash
@@ -53,57 +55,156 @@ runs:
       env:
         IMAGE_NAME: ${{ inputs.image-name }}
         IMAGE_TAG: ${{ inputs.image-tag }}
-      run: echo "digest=$(crane digest ${IMAGE_NAME}:${IMAGE_TAG})" >> $GITHUB_OUTPUT
+      run: |
+        echo "::group::Crane digest lookup"
+        echo "Looking up digest for ${IMAGE_NAME}:${IMAGE_TAG}"
+        DIGEST=$(crane digest ${IMAGE_NAME}:${IMAGE_TAG})
+        echo "Found digest: ${DIGEST}"
+        echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
+        echo "::endgroup::"
 
     - name: Sign image
       shell: bash
       env:
-        COSIGN_EXPERIMENTAL: "1"
         IMAGE_NAME: ${{ inputs.image-name }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
         GITHUB_TRIGGERING_ACTOR: ${{ github.triggering_actor }}
-      run: cosign sign -a GITHUB_ACTOR=${GITHUB_TRIGGERING_ACTOR} "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+      run: |
+        echo "::group::Cosign sign"
+        echo "Signing ${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        cosign sign --yes --new-bundle-format=false --use-signing-config=false -a GITHUB_ACTOR=${GITHUB_TRIGGERING_ACTOR} "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
 
     - name: Attach SBOM to image
       shell: bash
       id: sbom
       env:
-        COSIGN_EXPERIMENTAL: "1"
         IMAGE_NAME: ${{ inputs.image-name }}
         IMAGE_TAG: ${{ inputs.image-tag }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
       run: |
+        echo "::group::Image SBOM generation"
         # Image SBOM (OS + application libs contained in the image)
+        echo "Generating image SBOM for ${IMAGE_NAME}@${CONTAINER_DIGEST}"
         syft "${IMAGE_NAME}@${CONTAINER_DIGEST}" -o spdx-json=sbom.${IMAGE_TAG}.spdx.json
-        cosign attest --predicate sbom.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} | jq '.payload |= @base64d | .payload | fromjson'
-
+        ORIGINAL_IMAGE_SBOM_SIZE="$(wc -c < sbom.${IMAGE_TAG}.spdx.json)"
+        echo "Original image SBOM size: ${ORIGINAL_IMAGE_SBOM_SIZE} bytes"
+
+        MAX_SBOM_SIZE_BYTES=10000000
+
+        echo "Deduplicating image SPDX package nodes and relationships"
+        bash ./hack/dedupe-spdx-gomod.sh \
+          --input sbom.${IMAGE_TAG}.spdx.json \
+          --output sbom.${IMAGE_TAG}.dedup.spdx.json
+
+        DEDUP_IMAGE_SBOM_SIZE="$(wc -c < sbom.${IMAGE_TAG}.dedup.spdx.json)"
+        echo "Deduplicated image SBOM size: ${DEDUP_IMAGE_SBOM_SIZE} bytes"
+
+        if [[ "${DEDUP_IMAGE_SBOM_SIZE}" -gt "${MAX_SBOM_SIZE_BYTES}" ]]; then
+          echo "Deduped image SBOM still above ${MAX_SBOM_SIZE_BYTES} bytes, dropping file ownership data"
+          bash ./hack/dedupe-spdx-gomod.sh \
+            --input sbom.${IMAGE_TAG}.spdx.json \
+            --output sbom.${IMAGE_TAG}.dedup.spdx.json \
+            --drop-file-ownership
+          DEDUP_IMAGE_SBOM_SIZE="$(wc -c < sbom.${IMAGE_TAG}.dedup.spdx.json)"
+          echo "Ownership-pruned deduplicated image SBOM size: ${DEDUP_IMAGE_SBOM_SIZE} bytes"
+        fi
+
+        if [[ "${DEDUP_IMAGE_SBOM_SIZE}" -gt "${MAX_SBOM_SIZE_BYTES}" ]]; then
+          echo "Image SBOM predicate is still too large (${DEDUP_IMAGE_SBOM_SIZE} bytes)."
+          echo "Refusing attestation to avoid Rekor submission retries/failure."
+          exit 1
+        fi
+        echo "::endgroup::"
+
+        echo "::group::Attest image SBOM"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate sbom.${IMAGE_TAG}.dedup.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify image SBOM attestation"
+        echo "Using certificate-identity-regexp: https://github.com/$GITHUB_REPOSITORY/.*"
+        cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} \
+            --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
+            --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq '.payload |= @base64d | .payload | fromjson'
+        echo "::endgroup::"
+
+        echo "::group::Go modules SBOM generation"
         # Go modules SBOM (dependencies from the source tree)
         # Requires repository to be checked out before this composite action runs.
         syft dir:. -o spdx-json=sbom.gomod.${IMAGE_TAG}.spdx.json
-        cosign attest --predicate sbom.gomod.${IMAGE_TAG}.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} | jq '.payload |= @base64d | .payload | fromjson'
+        ORIGINAL_GOMOD_SBOM_SIZE="$(wc -c < sbom.gomod.${IMAGE_TAG}.spdx.json)"
+        echo "Original Go modules SBOM size: ${ORIGINAL_GOMOD_SBOM_SIZE} bytes"
+
+        echo "Deduplicating Go modules SPDX package nodes and relationships"
+        bash ./hack/dedupe-spdx-gomod.sh \
+          --input sbom.gomod.${IMAGE_TAG}.spdx.json \
+          --output sbom.gomod.${IMAGE_TAG}.dedup.spdx.json
+
+        DEDUP_GOMOD_SBOM_SIZE="$(wc -c < sbom.gomod.${IMAGE_TAG}.dedup.spdx.json)"
+        echo "Deduplicated Go modules SBOM size: ${DEDUP_GOMOD_SBOM_SIZE} bytes"
+
+        # Rekor requests can fail when predicates are too large. If the deduped
+        # SBOM is still big, drop file ownership-heavy data and re-check size.
+        if [[ "${DEDUP_GOMOD_SBOM_SIZE}" -gt "${MAX_SBOM_SIZE_BYTES}" ]]; then
+          echo "Deduped SBOM still above ${MAX_SBOM_SIZE_BYTES} bytes, dropping file ownership data"
+          bash ./hack/dedupe-spdx-gomod.sh \
+            --input sbom.gomod.${IMAGE_TAG}.spdx.json \
+            --output sbom.gomod.${IMAGE_TAG}.dedup.spdx.json \
+            --drop-file-ownership
+          DEDUP_GOMOD_SBOM_SIZE="$(wc -c < sbom.gomod.${IMAGE_TAG}.dedup.spdx.json)"
+          echo "Ownership-pruned deduplicated Go modules SBOM size: ${DEDUP_GOMOD_SBOM_SIZE} bytes"
+        fi
+
+        if [[ "${DEDUP_GOMOD_SBOM_SIZE}" -gt "${MAX_SBOM_SIZE_BYTES}" ]]; then
+          echo "Go modules SBOM predicate is still too large (${DEDUP_GOMOD_SBOM_SIZE} bytes)."
+          echo "Refusing attestation to avoid Rekor submission retries/failure."
+          exit 1
+        fi
+        echo "::endgroup::"
+
+        echo "::group::Attest Go modules SBOM"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate sbom.gomod.${IMAGE_TAG}.dedup.spdx.json --type spdx "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify Go modules SBOM attestation"
+        cosign verify-attestation --type spdx ${IMAGE_NAME}@${CONTAINER_DIGEST} \
+            --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
+            --certificate-oidc-issuer https://token.actions.githubusercontent.com | jq ' .payload |= @base64d | .payload | fromjson | .subject'
+        echo "::endgroup::"
 
     - name: Generate provenance
-      # https://github.com/philips-labs/slsa-provenance-action/releases/tag/v0.7.2
-      uses: philips-labs/slsa-provenance-action@dddb40e199ae28d4cd2f17bad7f31545556fdd3d # v0.7.2
-      with:
-        command: generate
-        subcommand: container
-        arguments: --repository "${{ inputs.image-name }}" --output-path provenance.${{ inputs.image-tag }}.intoto.jsonl --digest "${{ steps.container_info.outputs.digest }}" --tags "${{ inputs.image-tag }}"
+      shell: bash
       env:
-        COSIGN_EXPERIMENTAL: "0"
-        GITHUB_TOKEN: "${{ github.token }}"
+        IMAGE_NAME: ${{ inputs.image-name }}
+        IMAGE_TAG: ${{ inputs.image-tag }}
+        CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
+      run: |
+        echo "::group::Generate provenance"
+        ./hack/generate-provenance.sh \
+          --repository "${IMAGE_NAME}" \
+          --digest "${CONTAINER_DIGEST}" \
+          --tags "${IMAGE_TAG}" \
+          --output-path "provenance.${IMAGE_TAG}.intoto.jsonl"
+        echo "::endgroup::"
 
     - name: Attach provenance
       shell: bash
       id: provenance
       env:
-        COSIGN_EXPERIMENTAL: "1"
         IMAGE_NAME: ${{ inputs.image-name }}
         IMAGE_TAG: ${{ inputs.image-tag }}
         CONTAINER_DIGEST: ${{ steps.container_info.outputs.digest }}
       run: |
+        echo "::group::Prepare provenance predicate"
         jq '.predicate' provenance.${IMAGE_TAG}.intoto.jsonl > provenance-predicate.att
-        cosign attest --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${CONTAINER_DIGEST}"
-        cosign verify-attestation --type slsaprovenance ${IMAGE_NAME}@${CONTAINER_DIGEST}
+        echo "::endgroup::"
+
+        echo "::group::Attest provenance"
+        cosign attest --yes --new-bundle-format=false --use-signing-config=false --predicate provenance-predicate.att --type slsaprovenance "${IMAGE_NAME}@${CONTAINER_DIGEST}"
+        echo "::endgroup::"
+
+        echo "::group::Verify provenance attestation"
+        cosign verify-attestation --type slsaprovenance ${IMAGE_NAME}@${CONTAINER_DIGEST} \
+            --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
+            --certificate-oidc-issuer https://token.actions.githubusercontent.com
+        echo "::endgroup::"

+ 23 - 47
.github/workflows/ci.yml

@@ -26,7 +26,7 @@ jobs:
     outputs:
       noop: ${{ steps.noop.outputs.should_skip }}
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Detect No-op Changes
@@ -38,48 +38,19 @@ jobs:
           do_not_skip: '["workflow_dispatch", "schedule", "push"]'
           concurrent_skipping: false
 
-  lint:
-    permissions:
-      contents: read  # for actions/checkout to fetch code
-      pull-requests: read  # for golangci/golangci-lint-action to fetch pull requests
-    runs-on: ubuntu-latest
-    needs: detect-noop
-    if: needs.detect-noop.outputs.noop != 'true' && github.ref != 'refs/heads/main'
-
-    steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
-        with:
-          egress-policy: audit
-      - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
-
-      - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
-        id: setup-go
-        with:
-          go-version-file: "go.mod"
-
-      - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
-        run: go mod download
-
-      - name: Run lint
-        run: make lint
-
   license-check:
     permissions:
-      contents: read  # for actions/checkout to fetch code
-      pull-requests: read  # for golangci/golangci-lint-action to fetch pull requests
+      contents: read
     runs-on: ubuntu-latest
     needs: detect-noop
     if: needs.detect-noop.outputs.noop != 'true' && github.ref != 'refs/heads/main'
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - name: Check License Headers
         uses: apache/skywalking-eyes/header@61275cc80d0798a405cb070f7d3a8aaf7cf2c2c1 # v0.8.0
 
@@ -87,22 +58,23 @@ jobs:
     runs-on: ubuntu-latest
     needs: detect-noop
     if: needs.detect-noop.outputs.noop != 'true' && github.ref != 'refs/heads/main'
+    permissions:
+      contents: read
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
-      - uses: hashicorp/setup-terraform@982f6f017c89db9dccac8593265de0c382e4c050 # v3
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+      - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v3
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         id: setup-go
         with:
           go-version-file: "go.mod"
 
       - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
         run: go mod download
 
       - name: Configure Git
@@ -111,36 +83,40 @@ jobs:
           git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
 
       - name: Check Diff
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
-          make check-diff
+          # make check-diff will also execute linting so there is no need for a separate lint action
+          make check-diff LINT_JOBS=2
 
   unit-tests:
     runs-on: ubuntu-latest
     needs: detect-noop
     if: needs.detect-noop.outputs.noop != 'true'
+    permissions:
+      contents: read
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
 
       - name: Fetch History
         run: git fetch --prune --unshallow
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         id: setup-go
         with:
           go-version-file: "go.mod"
 
       - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
         run: go mod download
 
       - name: Cache envtest binaries
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: bin/k8s
           key: ${{ runner.os }}-envtest-${{env.KUBERNETES_VERSION}}
@@ -150,7 +126,7 @@ jobs:
           make test
 
       - name: Publish Unit Test Coverage
-        uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1
+        uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
         env:
           CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
         with:
@@ -180,8 +156,8 @@ jobs:
           tag-suffix: "-ubi"
         - dockerfile: "Dockerfile.ubi"
           build-args: "CGO_ENABLED=0 GOEXPERIMENT=boringcrypto"
-          build-arch: "amd64 ppc64le"
-          build-platform: "linux/amd64,linux/ppc64le"
+          build-arch: "amd64 arm64 ppc64le"
+          build-platform: "linux/amd64,linux/arm64,linux/ppc64le"
           tag-suffix: "-ubi-boringssl"
     with:
       dockerfile: ${{ matrix.dockerfile }}

+ 4 - 4
.github/workflows/codeql.yml

@@ -26,20 +26,20 @@ jobs:
           - language: actions
             build-mode: none
     steps:
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
     - name: Checkout repository
-      uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
     # Without this, codeql scan builds databases separately for all modules during every run.
     - name: Run go work
       run: make go-work
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
+      uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3.29.5
       with:
         languages: ${{ matrix.language }}
         build-mode: ${{ matrix.build-mode }}
         config-file: ./.github/config/codeql-config.yaml
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
+      uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3.29.5

+ 2 - 2
.github/workflows/crds.yml

@@ -18,11 +18,11 @@ jobs:
   crd-tests:
     runs-on: ubuntu-latest
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
 

+ 3 - 3
.github/workflows/dependabot-approve.yml

@@ -12,10 +12,10 @@ jobs:
     # PRs but also ensures that it only does work for Dependabot PRs.
     if: ${{ github.actor == 'dependabot[bot]' }}
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
-      - uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      - uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
         id: app-token
         with:
           app-id: ${{ secrets.APP_ID }}
@@ -24,7 +24,7 @@ jobs:
       # will not occur.
       - name: Dependabot metadata
         id: dependabot-metadata
-        uses: dependabot/fetch-metadata@08eff52bf64351f401fb50d4972fa95b9f2c2d1b # v2.4.0
+        uses: dependabot/fetch-metadata@21025c705c08248db411dc16f3619e6b5f9ea21a # v2.5.0
         with:
           github-token: "${{ steps.app-token.outputs.token }}"
       # Here the PR gets approved.

+ 3 - 3
.github/workflows/dependency-review.yml

@@ -17,11 +17,11 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Harden the runner (Audit all outbound calls)
-        uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: 'Checkout Repository'
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - name: 'Dependency Review'
-        uses: actions/dependency-review-action@40c09b7dc99638e5ddb0bfd91c1673effc064d8a # v4
+        uses: actions/dependency-review-action@05fe4576374b728f0c523d6a13d64c25081e0803 # v4

+ 4 - 4
.github/workflows/dlc.yml

@@ -16,22 +16,22 @@ jobs:
   fossa-scan:
     runs-on: ubuntu-latest
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         if: ${{ env.HAS_FOSSA_KEY == 'true' }}
         with:
           egress-policy: audit
       - name: "Checkout Code"
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         if: ${{ env.HAS_FOSSA_KEY == 'true' }}
 
       - name: "Run FOSSA Scan"
-        uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # main
+        uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # main
         if: ${{ env.HAS_FOSSA_KEY == 'true' }}
         with:
           api-key: ${{secrets.FOSSA_API_KEY}}
 
       - name: "Run FOSSA Test"
-        uses: fossas/fossa-action@3ebcea1862c6ffbd5cf1b4d0bd6b3fe7bd6f2cac # main
+        uses: fossas/fossa-action@c414b9ad82eaad041e47a7cf62a4f02411f427a0 # main
         if: ${{ env.HAS_FOSSA_KEY == 'true' }}
         with:
           api-key: ${{secrets.FOSSA_API_KEY}}

+ 6 - 3
.github/workflows/docs.yml

@@ -14,22 +14,25 @@ jobs:
     permissions:
       contents: write #needed to publish documentation
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
-      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         with:
           go-version-file: "go.mod"
 
       - name: Configure Git
+        env:
+          TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
           git config user.name "$GITHUB_ACTOR"
           git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
+          git remote set-url origin "https://x-access-token:${{ env.TOKEN }}@github.com/${{ github.repository }}.git"
 
       - name: Build Docs
         run: make docs.publish

+ 23 - 23
.github/workflows/e2e-managed.yml

@@ -54,7 +54,7 @@ jobs:
     outputs:
       check_run_id: ${{ steps.create_check.outputs.check_run_id }}
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
@@ -102,17 +102,17 @@ jobs:
       contents: read
       packages: write
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Fork based /ok-to-test-managed checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         with:
           go-version-file: go.mod
 
@@ -123,23 +123,23 @@ jobs:
           echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
 
       - name: Cache the Go Build Cache
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.build-cache }}
           key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-
 
       - name: Cache Go Dependencies
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.mod-cache }}
           key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
 
-      - uses: hashicorp/setup-terraform@982f6f017c89db9dccac8593265de0c382e4c050 # v3
+      - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v3
 
       - name: Configure AWS Credentials
-        uses: aws-actions/configure-aws-credentials@0d00a56e021d460a2d2bb10b9d8f94f6693a71ad
+        uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7
         with:
           role-to-assume: ${{ secrets.AWS_OIDC_ROLE_ARN }}
           aws-region: ${{ env.AWS_REGION }}
@@ -151,7 +151,7 @@ jobs:
         run: aws --region $AWS_REGION eks update-kubeconfig --name $AWS_CLUSTER_NAME
 
       - name: Login to Docker
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         if: env.GHCR_USERNAME != ''
         with:
           registry: ghcr.io
@@ -177,17 +177,17 @@ jobs:
       contents: read
       packages: write
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Fork based /ok-to-test-managed checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         with:
           go-version-file: go.mod
 
@@ -198,20 +198,20 @@ jobs:
           echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
 
       - name: Cache the Go Build Cache
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.build-cache }}
           key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-
 
       - name: Cache Go Dependencies
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.mod-cache }}
           key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
 
-      - uses: hashicorp/setup-terraform@982f6f017c89db9dccac8593265de0c382e4c050 # v3
+      - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v3
 
       - name: Authenticate to Google Cloud
         uses: 'google-github-actions/auth@fc2174804b84f912b1f6d334e9463f484f1c552d' # v3
@@ -237,7 +237,7 @@ jobs:
           project_id: '${{ secrets.GCP_FED_PROJECT_ID }}'
 
       - name: Login to Docker
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         if: env.GHCR_USERNAME != ''
         with:
           registry: ghcr.io
@@ -265,17 +265,17 @@ jobs:
       contents: read
       packages: write
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Fork based /ok-to-test-managed checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           ref: 'refs/pull/${{ github.event.client_payload.pull_request.number }}/merge'
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         with:
           go-version-file: go.mod
 
@@ -286,20 +286,20 @@ jobs:
           echo "mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
 
       - name: Cache the Go Build Cache
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.build-cache }}
           key: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-build-unit-tests-${{ github.sha }}-
 
       - name: Cache Go Dependencies
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
+        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
         with:
           path: ${{ steps.go.outputs.mod-cache }}
           key: ${{ runner.os }}-pkg-${{ github.sha }}-${{ hashFiles('**/go.sum') }}
           restore-keys: ${{ runner.os }}-pkg-${{ github.sha }}-
 
-      - uses: hashicorp/setup-terraform@982f6f017c89db9dccac8593265de0c382e4c050 # v3
+      - uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v3
 
       - name: Azure CLI login
         uses: azure/login@a457da9ea143d694b1b9c7c869ebb04ebe844ef5
@@ -319,7 +319,7 @@ jobs:
         run: az aks get-credentials --admin --name eso-cluster --resource-group external-secrets-e2e
 
       - name: Login to Docker
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         if: env.GHCR_USERNAME != ''
         with:
           registry: ghcr.io

+ 5 - 6
.github/workflows/e2e.yml

@@ -10,7 +10,6 @@ name: e2e tests
 
 env:
   # Common versions
-  DOCKER_BUILDX_VERSION: 'v0.4.2'
   KIND_VERSION: 'v0.30.0'
   KIND_IMAGE: 'kindest/node:v1.33.4'
 
@@ -62,12 +61,12 @@ jobs:
       contents: read  #for checkout
     if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor !='dependabot[bot]'
     steps:
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
 
     - name: Branch based PR checkout
-      uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
 
     - name: Fetch History
       run: git fetch --prune --unshallow
@@ -83,13 +82,13 @@ jobs:
       pull-requests: write # to publish the status as comments
     if: github.event_name == 'repository_dispatch'
     steps:
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
 
     # Check out merge commit
     - name: Fork based /ok-to-test checkout
-      uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       with:
         ref: '${{ env.TARGET_SHA }}'
 
@@ -100,7 +99,7 @@ jobs:
       uses: ./.github/actions/e2e
     - id: create_token
       if: always()
-      uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
       with:
         app-id: ${{ secrets.APP_ID }}
         private-key: ${{ secrets.PRIVATE_KEY }}

+ 15 - 13
.github/workflows/helm.yml

@@ -13,12 +13,14 @@ permissions:
 jobs:
   lint-and-test:
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
 
@@ -30,12 +32,12 @@ jobs:
         with:
           version: v3.14.2 # remember to also update for the second job (release)
 
-      - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
+      - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
         with:
           python-version: 3.12
 
       - name: Set up chart-testing
-        uses: helm/chart-testing-action@0d28d3144d3a25ea2cc349d6e59901c4ff469b3b # v2.7.0
+        uses: helm/chart-testing-action@6ec842c01de15ebb84c8627d2744a0c2f2755c9f # v2.8.0
 
       - name: Run chart-testing (list-changed)
         id: list-changed
@@ -48,7 +50,7 @@ jobs:
         run: ct lint --config=.github/ci/ct.yaml
 
       - name: Create kind cluster
-        uses: helm/kind-action@a1b0e391336a6ee6713a0583f8c6240d70863de3 # v1.12.0
+        uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0
         if: steps.list-changed.outputs.changed == 'true'
 
       - name: Run chart-testing (install)
@@ -68,12 +70,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Harden the runner (Audit all outbound calls)
-        uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
 
@@ -121,7 +123,7 @@ jobs:
           version: v3.17.3 # remember to also update for the first job (lint-and-test)
 
       - name: Login to GHCR
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
@@ -130,7 +132,7 @@ jobs:
       - name: Install cosign
         uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
         with:
-          cosign-release: 'v2.4.1'
+          cosign-release: 'v3.0.2'
 
       - name: Push chart to GHCR
         id: push_chart
@@ -155,9 +157,9 @@ jobs:
             echo "$helm_push_output"
 
             artifact_digest_uri="${chart_registry}/${chart_name}@${digest}"
-            cosign sign --yes "$artifact_digest_uri"
-            cosign verify "$artifact_digest_uri" \
-                --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/*" \
+            cosign sign --yes --new-bundle-format=false --use-signing-config=false "$artifact_digest_uri"
+            cosign verify --new-bundle-format=false "$artifact_digest_uri" \
+                --certificate-identity-regexp "https://github.com/$GITHUB_REPOSITORY/.*" \
                 --certificate-oidc-issuer https://token.actions.githubusercontent.com
 
             echo "digest=${digest}" >> "$GITHUB_OUTPUT"
@@ -168,7 +170,7 @@ jobs:
 
       - name: Generate provenance attestation and push to OCI registry
         if: steps.push_chart.outputs.push_status == 'pushed'
-        uses: actions/attest-build-provenance@977bb373ede98d70efdf65b84cb5f73e068dcc2a # v3.0.0
+        uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
         with:
           push-to-registry: true
           subject-name: ${{ steps.push_chart.outputs.registry }}/${{ steps.push_chart.outputs.chart_name }}

+ 3 - 3
.github/workflows/lgtm.yml

@@ -19,7 +19,7 @@ jobs:
     steps:
     # Checkout repo to access CODEOWNERS.md
     - name: Checkout repository
-      uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5
       with:
         sparse-checkout: |
           CODEOWNERS.md
@@ -27,14 +27,14 @@ jobs:
     # Generate a GitHub App installation access token
     - name: Generate token
       id: generate_token
-      uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
       with:
         app-id: ${{ secrets.LGTM_APP_ID }}
         private-key: ${{ secrets.LGTM_PRIVATE_KEY }}
         owner: ${{ github.repository_owner }}
 
     - name: Slash Command Dispatch
-      uses: peter-evans/slash-command-dispatch@13bc09769d122a64f75aa5037256f6f2d78be8c4 # v4.0.0
+      uses: peter-evans/slash-command-dispatch@9bdcd7914ec1b75590b790b844aa3b8eee7c683a # v5.0.2
       with:
         token: ${{ steps.generate_token.outputs.token }}
         reaction-token: ${{ secrets.GITHUB_TOKEN }}

+ 3 - 3
.github/workflows/ok-to-test-managed.yml

@@ -20,19 +20,19 @@ jobs:
     # To create a new GitHub App:
     #   https://developer.github.com/apps/building-github-apps/creating-a-github-app/
     # See app.yml for an example app manifest
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
     - name: Generate token
       id: generate_token
-      uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
       with:
         app-id: ${{ secrets.APP_ID }}
         private-key: ${{ secrets.PRIVATE_KEY }}
         owner: ${{ github.repository_owner }}
 
     - name: Slash Command Dispatch
-      uses: peter-evans/slash-command-dispatch@13bc09769d122a64f75aa5037256f6f2d78be8c4 # v4.0.0
+      uses: peter-evans/slash-command-dispatch@9bdcd7914ec1b75590b790b844aa3b8eee7c683a # v5.0.2
       env:
         TOKEN: ${{ steps.generate_token.outputs.token }}
       with:

+ 3 - 3
.github/workflows/ok-to-test.yml

@@ -16,7 +16,7 @@ jobs:
     # Only run for PRs, not issue comments
     if: ${{ github.event.issue.pull_request }}
     steps:
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
     # Generate a GitHub App installation access token from an App ID and private key
@@ -25,14 +25,14 @@ jobs:
     # See app.yml for an example app manifest
     - name: Generate token
       id: generate_token
-      uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
       with:
         app-id: ${{ secrets.APP_ID }}
         private-key: ${{ secrets.PRIVATE_KEY }}
         owner: ${{ github.repository_owner }}
 
     - name: Slash Command Dispatch
-      uses: peter-evans/slash-command-dispatch@13bc09769d122a64f75aa5037256f6f2d78be8c4 # v4.0.0
+      uses: peter-evans/slash-command-dispatch@9bdcd7914ec1b75590b790b844aa3b8eee7c683a # v5.0.2
       with:
         token: ${{ steps.generate_token.outputs.token }}
         reaction-token: ${{ secrets.GITHUB_TOKEN }}

+ 20 - 13
.github/workflows/publish.yml

@@ -53,34 +53,32 @@ jobs:
     outputs:
       image-tag: ${{ steps.container_info.outputs.image-tag }}
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           ref: ${{ inputs.ref }}
 
       - name: Setup QEMU
-        uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
+        uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0
         with:
           platforms: all
 
       - name: Setup Docker Buildx
-        uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
+        uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
         with:
-          version: 'v0.4.2'
           install: true
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         id: setup-go
         with:
           go-version-file: "go.mod"
 
       - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
         run: go mod download
 
       - name: Fetch History
@@ -88,7 +86,7 @@ jobs:
         run: git fetch --prune --unshallow
 
       - name: Login to Docker
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         if: env.IS_FORK != ''
         with:
           registry: ghcr.io
@@ -122,6 +120,7 @@ jobs:
           IMAGE_TAG: ${{ steps.container_info.outputs.image-tag }}
           BUILD_ARGS: ${{ inputs.build-args }}
           DOCKER_BUILD_ARGS: >-
+            --no-cache
             --push
             --platform ${{ inputs.build-platform }}
         run: make docker.build
@@ -132,11 +131,19 @@ jobs:
         env:
           IMAGE_TAG: ${{ steps.container_info.outputs.image-tag }}
           BUILD_ARGS: ${{ inputs.build-args }}
-          DOCKER_BUILD_ARGS: --load
+          DOCKER_BUILD_ARGS: --no-cache --load
         run: make docker.build
-
+      # images are large to the point trivy fails due to no space on disk left
+      # This is a silly attempt to clean up space for trivy to run more
+      # consistently
+      - name: Cleanup unused cache
+        shell: bash
+        run: |
+          docker system prune --force
+          go clean -cache
+          go clean -modcache
       - name: Run Trivy vulnerability scanner
-        uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # master
+        uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # master
         with:
           image-ref: ${{ inputs.image-name }}:${{ steps.container_info.outputs.image-tag }}
           format: 'table'
@@ -153,11 +160,11 @@ jobs:
       id-token: write #for keyless sign
       packages: write #to update packages with added SBOMs.
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       - name: Sign image
         if: env.IS_FORK != ''
         uses: ./.github/actions/sign

+ 6 - 4
.github/workflows/pull-request-label.yml

@@ -9,8 +9,7 @@ on:
       - reopened
 
 permissions:
-  pull-requests: write
-  issues: write
+  contents: read
 
 jobs:
   conventional-commit-labeler:
@@ -75,7 +74,7 @@ jobs:
 
               if (breaking) {
                 console.log("Adding breaking change label");
-                labels.push(process.env.BREAKING_CHANGE_LABEL);
+                labels.push("breaking-change");
               }
 
               // Add type-based label
@@ -113,7 +112,7 @@ jobs:
       pull-requests: write
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
+      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v5
         with:
           sparse-checkout: |
             .github/config/labeler.yml
@@ -148,6 +147,9 @@ jobs:
     needs: [labeler, size-labeler, conventional-commit-labeler]
     name: verify labels
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
+      pull-requests: read
     steps:
       - name: PRs should have at least one qualifying label
         uses: docker://agilepathway/pull-request-label-checker:latest@sha256:14f5f3dfda922496d07d53494e2d2b42885165f90677a1c03d600059b7706a61

+ 2 - 2
.github/workflows/rebuild-image.yml

@@ -19,11 +19,11 @@ jobs:
       timestamp: ${{ steps.timestamp.outputs.timestamp }}
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
           ref: ${{ github.event.inputs.ref }}

+ 59 - 13
.github/workflows/release.yml

@@ -26,15 +26,37 @@ jobs:
       contents: read
     steps:
       - name: Harden the runner (Audit all outbound calls)
-        uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        env:
+          SOURCE_REF: ${{ github.event.inputs.source_ref }}
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "$SOURCE_REF"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/$SOURCE_REF")
+          elif git rev-parse --verify "$SOURCE_REF" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "$SOURCE_REF")
+          else
+            echo "Error: ref '$SOURCE_REF' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
       - name: check-docs
         env:
           DOCS_VERSION: ${{ github.event.inputs.version }}
@@ -47,18 +69,40 @@ jobs:
       contents: write # to create a release and push new docs
     steps:
       - name: Harden the runner (Audit all outbound calls)
-        uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+        uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
 
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        env:
+          SOURCE_REF: ${{ github.event.inputs.source_ref }}
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "$SOURCE_REF"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/$SOURCE_REF")
+          elif git rev-parse --verify "$SOURCE_REF" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "$SOURCE_REF")
+          else
+            echo "Error: ref '$SOURCE_REF' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
 
       - name: Create Release
-        uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
+        uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
         with:
           tag_name: ${{ github.event.inputs.version }}
           target_commitish: ${{ github.event.inputs.source_ref }}
@@ -71,9 +115,12 @@ jobs:
           GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
 
       - name: Configure Git
+        env:
+          TOKEN: ${{ secrets.GITHUB_TOKEN }}
         run: |
           git config user.name "$GITHUB_ACTOR"
           git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
+          git remote set-url origin "https://x-access-token:${{ env.TOKEN }}@github.com/${{ github.repository }}.git"
 
       - name: Update Docs
         if: github.ref == 'refs/heads/main'
@@ -102,26 +149,25 @@ jobs:
       RELEASE_TAG: ${{ github.event.inputs.version }}${{ matrix.tag_suffix }}
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         id: setup-go
         with:
           go-version-file: "go.mod"
 
       - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
         run: go mod download
 
       - name: Login to Docker
-        uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
+        uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
@@ -147,7 +193,7 @@ jobs:
           image-tag: ${{ env.RELEASE_TAG }}
 
       - name: Update Release
-        uses: softprops/action-gh-release@6da8fa9354ddfdc4aeace5fc48d7f679b5214090 # v2.4.1
+        uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2.5.0
         with:
           tag_name: ${{ github.event.inputs.version }}
           files: |

+ 28 - 7
.github/workflows/release_esoctl.yml

@@ -24,27 +24,48 @@ jobs:
     permissions:
       contents: write # for publishing the release
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
-          ref: ${{ github.event.inputs.source_ref }}
+
+      - name: Resolve and validate ref
+        id: resolve_ref
+        env:
+          SOURCE_REF: ${{ github.event.inputs.source_ref }}
+        run: |
+          set -e
+          # Try to fetch the ref from remote
+          if git fetch origin "$SOURCE_REF"; then
+            # Remote ref exists, use it
+            RESOLVED_SHA=$(git rev-parse "origin/$SOURCE_REF")
+          elif git rev-parse --verify "$SOURCE_REF" >/dev/null 2>&1; then
+            # Local ref exists (e.g., a tag)
+            RESOLVED_SHA=$(git rev-parse "$SOURCE_REF")
+          else
+            echo "Error: ref '$SOURCE_REF' not found"
+            exit 1
+          fi
+          echo "Resolved to SHA: $RESOLVED_SHA"
+          echo "sha=$RESOLVED_SHA" >> $GITHUB_OUTPUT
+
+      - name: Checkout validated ref
+        run: git checkout ${{ steps.resolve_ref.outputs.sha }}
 
       - name: Setup Go
-        uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+        uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
         id: setup-go
         with:
           go-version-file: "go.mod"
 
       - name: Download Go modules
-        if: ${{ steps.setup-go.outputs.cache-hit != 'true' }}
         run: go mod download
 
       - name: Install Syft
-        uses: anchore/sbom-action/download-syft@8e94d75ddd33f69f691467e42275782e4bfefe84 # v0.20.9
+        uses: anchore/sbom-action/download-syft@17ae1740179002c89186b61233e0f892c3118b11 # v0.23.0
 
       - name: Import GPG key
         id: import_gpg
@@ -72,7 +93,7 @@ jobs:
           git push origin $TAG
 
       - name: Run GoReleaser
-        uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
+        uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
         with:
           version: '~> v2'
           args: release --clean

+ 5 - 4
.github/workflows/scorecard.yml

@@ -6,7 +6,8 @@ on:
   push:
     branches: [ "main" ]
 
-permissions: read-all
+permissions:
+  contents: read
 
 jobs:
   analysis:
@@ -19,11 +20,11 @@ jobs:
       id-token: write
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: "Checkout code"
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           persist-credentials: false
 
@@ -36,6 +37,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v3.29.5
+        uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v3.29.5
         with:
           sarif_file: results.sarif

+ 2 - 2
.github/workflows/stale.yml

@@ -13,10 +13,10 @@ jobs:
       pull-requests: write  # for actions/stale to close stale PRs
     runs-on: ubuntu-latest
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
-      - uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 # v10.1.0
+      - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
         with:
           repo-token: ${{ secrets.GITHUB_TOKEN }}
           stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days.'

+ 8 - 7
.github/workflows/update-deps.yml

@@ -7,7 +7,6 @@ on:
   workflow_dispatch:
     inputs: {}
 
-
 permissions:
   contents: read
 
@@ -15,15 +14,17 @@ jobs:
   branches:
     name: get branch data
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     outputs:
       branches: ${{ steps.branches.outputs.branches }}
 
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Checkout
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           fetch-depth: 0
           ref: ${{ github.event.inputs.ref }}
@@ -40,7 +41,7 @@ jobs:
       matrix:
         branch: ${{ fromJson(needs.branches.outputs.branches) }}
     steps:
-    - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+    - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
       with:
         egress-policy: audit
 
@@ -48,20 +49,20 @@ jobs:
       # from running: we can create a PR but the tests won't run :/
     - name: Generate token
       id: generate_token
-      uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
+      uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
       with:
         app-id: ${{ secrets.APP_ID }}
         private-key: ${{ secrets.PRIVATE_KEY }}
         owner: ${{ github.repository_owner }}
 
-    - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
       with:
         token: ${{ steps.generate_token.outputs.token }}
         ref: ${{ matrix.branch }}
         fetch-depth: 0
 
     - name: Setup Go
-      uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
+      uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
       with:
         go-version-file: go.mod
 

+ 3 - 3
.github/workflows/zizmor.yml

@@ -24,7 +24,7 @@ jobs:
     outputs:
       noop: ${{ steps.noop.outputs.should_skip }}
     steps:
-      - uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
+      - uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
         with:
           egress-policy: audit
       - name: Detect No-op Changes
@@ -45,12 +45,12 @@ jobs:
       security-events: write
     steps:
       - name: Checkout repository
-        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
         with:
           persist-credentials: false
 
       - name: Run zizmor 🌈
-        uses: zizmorcore/zizmor-action@e673c3917a1aef3c65c972347ed84ccd013ecda4 # v0.2.0
+        uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
         with:
           inputs: |
             .github/

+ 8 - 0
.golangci.yaml

@@ -125,7 +125,15 @@ issues:
   max-same-issues: 0
 
 formatters:
+  enable:
+    - gci
+    - gofmt
+    - goimports
+    - golines
   settings:
+    goimports:
+      local-prefixes:
+        - github.com/external-secrets/external-secrets
     golines:
       # Target maximum line length.
       # Default: 100

+ 2 - 0
ADOPTERS.md

@@ -17,6 +17,7 @@
 - [Heureka Group](https://heureka.group)
 - [Hostinger](https://www.hostinger.com/)
 - [K8S Website Infra](https://k8s.io/)
+- [Loblaw](https://www.loblaw.ca/en/digital-and-technology/)
 - [Mercedes-Benz Tech Innovation](https://www.mercedes-benz-techinnovation.com/)
 - [Mixpanel](https://mixpanel.com)
 - [OpenClassrooms](https://openclassrooms.com)
@@ -31,6 +32,7 @@
 - [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift)
 - [SAP](https://www.sap.com/)
 - [Skeeled](https://www.skeeled.com/)
+- [Topicus.Education](https://topicus.nl/en/sectors/education)
 - [Made People](https://madepeople.se/)
 - [Voiceflow](https://www.voiceflow.com/)
 - [VMware Tanzu](https://tanzu.vmware.com/)

+ 0 - 2
CODEOWNERS.md

@@ -21,7 +21,6 @@ pkg/controllers/              @external-secrets/core-reviewers
 # --- Providers ---
 pkg/provider/                 @external-secrets/providers-reviewers
 pkg/provider/akeyless/        @external-secrets/provider-akeyless-reviewers
-pkg/provider/alibaba/         @external-secrets/provider-alibaba-reviewers
 pkg/provider/aws/             @external-secrets/provider-aws-reviewers
 pkg/provider/azure/           @external-secrets/provider-azure-reviewers
 pkg/provider/beyondtrust/     @external-secrets/provider-beyondtrust-reviewers
@@ -30,7 +29,6 @@ pkg/provider/chef/            @external-secrets/provider-chef-reviewers
 pkg/provider/cloudru/         @external-secrets/provider-cloudru-reviewers
 pkg/provider/conjur/          @external-secrets/provider-conjur-reviewers
 pkg/provider/delinea/         @external-secrets/provider-delinea-reviewers
-pkg/provider/device42/        @external-secrets/provider-device42-reviewers
 pkg/provider/doppler/         @external-secrets/provider-doppler-reviewers
 pkg/provider/fake/            @external-secrets/provider-fake-reviewers
 pkg/provider/fortanix/        @external-secrets/provider-fortanix-reviewers

+ 1 - 1
Dockerfile

@@ -1,4 +1,4 @@
-FROM gcr.io/distroless/static@sha256:87bce11be0af225e4ca761c40babb06d6d559f5767fbf7dc3c47f0f1a466b92c
+FROM gcr.io/distroless/static@sha256:28efbe90d0b2f2a3ee465cc5b44f3f2cf5533514cf4d51447a977a5dc8e526d0
 
 # Add metadata
 LABEL maintainer="cncf-externalsecretsop-maintainers@lists.cncf.io" \

+ 3 - 6
Dockerfile.standalone

@@ -1,6 +1,6 @@
 # This version of Dockerfile is for building without external dependencies.
 # Build a multi-platform image e.g. `docker buildx build --push --platform linux/arm64,linux/amd64 --tag external-secrets:dev --file Dockerfile.standalone .`
-FROM golang:1.25.3-alpine@sha256:aee43c3ccbf24fdffb7295693b6e33b21e01baec1b2a55acc351fde345e9ec34 AS builder
+FROM golang:1.25.7-alpine@sha256:f6751d823c26342f9506c03797d2527668d095b0a15f1862cddb4d927a7a4ced AS builder
 # Add metadata
 LABEL maintainer="cncf-externalsecretsop-maintainers@lists.cncf.io" \
       description="External Secrets Operator is a Kubernetes operator that integrates external secret management systems"
@@ -8,14 +8,11 @@ ARG TARGETOS
 ARG TARGETARCH
 ENV CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH}
 WORKDIR /app
-# Avoid invalidating the `go mod download` cache when only code has changed.
-COPY go.mod go.sum /app/
-RUN go mod download
 COPY . /app/
+RUN go mod download
 RUN go build -o external-secrets main.go
 
-
-FROM gcr.io/distroless/static@sha256:87bce11be0af225e4ca761c40babb06d6d559f5767fbf7dc3c47f0f1a466b92c AS app
+FROM gcr.io/distroless/static@sha256:28efbe90d0b2f2a3ee465cc5b44f3f2cf5533514cf4d51447a977a5dc8e526d0 AS app
 COPY --from=builder /app/external-secrets /bin/external-secrets
 
 # Run as UID for nobody

+ 8 - 11
Dockerfile.ubi

@@ -1,4 +1,4 @@
-FROM registry.access.redhat.com/ubi9/ubi@sha256:dec374e05cc13ebbc0975c9f521f3db6942d27f8ccdf06b180160490eef8bdbc AS minimal-ubi
+FROM registry.access.redhat.com/ubi9/ubi@sha256:cecb1cde7bda7c8165ae27841c2335667f8a3665a349c0d051329c61660a496c AS minimal-ubi
 
 # Add metadata
 LABEL maintainer="cncf-externalsecretsop-maintainers@lists.cncf.io" \
@@ -6,7 +6,7 @@ LABEL maintainer="cncf-externalsecretsop-maintainers@lists.cncf.io" \
 
 ARG TARGETOS
 ARG TARGETARCH
-RUN dnf update -y --allowerasing && dnf install -y binutils
+RUN dnf update -y --allowerasing
 # prep target rootfs for scratch container
 WORKDIR /
 RUN mkdir /image && \
@@ -16,15 +16,12 @@ RUN mkdir /image && \
 	ln -s usr/lib /image/lib && \
 	mkdir -p /image/{usr/bin,usr/lib64,usr/lib,root,home,proc,etc,sys,var,dev}
 
-COPY ubi-build-files-${TARGETARCH}.txt /tmp
-# Copy all the required files from the base UBI image into the image directory
-# As the go binary is not statically compiled this includes everything needed for CGO to work, cacerts, tzdata and RH release files
-RUN tar cf /tmp/files.tar -T /tmp/ubi-build-files-${TARGETARCH}.txt && tar xf /tmp/files.tar -C /image/ \
-  && rpm --root /image --initdb \
-  && PACKAGES=$(rpm -qf $(cat /tmp/ubi-build-files-${TARGETARCH}.txt) | grep -v "is not owned by any package" | sort -u) \
-  && echo dnf install -y 'dnf-command(download)' \
-  && dnf download --destdir / ${PACKAGES} \
-  && rpm --root /image -ivh --justdb --nodeps `for i in ${PACKAGES}; do echo $i.rpm; done`
+# Install required packages directly into /image root - more robust under QEMU emulation
+RUN rpm --root /image --initdb \
+  && dnf install -y --installroot=/image --releasever=9 --setopt=install_weak_deps=false --nodocs \
+     glibc tzdata ca-certificates \
+  && dnf clean all --installroot=/image \
+  && rm -rf /image/var/cache/dnf /image/var/log/*
 
 FROM scratch
 # Copy all required files + rpm database so the image is scannable

+ 40 - 51
Makefile

@@ -1,5 +1,5 @@
 # set the shell to bash always
-SHELL         := /bin/bash
+SHELL         := /usr/bin/env bash
 
 # set make and shell flags to exit on errors
 MAKEFLAGS     += --warn-undefined-variables
@@ -108,7 +108,7 @@ go-work:
 .PHONY: test
 test: generate envtest go-work ## Run tests
 	@$(INFO) go test unit-tests
-	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(KUBERNETES_VERSION) -p path --bin-dir $(LOCALBIN))" go test work -v -race -coverprofile cover.out
+	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(KUBERNETES_VERSION) -p path --bin-dir $(LOCALBIN))" go test -tags $(PROVIDER) work -v -race -coverprofile cover.out
 	@$(OK) go test unit-tests
 
 .PHONY: test.e2e
@@ -138,54 +138,48 @@ test.crds.update: cty crds.generate.tests ## Update the snapshots used by the CR
 .PHONY: build
 build: $(addprefix build-,$(ARCH)) ## Build binary
 
+PROVIDER ?= all_providers
 .PHONY: build-%
 build-%: generate ## Build binary for the specified arch
 	@$(INFO) go build $*
 	$(BUILD_ARGS) GOOS=linux GOARCH=$* \
-		go build -o '$(OUTPUT_DIR)/external-secrets-linux-$*' main.go
+		go build -tags $(PROVIDER) -o '$(OUTPUT_DIR)/external-secrets-linux-$*' main.go
 	@$(OK) go build $*
 
-lint: golangci-lint ## Run golangci-lint (set LINT_TARGET to run on specific module)
+lint: golangci-lint ## Run golangci-lint (set LINT_TARGET to run on specific module, LINT_JOBS for parallel jobs)
 	@if [ -n "$(LINT_TARGET)" ]; then \
 		$(INFO) Running golangci-lint on $(LINT_TARGET); \
 		(cd $(LINT_TARGET) && $(GOLANGCI_LINT) run ./...) || exit 1; \
 		$(OK) Finished linting $(LINT_TARGET); \
 	else \
-		$(INFO) Running golangci-lint on all modules; \
-		FAILED=0; \
-		MODULES=$$(find . -name go.mod -not -path "*/vendor/*" -not -path "*/e2e/*" -not -path "*/node_modules/*" -exec dirname {} \;); \
-		for module in $$MODULES; do \
+		$(INFO) Running golangci-lint on all modules in parallel; \
+		JOBS=$${LINT_JOBS:-20}; \
+		TMPDIR=$$(mktemp -d); \
+		GOLANGCI=$(GOLANGCI_LINT); \
+		trap "rm -rf $$TMPDIR" EXIT; \
+		export TMPDIR GOLANGCI; \
+		find . -name go.mod -not -path "*/vendor/*" -not -path "*/e2e/*" -not -path "*/node_modules/*" -exec dirname {} \; | \
+		xargs -n 1 -P $$JOBS sh -c ' \
+			module="$$0"; \
+			name=$$(echo "$$module" | sed "s/[\/\.]/_/g"); \
 			echo "Linting $$module"; \
-			(cd $$module && $(GOLANGCI_LINT) run ./...) || FAILED=$$((FAILED + 1)); \
-		done; \
+			if (cd "$$module" && $$GOLANGCI run ./... 2>&1); then \
+				echo "✓ $$module" > "$$TMPDIR/$$name.success"; \
+			else \
+				echo "✗ $$module" > "$$TMPDIR/$$name.failed"; \
+				exit 1; \
+			fi \
+		'; \
+		FAILED=$$(find $$TMPDIR -name "*.failed" 2>/dev/null | wc -l | tr -d " "); \
+		SUCCESS=$$(find $$TMPDIR -name "*.success" 2>/dev/null | wc -l | tr -d " "); \
+		echo "Results: $$SUCCESS passed, $$FAILED failed"; \
 		if [ $$FAILED -ne 0 ]; then \
+			echo "Failed modules:"; \
+			cat $$TMPDIR/*.failed 2>/dev/null || true; \
 			$(ERR) Linting failed in $$FAILED module\(s\); \
 			exit 1; \
 		fi; \
-		$(OK) Finished linting; \
-	fi
-
-fmt: golangci-lint ## Ensure consistent code style (set LINT_TARGET to run on specific module)
-	@go mod tidy
-	@cd e2e/ && go mod tidy
-	@go fmt ./...
-	@if [ -n "$(LINT_TARGET)" ]; then \
-		$(INFO) Running golangci-lint --fix on $(LINT_TARGET); \
-		(cd $(LINT_TARGET) && $(GOLANGCI_LINT) run --fix ./...); \
-		$(OK) Finished fixing $(LINT_TARGET); \
-	else \
-		$(INFO) Running golangci-lint --fix on all modules; \
-		FAILED=0; \
-		MODULES=$$(find . -name go.mod -not -path "*/vendor/*" -not -path "*/e2e/*" -not -path "*/node_modules/*" -exec dirname {} \;); \
-		for module in $$MODULES; do \
-			echo "Fixing $$module"; \
-			(cd $$module && $(GOLANGCI_LINT) run --fix ./...) || FAILED=$$((FAILED + 1)); \
-		done; \
-		if [ $$FAILED -ne 0 ]; then \
-			$(ERR) Fixing failed in $$FAILED module\(s\); \
-			exit 1; \
-		fi; \
-		$(OK) Ensured consistent code style; \
+		$(OK) Finished linting all modules; \
 	fi
 
 generate: ## Generate code and crds
@@ -198,7 +192,7 @@ generate: ## Generate code and crds
 # This is for running out-of-cluster locally, and is for convenience.
 # For more control, try running the binary directly with different arguments.
 run: generate ## Run app locally (without a k8s cluster)
-	go run ./main.go
+	go run -tags $(PROVIDER) ./main.go
 
 manifests: helm.generate ## Generate manifests from helm chart
 	mkdir -p $(OUTPUT_DIR)/deploy/manifests
@@ -223,7 +217,7 @@ tilt-up: tilt manifests ## Generates the local manifests that tilt will use to d
 
 helm.docs: ## Generate helm docs
 	@cd $(HELM_DIR); \
-	$(DOCKER) run --rm -v $(shell pwd)/$(HELM_DIR):/helm-docs -u $(shell id -u) docker.io/jnorwood/helm-docs:v1.7.0
+	$(DOCKER) run --rm -v $(shell pwd)/$(HELM_DIR):/helm-docs -u $(shell id -u) docker.io/jnorwood/helm-docs:v1.14.2
 
 HELM_VERSION ?= $(shell helm show chart $(HELM_DIR) | grep '^version:' | sed 's/version: //g')
 
@@ -292,6 +286,7 @@ helm.update.appversion:
 
 # ====================================================================================
 # Documentation
+
 .PHONY: docs
 docs: generate ## Generate docs
 	$(MAKE) -C ./hack/api-docs build
@@ -353,11 +348,11 @@ SOURCE_TAG ?= $(VERSION)$(TAG_SUFFIX)
 docker.promote: ## Promote the docker image to the registry
 	@$(INFO) promoting $(SOURCE_TAG) to $(RELEASE_TAG)
 	$(DOCKER) manifest inspect --verbose $(IMAGE_NAME):$(SOURCE_TAG) > .tagmanifest
-	for digest in $$(jq -r 'if type=="array" then .[].Descriptor.digest else .Descriptor.digest end' < .tagmanifest); do \
+	for digest in $$(jq -r 'if type=="array" then .[] | select(.Descriptor.platform.architecture != "unknown") | .Descriptor.digest else .Descriptor.digest end' < .tagmanifest); do \
 		$(DOCKER) pull $(IMAGE_NAME)@$$digest; \
 	done
 	$(DOCKER) manifest create $(IMAGE_NAME):$(RELEASE_TAG) \
-		$$(jq -j '"--amend $(IMAGE_NAME)@" + if type=="array" then .[].Descriptor.digest else .Descriptor.digest end + " "' < .tagmanifest)
+		$$(jq -j 'if type=="array" then [.[] | select(.Descriptor.platform.architecture != "unknown")] | map("--amend $(IMAGE_NAME)@" + .Descriptor.digest) | join(" ") else "--amend $(IMAGE_NAME)@" + .Descriptor.digest end' < .tagmanifest)
 	$(DOCKER) manifest push $(IMAGE_NAME):$(RELEASE_TAG)
 	@$(OK) $(DOCKER) push $(RELEASE_TAG) \
 
@@ -409,22 +404,16 @@ clean:  ## Clean bins
 # ====================================================================================
 # Build Dependencies
 
-ifeq ($(OS),Windows_NT)     # is Windows_NT on XP, 2000, 7, Vista, 10...
-    detected_OS := windows
-    real_OS := windows
-    arch := x86_64
-else
-    detected_OS := $(shell uname -s)
-    real_OS := $(detected_OS)
-    arch := $(shell uname -m)
-    ifeq ($(detected_OS),Darwin)
+detected_OS := $(shell uname -s)
+real_OS := $(detected_OS)
+arch := $(shell uname -m)
+ifeq ($(detected_OS),Darwin)
         detected_OS := mac
         real_OS := darwin
-    endif
-    ifeq ($(detected_OS),Linux)
+endif
+ifeq ($(detected_OS),Linux)
         detected_OS := linux
-        real_OS := linux
-    endif
+	real_OS := linux
 endif
 
 ## Location to install dependencies to

+ 4 - 2
Tiltfile

@@ -73,9 +73,11 @@ gcflags = ''
 if settings.get('debug').get('enabled'):
     gcflags = '-N -l'
 
+buildtags = settings.get('buildtags', 'all_providers')
+
 local_resource(
     'external-secret-binary',
-    "CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -gcflags '{gcflags}' -v -o bin/external-secrets ./".format(gcflags=gcflags),
+    "CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -tags '{buildtags}' -gcflags '{gcflags}' -v -o bin/external-secrets ./".format(buildtags=buildtags, gcflags=gcflags),
     deps = [
         "main.go",
         "go.mod",
@@ -102,7 +104,7 @@ if settings.get('debug').get('enabled'):
     dockerfile = 'tilt.debug.dockerfile'
 
 docker_build_with_restart(
-    'oci.external-secrets.io/external-secrets/external-secrets',
+    'ghcr.io/external-secrets/external-secrets',
     '.',
     dockerfile = dockerfile,
     entrypoint = entrypoint,

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

@@ -519,9 +519,9 @@ type ExternalSecretSpec struct {
 	// RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
 	// specified as Golang Duration strings.
 	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-	// Example values: "1h", "2h30m", "10s"
-	// May be set to zero to fetch and create it once. Defaults to 1h.
-	// +kubebuilder:default="1h"
+	// Example values: "1h0m0s", "2h30m0s", "10m0s"
+	// May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
+	// +kubebuilder:default="1h0m0s"
 	RefreshInterval *metav1.Duration `json:"refreshInterval,omitempty"`
 
 	// Data defines the connection between the Kubernetes Secret keys and the Provider data

+ 10 - 12
apis/externalsecrets/v1/externalsecret_validator.go

@@ -21,35 +21,33 @@ import (
 	"errors"
 	"fmt"
 
-	"k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 )
 
 // Ensures ExternalSecretValidator implements the admission.CustomValidator interface correctly.
-var _ admission.CustomValidator = &ExternalSecretValidator{}
+var _ admission.Validator[*ExternalSecret] = &ExternalSecretValidator{}
 
 // ExternalSecretValidator implements a validating webhook for ExternalSecrets.
 type ExternalSecretValidator struct{}
 
-// ValidateCreate is called on creation of ExternalSecret resource object.
-func (esv *ExternalSecretValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
+// ValidateCreate validates the creation of an external secret object.
+func (in *ExternalSecretValidator) ValidateCreate(_ context.Context, obj *ExternalSecret) (warnings admission.Warnings, err error) {
 	return validateExternalSecret(obj)
 }
 
-// ValidateUpdate is called when updating an ExternalSecret resource object.
-func (esv *ExternalSecretValidator) ValidateUpdate(_ context.Context, _, newObj runtime.Object) (admission.Warnings, error) {
+// ValidateUpdate validates the update of an external secret object.
+func (in *ExternalSecretValidator) ValidateUpdate(_ context.Context, _, newObj *ExternalSecret) (warnings admission.Warnings, err error) {
 	return validateExternalSecret(newObj)
 }
 
-// ValidateDelete is called when deleting an ExternalSecret resource object.
-func (esv *ExternalSecretValidator) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
+// ValidateDelete validates the deletion of an external secret object.
+func (in *ExternalSecretValidator) ValidateDelete(_ context.Context, _ *ExternalSecret) (warnings admission.Warnings, err error) {
 	return nil, nil
 }
 
-func validateExternalSecret(obj runtime.Object) (admission.Warnings, error) {
-	es, ok := obj.(*ExternalSecret)
-	if !ok {
-		return nil, errors.New("unexpected type")
+func validateExternalSecret(es *ExternalSecret) (admission.Warnings, error) {
+	if es == nil {
+		return nil, errors.New("external secret cannot be nil during validation")
 	}
 
 	var errs error

+ 2 - 4
apis/externalsecrets/v1/externalsecret_validator_test.go

@@ -18,8 +18,6 @@ package v1
 
 import (
 	"testing"
-
-	"k8s.io/apimachinery/pkg/runtime"
 )
 
 const (
@@ -29,13 +27,13 @@ const (
 func TestValidateExternalSecret(t *testing.T) {
 	tests := []struct {
 		name        string
-		obj         runtime.Object
+		obj         *ExternalSecret
 		expectedErr string
 	}{
 		{
 			name:        "nil",
 			obj:         nil,
-			expectedErr: "unexpected type",
+			expectedErr: "external secret cannot be nil during validation",
 		},
 		{
 			name: "deletion policy delete",

+ 1 - 2
apis/externalsecrets/v1/externalsecret_webhook.go

@@ -22,8 +22,7 @@ import (
 
 // SetupWebhookWithManager sets up the webhook for ExternalSecret.
 func (es *ExternalSecret) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(es).
+	return ctrl.NewWebhookManagedBy(mgr, es).
 		WithValidator(&ExternalSecretValidator{}).
 		Complete()
 }

+ 1 - 1
apis/externalsecrets/v1/fakes/pushremoteref.go

@@ -20,7 +20,7 @@ package fakes
 import (
 	"sync"
 
-	"github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
+	v1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
 )
 
 // PushRemoteRef is a fake implementation of the PushRemoteRef interface for testing.

+ 4 - 3
apis/externalsecrets/v1/provider_schema_maintenance.go

@@ -22,12 +22,13 @@ import (
 )
 
 // MaintenanceStatus defines a type for different maintenance states of a provider schema.
-type MaintenanceStatus bool
+type MaintenanceStatus string
 
 // These are the defined maintenance states for a provider schema.
 const (
-	MaintenanceStatusMaintained    MaintenanceStatus = true
-	MaintenanceStatusNotMaintained MaintenanceStatus = false
+	MaintenanceStatusMaintained    MaintenanceStatus = "Maintained"
+	MaintenanceStatusNotMaintained MaintenanceStatus = "NotMaintained"
+	MaintenanceStatusDeprecated    MaintenanceStatus = "Deprecated"
 )
 
 var maintenance map[string]MaintenanceStatus

+ 11 - 0
apis/externalsecrets/v1/secretsstore_infisical_types.go

@@ -164,4 +164,15 @@ type InfisicalProvider struct {
 	// +kubebuilder:default="https://app.infisical.com/api"
 	// +optional
 	HostAPI string `json:"hostAPI,omitempty"`
+
+	// CABundle is a PEM-encoded CA certificate bundle used to validate
+	// the Infisical server's TLS certificate. Mutually exclusive with CAProvider.
+	// +optional
+	CABundle []byte `json:"caBundle,omitempty"`
+
+	// CAProvider is a reference to a Secret or ConfigMap that contains a CA certificate.
+	// The certificate is used to validate the Infisical server's TLS certificate.
+	// Mutually exclusive with CABundle.
+	// +optional
+	CAProvider *CAProvider `json:"caProvider,omitempty"`
 }

+ 10 - 1
apis/externalsecrets/v1/secretsstore_secretserver_types.go

@@ -34,7 +34,6 @@ type SecretServerProviderRef struct {
 // SecretServerProvider provides access to authenticate to a secrets provider server.
 // See: https://github.com/DelineaXPM/tss-sdk-go/blob/main/server/server.go.
 type SecretServerProvider struct {
-
 	// Username is the secret server account username.
 	// +required
 	Username *SecretServerProviderRef `json:"username"`
@@ -51,4 +50,14 @@ type SecretServerProvider struct {
 	// URL to your secret server installation
 	// +required
 	ServerURL string `json:"serverURL"`
+
+	// PEM/base64 encoded CA bundle used to validate Secret ServerURL. Only used
+	// if the ServerURL URL is using HTTPS protocol. If not set the system root certificates
+	// are used to validate the TLS connection.
+	// +optional
+	CABundle []byte `json:"caBundle,omitempty"`
+
+	// The provider for the CA bundle to use to validate Secret ServerURL certificate.
+	// +optional
+	CAProvider *CAProvider `json:"caProvider,omitempty"`
 }

+ 0 - 52
apis/externalsecrets/v1/secretstore_alibaba_types.go

@@ -1,52 +0,0 @@
-/*
-Copyright © 2025 ESO Maintainer Team
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
-)
-
-// AlibabaAuth contains a secretRef for credentials.
-type AlibabaAuth struct {
-	// +optional
-	SecretRef *AlibabaAuthSecretRef `json:"secretRef,omitempty"`
-	// +optional
-	RRSAAuth *AlibabaRRSAAuth `json:"rrsa,omitempty"`
-}
-
-// AlibabaAuthSecretRef holds secret references for Alibaba credentials.
-type AlibabaAuthSecretRef struct {
-	// The AccessKeyID is used for authentication
-	AccessKeyID esmeta.SecretKeySelector `json:"accessKeyIDSecretRef"`
-	// The AccessKeySecret is used for authentication
-	AccessKeySecret esmeta.SecretKeySelector `json:"accessKeySecretSecretRef"`
-}
-
-// AlibabaRRSAAuth authenticates against Alibaba using RRSA.
-type AlibabaRRSAAuth struct {
-	OIDCProviderARN   string `json:"oidcProviderArn"`
-	OIDCTokenFilePath string `json:"oidcTokenFilePath"`
-	RoleARN           string `json:"roleArn"`
-	SessionName       string `json:"sessionName"`
-}
-
-// AlibabaProvider configures a store to sync secrets using the Alibaba Secret Manager provider.
-type AlibabaProvider struct {
-	Auth AlibabaAuth `json:"auth"`
-	// Alibaba Region to be used for the provider
-	RegionID string `json:"regionID"`
-}

+ 4 - 1
apis/externalsecrets/v1/secretstore_azurekv_types.go

@@ -118,8 +118,11 @@ type AzureKVProvider struct {
 	// +kubebuilder:default=false
 	UseAzureSDK *bool `json:"useAzureSDK,omitempty"`
 
-	// CustomCloudConfig defines custom Azure Stack Hub or Azure Stack Edge endpoints.
+	// CustomCloudConfig defines custom Azure endpoints for non-standard clouds.
 	// Required when EnvironmentType is AzureStackCloud.
+	// Optional for other environment types - useful for Azure China when using Workload Identity
+	// with AKS, where the OIDC issuer (login.partner.microsoftonline.cn) differs from the
+	// standard China Cloud endpoint (login.chinacloudapi.cn).
 	// IMPORTANT: This feature REQUIRES UseAzureSDK to be set to true. Custom cloud
 	// configuration is not supported with the legacy go-autorest SDK.
 	// +optional

+ 49 - 0
apis/externalsecrets/v1/secretstore_barbican_types.go

@@ -0,0 +1,49 @@
+/*
+Copyright © 2025 ESO Maintainer Team
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1
+
+import (
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// BarbicanProviderUsernameRef defines a reference to a secret containing username for the Barbican provider.
+// +kubebuilder:validation:MinProperties=1
+// +kubebuilder:validation:MaxProperties=1
+type BarbicanProviderUsernameRef struct {
+	Value     string                    `json:"value,omitempty"`
+	SecretRef *esmeta.SecretKeySelector `json:"secretRef,omitempty"`
+}
+
+// BarbicanProviderPasswordRef defines a reference to a secret containing password for the Barbican provider.
+type BarbicanProviderPasswordRef struct {
+	SecretRef *esmeta.SecretKeySelector `json:"secretRef"`
+}
+
+// BarbicanProvider setup a store to sync secrets with barbican.
+type BarbicanProvider struct {
+	AuthURL    string       `json:"authURL,omitempty"`
+	TenantName string       `json:"tenantName,omitempty"`
+	DomainName string       `json:"domainName,omitempty"`
+	Region     string       `json:"region,omitempty"`
+	Auth       BarbicanAuth `json:"auth"`
+}
+
+// BarbicanAuth contains the authentication information for Barbican.
+type BarbicanAuth struct {
+	Username BarbicanProviderUsernameRef `json:"username"`
+	Password BarbicanProviderPasswordRef `json:"password"`
+}

+ 4 - 0
apis/externalsecrets/v1/secretstore_beyondtrust_types.go

@@ -55,6 +55,10 @@ type BeyondtrustServer struct {
 	RetrievalType string `json:"retrievalType,omitempty"`
 	// A character that separates the folder names.
 	Separator string `json:"separator,omitempty"`
+	// When true, the response includes the decrypted password. When false, the password field is omitted. This option only applies to the SECRET retrieval type. Default: true.
+	// +optional
+	// +kubebuilder:default=true
+	Decrypt bool `json:"decrypt,omitempty"`
 	// +required - Indicates whether to verify the certificate authority on the Secrets Safe instance. Warning - false is insecure, instructs the BT provider not to verify the certificate authority.
 	VerifyCA bool `json:"verifyCA"`
 	// Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.

+ 0 - 42
apis/externalsecrets/v1/secretstore_device42_types.go

@@ -1,42 +0,0 @@
-/*
-Copyright © 2025 ESO Maintainer Team
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    https://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1
-
-import (
-	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
-)
-
-// Device42Provider configures a store to sync secrets with a Device42 instance.
-type Device42Provider struct {
-	// URL configures the Device42 instance URL.
-	Host string `json:"host"`
-
-	// Auth configures how secret-manager authenticates with a Device42 instance.
-	Auth Device42Auth `json:"auth"`
-}
-
-// Device42Auth defines the authentication method for the Device42 provider.
-type Device42Auth struct {
-	SecretRef Device42SecretRef `json:"secretRef"`
-}
-
-// Device42SecretRef contains the secret reference for accessing the Device42 instance.
-type Device42SecretRef struct {
-	// Username / Password is used for authentication.
-	// +optional
-	Credentials esmeta.SecretKeySelector `json:"credentials,omitempty"`
-}

+ 25 - 2
apis/externalsecrets/v1/secretstore_doppler_types.go

@@ -22,9 +22,17 @@ import (
 
 // Set DOPPLER_BASE_URL and DOPPLER_VERIFY_TLS environment variables to override defaults
 
-// DopplerAuth defines the authentication method for the Doppler provider.
+// DopplerAuth configures authentication with the Doppler API.
+// Exactly one of secretRef or oidcConfig must be specified.
+// +kubebuilder:validation:XValidation:rule="(has(self.secretRef) && !has(self.oidcConfig)) || (!has(self.secretRef) && has(self.oidcConfig))",message="Exactly one of 'secretRef' or 'oidcConfig' must be specified"
 type DopplerAuth struct {
-	SecretRef DopplerAuthSecretRef `json:"secretRef"`
+	// SecretRef authenticates using a Doppler service token stored in a Kubernetes Secret.
+	// +optional
+	SecretRef *DopplerAuthSecretRef `json:"secretRef,omitempty"`
+
+	// OIDCConfig authenticates using Kubernetes ServiceAccount tokens via OIDC.
+	// +optional
+	OIDCConfig *DopplerOIDCAuth `json:"oidcConfig,omitempty"`
 }
 
 // DopplerAuthSecretRef contains the secret reference for accessing the Doppler API.
@@ -35,6 +43,21 @@ type DopplerAuthSecretRef struct {
 	DopplerToken esmeta.SecretKeySelector `json:"dopplerToken"`
 }
 
+// DopplerOIDCAuth configures OIDC authentication with Doppler using Kubernetes ServiceAccount tokens.
+type DopplerOIDCAuth struct {
+	// Identity is the Doppler Service Account Identity ID configured for OIDC authentication.
+	Identity string `json:"identity"`
+
+	// ServiceAccountRef specifies the Kubernetes ServiceAccount to use for authentication.
+	ServiceAccountRef esmeta.ServiceAccountSelector `json:"serviceAccountRef"`
+
+	// ExpirationSeconds sets the ServiceAccount token validity duration.
+	// Defaults to 10 minutes.
+	// +kubebuilder:default=600
+	// +optional
+	ExpirationSeconds *int64 `json:"expirationSeconds,omitempty"`
+}
+
 // DopplerProvider configures a store to sync secrets using the Doppler provider.
 // Project and Config are required if not using a Service Token.
 type DopplerProvider struct {

+ 56 - 0
apis/externalsecrets/v1/secretstore_dvls_types.go

@@ -0,0 +1,56 @@
+/*
+Copyright © 2025 ESO Maintainer Team
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1
+
+import (
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+)
+
+// DVLSProvider configures a store to sync secrets using Devolutions Server.
+type DVLSProvider struct {
+	// ServerURL is the DVLS instance URL (e.g., https://dvls.example.com).
+	// +kubebuilder:validation:Required
+	ServerURL string `json:"serverUrl"`
+
+	// Insecure allows connecting to DVLS over plain HTTP.
+	// This is NOT RECOMMENDED for production use.
+	// Set to true only if you understand the security implications.
+	// +optional
+	Insecure bool `json:"insecure,omitempty"`
+
+	// Auth defines the authentication method to use.
+	// +kubebuilder:validation:Required
+	Auth DVLSAuth `json:"auth"`
+}
+
+// DVLSAuth defines the authentication method for the DVLS provider.
+type DVLSAuth struct {
+	// SecretRef contains the Application ID and Application Secret for authentication.
+	// +kubebuilder:validation:Required
+	SecretRef DVLSAuthSecretRef `json:"secretRef"`
+}
+
+// DVLSAuthSecretRef defines the secret references for DVLS authentication credentials.
+type DVLSAuthSecretRef struct {
+	// AppID is the reference to the secret containing the Application ID.
+	// +kubebuilder:validation:Required
+	AppID esmeta.SecretKeySelector `json:"appId"`
+
+	// AppSecret is the reference to the secret containing the Application Secret.
+	// +kubebuilder:validation:Required
+	AppSecret esmeta.SecretKeySelector `json:"appSecret"`
+}

+ 3 - 0
apis/externalsecrets/v1/secretstore_ibm_types.go

@@ -42,6 +42,9 @@ type IBMAuth struct {
 type IBMAuthSecretRef struct {
 	// The SecretAccessKey is used for authentication
 	SecretAPIKey esmeta.SecretKeySelector `json:"secretApiKeySecretRef,omitempty"`
+
+	// The IAM endpoint used to obain a token
+	IAMEndpoint string `json:"iamEndpoint,omitempty"`
 }
 
 // IBMAuthContainerAuth defines container-based authentication with IAM Trusted Profile.

+ 62 - 0
apis/externalsecrets/v1/secretstore_nebius_types.go

@@ -0,0 +1,62 @@
+// /*
+// Copyright © 2025 ESO Maintainer Team
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// */
+
+package v1
+
+import esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+
+// NebiusAuth defines the authentication method for the Nebius provider.
+// +kubebuilder:validation:XValidation:rule="has(self.serviceAccountCredsSecretRef) || has(self.tokenSecretRef)",message="either serviceAccountCredsSecretRef or tokenSecretRef must be set"
+type NebiusAuth struct {
+	// ServiceAccountCreds references a Kubernetes Secret key that contains a JSON
+	// document with service account credentials used to get an IAM token.
+	//
+	// Expected JSON structure:
+	// {
+	//   "subject-credentials": {
+	//     "alg": "RS256",
+	//     "private-key": "-----BEGIN PRIVATE KEY-----\n<private-key>\n-----END PRIVATE KEY-----\n",
+	//     "kid": "<public-key-id>",
+	//     "iss": "<issuer-service-account-id>",
+	//     "sub": "<subject-service-account-id>"
+	//   }
+	// }
+	// +optional
+	ServiceAccountCreds esmeta.SecretKeySelector `json:"serviceAccountCredsSecretRef,omitempty"`
+	// Token authenticates with Nebius Mysterybox by presenting a token.
+	// +optional
+	Token esmeta.SecretKeySelector `json:"tokenSecretRef,omitempty"`
+}
+
+// NebiusCAProvider The provider for the CA bundle to use to validate Nebius server certificate.
+type NebiusCAProvider struct {
+	// +optional
+	Certificate esmeta.SecretKeySelector `json:"certSecretRef,omitempty"`
+}
+
+// NebiusMysteryboxProvider Configures a store to sync secrets using the Nebius Mysterybox provider.
+type NebiusMysteryboxProvider struct {
+
+	// NebiusMysterybox API endpoint
+	APIDomain string `json:"apiDomain"`
+
+	// Auth defines parameters to authenticate in MysteryBox
+	Auth NebiusAuth `json:"auth"`
+
+	// The provider for the CA bundle to use to validate NebiusMysterybox server certificate.
+	// +optional
+	CAProvider *NebiusCAProvider `json:"caProvider,omitempty"`
+}

+ 25 - 0
apis/externalsecrets/v1/secretstore_onepassword_sdk_types.go

@@ -17,6 +17,8 @@ limitations under the License.
 package v1
 
 import (
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
 	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
@@ -36,6 +38,22 @@ type IntegrationInfo struct {
 	Version string `json:"version,omitempty"`
 }
 
+// CacheConfig configures client-side caching for read operations.
+type CacheConfig struct {
+	// TTL is the time-to-live for cached secrets.
+	// Format: duration string (e.g., "5m", "1h", "30s")
+	// +kubebuilder:default="5m"
+	// +optional
+	TTL metav1.Duration `json:"ttl,omitempty"`
+
+	// MaxSize is the maximum number of secrets to cache.
+	// When the cache is full, least-recently-used entries are evicted.
+	// +kubebuilder:default=100
+	// +kubebuilder:validation:Minimum=1
+	// +optional
+	MaxSize int `json:"maxSize,omitempty"`
+}
+
 // OnePasswordSDKProvider configures a store to sync secrets using the 1Password sdk.
 type OnePasswordSDKProvider struct {
 	// Vault defines the vault's name or uuid to access. Do NOT add op:// prefix. This will be done automatically.
@@ -46,4 +64,11 @@ type OnePasswordSDKProvider struct {
 	IntegrationInfo *IntegrationInfo `json:"integrationInfo,omitempty"`
 	// Auth defines the information necessary to authenticate against OnePassword API.
 	Auth *OnePasswordSDKAuth `json:"auth"`
+	// Cache configures client-side caching for read operations (GetSecret, GetSecretMap).
+	// When enabled, secrets are cached with the specified TTL.
+	// Write operations (PushSecret, DeleteSecret) automatically invalidate relevant cache entries.
+	// If omitted, caching is disabled (default).
+	// cache: {} is a valid option to set.
+	// +optional
+	Cache *CacheConfig `json:"cache,omitempty"`
 }

+ 17 - 11
apis/externalsecrets/v1/secretstore_types.go

@@ -31,7 +31,7 @@ type SecretStoreSpec struct {
 	// Used to configure the provider. Only one provider may be set
 	Provider *SecretStoreProvider `json:"provider"`
 
-	// Used to configure http retries if failed
+	// Used to configure HTTP retries on failures.
 	// +optional
 	RetrySettings *SecretStoreRetrySettings `json:"retrySettings,omitempty"`
 
@@ -39,7 +39,7 @@ type SecretStoreSpec struct {
 	// +optional
 	RefreshInterval int `json:"refreshInterval,omitempty"`
 
-	// Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
+	// Used to constrain a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore.
 	// +optional
 	Conditions []ClusterSecretStoreCondition `json:"conditions,omitempty"`
 }
@@ -83,7 +83,7 @@ type SecretStoreProvider struct {
 	// +optional
 	BitwardenSecretsManager *BitwardenSecretsManagerProvider `json:"bitwardensecretsmanager,omitempty"`
 
-	// Vault configures this store to sync secrets using Hashi provider
+	// Vault configures this store to sync secrets using the HashiCorp Vault provider.
 	// +optional
 	Vault *VaultProvider `json:"vault,omitempty"`
 
@@ -107,7 +107,7 @@ type SecretStoreProvider struct {
 	// +optional
 	YandexLockbox *YandexLockboxProvider `json:"yandexlockbox,omitempty"`
 
-	// Github configures this store to push GitHub Action secrets using GitHub API provider.
+	// Github configures this store to push GitHub Actions secrets using the GitHub API provider.
 	// Note: This provider only supports write operations (PushSecret) and cannot fetch secrets from GitHub
 	// +optional
 	Github *GithubProvider `json:"github,omitempty"`
@@ -116,10 +116,6 @@ type SecretStoreProvider struct {
 	// +optional
 	Gitlab *GitlabProvider `json:"gitlab,omitempty"`
 
-	// Alibaba configures this store to sync secrets using Alibaba Cloud provider
-	// +optional
-	Alibaba *AlibabaProvider `json:"alibaba,omitempty"`
-
 	// OnePassword configures this store to sync secrets using the 1Password Cloud provider
 	// +optional
 	OnePassword *OnePasswordProvider `json:"onepassword,omitempty"`
@@ -144,7 +140,7 @@ type SecretStoreProvider struct {
 	// +optional
 	Senhasegura *SenhaseguraProvider `json:"senhasegura,omitempty"`
 
-	// Scaleway
+	// Scaleway configures this store to sync secrets using the Scaleway provider.
 	// +optional
 	Scaleway *ScalewayProvider `json:"scaleway,omitempty"`
 
@@ -196,9 +192,9 @@ type SecretStoreProvider struct {
 	// +optional
 	Passbolt *PassboltProvider `json:"passbolt,omitempty"`
 
-	// Device42 configures this store to sync secrets using the Device42 provider
+	// DVLS configures this store to sync secrets using Devolutions Server provider
 	// +optional
-	Device42 *Device42Provider `json:"device42,omitempty"`
+	DVLS *DVLSProvider `json:"dvls,omitempty"`
 
 	// Infisical configures this store to sync secrets using the Infisical provider
 	// +optional
@@ -215,9 +211,18 @@ type SecretStoreProvider struct {
 	// Volcengine configures this store to sync secrets using the Volcengine provider
 	// +optional
 	Volcengine *VolcengineProvider `json:"volcengine,omitempty"`
+
 	// Ngrok configures this store to sync secrets using the ngrok provider.
 	// +optional
 	Ngrok *NgrokProvider `json:"ngrok,omitempty"`
+
+	// Barbican configures this store to sync secrets using the OpenStack Barbican provider
+	// +optional
+	Barbican *BarbicanProvider `json:"barbican,omitempty"`
+
+	// NebiusMysterybox configures this store to sync secrets using NebiusMysterybox provider
+	// +optional
+	NebiusMysterybox *NebiusMysteryboxProvider `json:"nebiusmysterybox,omitempty"`
 }
 
 // CAProviderType defines the type of provider for certificate authority.
@@ -280,6 +285,7 @@ const (
 	ReasonValidationUnknown     = "ValidationUnknown"
 	ReasonStoreValid            = "Valid"
 	StoreUnmaintained           = "StoreUnmaintained"
+	StoreDeprecated             = "StoreDeprecated"
 )
 
 // SecretStoreStatusCondition contains condition information for a SecretStore.

+ 35 - 19
apis/externalsecrets/v1/secretstore_validator.go

@@ -22,41 +22,51 @@ import (
 	"fmt"
 	"regexp"
 
-	"k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 )
 
 // Ensures ExternalSecretValidator implements the admission.CustomValidator interface correctly.
-var _ admission.CustomValidator = &GenericStoreValidator{}
+var _ admission.Validator[*SecretStore] = &GenericStoreValidator{}
+var _ admission.Validator[*ClusterSecretStore] = &GenericClusterStoreValidator{}
 
 const (
-	errInvalidStore       = "invalid store"
 	warnStoreUnmaintained = "store %s isn't currently maintained. Please plan and prepare accordingly."
+	warnStoreDeprecated   = "store %s is deprecated and will stop working on the next major version. Please plan and prepare accordingly."
 )
 
-// GenericStoreValidator implements webhook validation for SecretStore and ClusterSecretStore resources.
+// GenericStoreValidator implements webhook validation for SecretStore resources.
 type GenericStoreValidator struct{}
 
+// GenericClusterStoreValidator implements webhook validation for ClusterSecretStore resources.
+type GenericClusterStoreValidator struct{}
+
 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
-	st, ok := obj.(GenericStore)
-	if !ok {
-		return nil, errors.New(errInvalidStore)
-	}
-	return validateStore(st)
+func (r *GenericStoreValidator) ValidateCreate(_ context.Context, obj *SecretStore) (admission.Warnings, error) {
+	return validateStore(obj)
 }
 
 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateUpdate(_ context.Context, _, newObj runtime.Object) (admission.Warnings, error) {
-	st, ok := newObj.(GenericStore)
-	if !ok {
-		return nil, errors.New(errInvalidStore)
-	}
-	return validateStore(st)
+func (r *GenericStoreValidator) ValidateUpdate(_ context.Context, _, newObj *SecretStore) (admission.Warnings, error) {
+	return validateStore(newObj)
+}
+
+// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericStoreValidator) ValidateDelete(_ context.Context, _ *SecretStore) (admission.Warnings, error) {
+	return nil, nil
+}
+
+// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericClusterStoreValidator) ValidateCreate(_ context.Context, obj *ClusterSecretStore) (admission.Warnings, error) {
+	return validateStore(obj)
+}
+
+// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericClusterStoreValidator) ValidateUpdate(_ context.Context, _, newObj *ClusterSecretStore) (admission.Warnings, error) {
+	return validateStore(newObj)
 }
 
 // ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
+func (r *GenericClusterStoreValidator) ValidateDelete(_ context.Context, _ *ClusterSecretStore) (admission.Warnings, error) {
 	return nil, nil
 }
 
@@ -69,13 +79,19 @@ func validateStore(store GenericStore) (admission.Warnings, error) {
 	if err != nil {
 		return nil, err
 	}
-	isMaintained, err := GetMaintenanceStatus(store)
+	status, err := GetMaintenanceStatus(store)
 	if err != nil {
 		return nil, err
 	}
 	warns, err := provider.ValidateStore(store)
-	if !isMaintained {
+	switch status {
+	case MaintenanceStatusNotMaintained:
 		warns = append(warns, fmt.Sprintf(warnStoreUnmaintained, store.GetName()))
+	case MaintenanceStatusDeprecated:
+		warns = append(warns, fmt.Sprintf(warnStoreDeprecated, store.GetName()))
+	case MaintenanceStatusMaintained:
+	default:
+		// no warnings
 	}
 	return warns, err
 }

+ 5 - 1
apis/externalsecrets/v1/secretstore_validator_test.go

@@ -118,7 +118,11 @@ func TestValidateSecretStore(t *testing.T) {
 				}, MaintenanceStatusMaintained)
 			},
 			assertErr: func(t *testing.T, err error) {
-				assert.EqualError(t, err, "failed to compile 0th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\1`\nfailed to compile 1th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\2`")
+				assert.EqualError(
+					t,
+					err,
+					"failed to compile 0th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\1`\nfailed to compile 1th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\2`",
+				)
 			},
 		},
 		{

+ 43 - 3
apis/externalsecrets/v1/secretstore_vault_types.go

@@ -29,8 +29,7 @@ const (
 	VaultKVStoreV2 VaultKVStoreVersion = "v2"
 )
 
-// VaultProvider configures a store to sync secrets using a HashiCorp Vault
-// KV backend.
+// VaultProvider configures a store to sync secrets using a Hashicorp Vault KV backend.
 type VaultProvider struct {
 	// Auth configures how secret-manager authenticates with the Vault server.
 	Auth *VaultAuth `json:"auth,omitempty"`
@@ -119,7 +118,7 @@ type VaultClientTLS struct {
 }
 
 // VaultAuth is the configuration used to authenticate with a Vault server.
-// Only one of `tokenSecretRef`, `appRole`,  `kubernetes`, `ldap`, `userPass`, `jwt` or `cert`
+// Only one of `tokenSecretRef`, `appRole`,  `kubernetes`, `ldap`, `userPass`, `jwt`, `cert`, `iam` or `gcp`
 // can be specified. A namespace to authenticate against can optionally be specified.
 type VaultAuth struct {
 	// Name of the vault namespace to authenticate to. This can be different than the namespace your secret is in.
@@ -167,6 +166,11 @@ type VaultAuth struct {
 	// UserPass authenticates with Vault by passing username/password pair
 	// +optional
 	UserPass *VaultUserPassAuth `json:"userPass,omitempty"`
+
+	// Gcp authenticates with Vault using Google Cloud Platform authentication method
+	// GCP authentication method
+	// +optional
+	GCP *VaultGCPAuth `json:"gcp,omitempty"`
 }
 
 // VaultAppRole authenticates with Vault using the App Role auth mechanism,
@@ -391,6 +395,42 @@ type VaultUserPassAuth struct {
 	SecretRef esmeta.SecretKeySelector `json:"secretRef,omitempty"`
 }
 
+// VaultGCPAuth authenticates with Vault using Google Cloud Platform authentication method.
+// Refer: https://developer.hashicorp.com/vault/docs/auth/gcp
+//
+// When ServiceAccountRef, SecretRef and WorkloadIdentity are not specified, the provider will use the controller pod's
+// identity to authenticate with GCP. This supports both GKE Workload Identity and service account keys.
+type VaultGCPAuth struct {
+	// Path where the GCP auth method is enabled in Vault, e.g: "gcp"
+	// +kubebuilder:default=gcp
+	// +optional
+	Path string `json:"path,omitempty"`
+
+	// Vault Role. In Vault, a role describes an identity with a set of permissions, groups, or policies you want to attach to a user of the secrets engine.
+	//+required
+	Role string `json:"role"`
+
+	// Project ID of the Google Cloud Platform project
+	// +optional
+	ProjectID string `json:"projectID,omitempty"`
+
+	// Location optionally defines a location/region for the secret
+	// +optional
+	Location string `json:"location,omitempty"`
+
+	// Specify credentials in a Secret object
+	// +optional
+	SecretRef *GCPSMAuthSecretRef `json:"secretRef,omitempty"`
+
+	// Specify a service account with Workload Identity
+	// +optional
+	WorkloadIdentity *GCPWorkloadIdentity `json:"workloadIdentity,omitempty"`
+
+	// ServiceAccountRef to a service account for impersonation
+	// +optional
+	ServiceAccountRef *esmeta.ServiceAccountSelector `json:"serviceAccountRef,omitempty"`
+}
+
 // VaultCheckAndSet defines the Check-And-Set (CAS) settings for Vault KV v2 PushSecret operations.
 type VaultCheckAndSet struct {
 	// Required when true, all write operations must include a check-and-set parameter.

+ 3 - 5
apis/externalsecrets/v1/secretstore_webhook.go

@@ -22,16 +22,14 @@ import (
 
 // SetupWebhookWithManager registers the SecretStore webhook with the controller manager.
 func (c *SecretStore) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(c).
+	return ctrl.NewWebhookManagedBy(mgr, c).
 		WithValidator(&GenericStoreValidator{}).
 		Complete()
 }
 
 // SetupWebhookWithManager registers the ClusterSecretStore webhook with the controller manager.
 func (c *ClusterSecretStore) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(c).
-		WithValidator(&GenericStoreValidator{}).
+	return ctrl.NewWebhookManagedBy(mgr, c).
+		WithValidator(&GenericClusterStoreValidator{}).
 		Complete()
 }

+ 301 - 120
apis/externalsecrets/v1/zz_generated.deepcopy.go

@@ -234,79 +234,6 @@ func (in *AkeylessProvider) DeepCopy() *AkeylessProvider {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AlibabaAuth) DeepCopyInto(out *AlibabaAuth) {
-	*out = *in
-	if in.SecretRef != nil {
-		in, out := &in.SecretRef, &out.SecretRef
-		*out = new(AlibabaAuthSecretRef)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.RRSAAuth != nil {
-		in, out := &in.RRSAAuth, &out.RRSAAuth
-		*out = new(AlibabaRRSAAuth)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaAuth.
-func (in *AlibabaAuth) DeepCopy() *AlibabaAuth {
-	if in == nil {
-		return nil
-	}
-	out := new(AlibabaAuth)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AlibabaAuthSecretRef) DeepCopyInto(out *AlibabaAuthSecretRef) {
-	*out = *in
-	in.AccessKeyID.DeepCopyInto(&out.AccessKeyID)
-	in.AccessKeySecret.DeepCopyInto(&out.AccessKeySecret)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaAuthSecretRef.
-func (in *AlibabaAuthSecretRef) DeepCopy() *AlibabaAuthSecretRef {
-	if in == nil {
-		return nil
-	}
-	out := new(AlibabaAuthSecretRef)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AlibabaProvider) DeepCopyInto(out *AlibabaProvider) {
-	*out = *in
-	in.Auth.DeepCopyInto(&out.Auth)
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaProvider.
-func (in *AlibabaProvider) DeepCopy() *AlibabaProvider {
-	if in == nil {
-		return nil
-	}
-	out := new(AlibabaProvider)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AlibabaRRSAAuth) DeepCopyInto(out *AlibabaRRSAAuth) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AlibabaRRSAAuth.
-func (in *AlibabaRRSAAuth) DeepCopy() *AlibabaRRSAAuth {
-	if in == nil {
-		return nil
-	}
-	out := new(AlibabaRRSAAuth)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AuthorizationProtocol) DeepCopyInto(out *AuthorizationProtocol) {
 	*out = *in
@@ -500,6 +427,79 @@ func (in *AzureKVProvider) DeepCopy() *AzureKVProvider {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BarbicanAuth) DeepCopyInto(out *BarbicanAuth) {
+	*out = *in
+	in.Username.DeepCopyInto(&out.Username)
+	in.Password.DeepCopyInto(&out.Password)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarbicanAuth.
+func (in *BarbicanAuth) DeepCopy() *BarbicanAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(BarbicanAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BarbicanProvider) DeepCopyInto(out *BarbicanProvider) {
+	*out = *in
+	in.Auth.DeepCopyInto(&out.Auth)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarbicanProvider.
+func (in *BarbicanProvider) DeepCopy() *BarbicanProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(BarbicanProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BarbicanProviderPasswordRef) DeepCopyInto(out *BarbicanProviderPasswordRef) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(apismetav1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarbicanProviderPasswordRef.
+func (in *BarbicanProviderPasswordRef) DeepCopy() *BarbicanProviderPasswordRef {
+	if in == nil {
+		return nil
+	}
+	out := new(BarbicanProviderPasswordRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BarbicanProviderUsernameRef) DeepCopyInto(out *BarbicanProviderUsernameRef) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(apismetav1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarbicanProviderUsernameRef.
+func (in *BarbicanProviderUsernameRef) DeepCopy() *BarbicanProviderUsernameRef {
+	if in == nil {
+		return nil
+	}
+	out := new(BarbicanProviderUsernameRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *BeyondTrustProviderSecretRef) DeepCopyInto(out *BeyondTrustProviderSecretRef) {
 	*out = *in
@@ -740,6 +740,22 @@ func (in *CSMAuthSecretRef) DeepCopy() *CSMAuthSecretRef {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CacheConfig) DeepCopyInto(out *CacheConfig) {
+	*out = *in
+	out.TTL = in.TTL
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CacheConfig.
+func (in *CacheConfig) DeepCopy() *CacheConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(CacheConfig)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *CertAuth) DeepCopyInto(out *CertAuth) {
 	*out = *in
@@ -1188,94 +1204,95 @@ func (in *ConjurProvider) DeepCopy() *ConjurProvider {
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DelineaProvider) DeepCopyInto(out *DelineaProvider) {
+func (in *DVLSAuth) DeepCopyInto(out *DVLSAuth) {
 	*out = *in
-	if in.ClientID != nil {
-		in, out := &in.ClientID, &out.ClientID
-		*out = new(DelineaProviderSecretRef)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.ClientSecret != nil {
-		in, out := &in.ClientSecret, &out.ClientSecret
-		*out = new(DelineaProviderSecretRef)
-		(*in).DeepCopyInto(*out)
-	}
+	in.SecretRef.DeepCopyInto(&out.SecretRef)
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DelineaProvider.
-func (in *DelineaProvider) DeepCopy() *DelineaProvider {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DVLSAuth.
+func (in *DVLSAuth) DeepCopy() *DVLSAuth {
 	if in == nil {
 		return nil
 	}
-	out := new(DelineaProvider)
+	out := new(DVLSAuth)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DelineaProviderSecretRef) DeepCopyInto(out *DelineaProviderSecretRef) {
+func (in *DVLSAuthSecretRef) DeepCopyInto(out *DVLSAuthSecretRef) {
 	*out = *in
-	if in.SecretRef != nil {
-		in, out := &in.SecretRef, &out.SecretRef
-		*out = new(apismetav1.SecretKeySelector)
-		(*in).DeepCopyInto(*out)
-	}
+	in.AppID.DeepCopyInto(&out.AppID)
+	in.AppSecret.DeepCopyInto(&out.AppSecret)
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DelineaProviderSecretRef.
-func (in *DelineaProviderSecretRef) DeepCopy() *DelineaProviderSecretRef {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DVLSAuthSecretRef.
+func (in *DVLSAuthSecretRef) DeepCopy() *DVLSAuthSecretRef {
 	if in == nil {
 		return nil
 	}
-	out := new(DelineaProviderSecretRef)
+	out := new(DVLSAuthSecretRef)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Device42Auth) DeepCopyInto(out *Device42Auth) {
+func (in *DVLSProvider) DeepCopyInto(out *DVLSProvider) {
 	*out = *in
-	in.SecretRef.DeepCopyInto(&out.SecretRef)
+	in.Auth.DeepCopyInto(&out.Auth)
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device42Auth.
-func (in *Device42Auth) DeepCopy() *Device42Auth {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DVLSProvider.
+func (in *DVLSProvider) DeepCopy() *DVLSProvider {
 	if in == nil {
 		return nil
 	}
-	out := new(Device42Auth)
+	out := new(DVLSProvider)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Device42Provider) DeepCopyInto(out *Device42Provider) {
+func (in *DelineaProvider) DeepCopyInto(out *DelineaProvider) {
 	*out = *in
-	in.Auth.DeepCopyInto(&out.Auth)
+	if in.ClientID != nil {
+		in, out := &in.ClientID, &out.ClientID
+		*out = new(DelineaProviderSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ClientSecret != nil {
+		in, out := &in.ClientSecret, &out.ClientSecret
+		*out = new(DelineaProviderSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device42Provider.
-func (in *Device42Provider) DeepCopy() *Device42Provider {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DelineaProvider.
+func (in *DelineaProvider) DeepCopy() *DelineaProvider {
 	if in == nil {
 		return nil
 	}
-	out := new(Device42Provider)
+	out := new(DelineaProvider)
 	in.DeepCopyInto(out)
 	return out
 }
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Device42SecretRef) DeepCopyInto(out *Device42SecretRef) {
+func (in *DelineaProviderSecretRef) DeepCopyInto(out *DelineaProviderSecretRef) {
 	*out = *in
-	in.Credentials.DeepCopyInto(&out.Credentials)
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(apismetav1.SecretKeySelector)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device42SecretRef.
-func (in *Device42SecretRef) DeepCopy() *Device42SecretRef {
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DelineaProviderSecretRef.
+func (in *DelineaProviderSecretRef) DeepCopy() *DelineaProviderSecretRef {
 	if in == nil {
 		return nil
 	}
-	out := new(Device42SecretRef)
+	out := new(DelineaProviderSecretRef)
 	in.DeepCopyInto(out)
 	return out
 }
@@ -1283,7 +1300,16 @@ func (in *Device42SecretRef) DeepCopy() *Device42SecretRef {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *DopplerAuth) DeepCopyInto(out *DopplerAuth) {
 	*out = *in
-	in.SecretRef.DeepCopyInto(&out.SecretRef)
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(DopplerAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.OIDCConfig != nil {
+		in, out := &in.OIDCConfig, &out.OIDCConfig
+		*out = new(DopplerOIDCAuth)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DopplerAuth.
@@ -1312,6 +1338,27 @@ func (in *DopplerAuthSecretRef) DeepCopy() *DopplerAuthSecretRef {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DopplerOIDCAuth) DeepCopyInto(out *DopplerOIDCAuth) {
+	*out = *in
+	in.ServiceAccountRef.DeepCopyInto(&out.ServiceAccountRef)
+	if in.ExpirationSeconds != nil {
+		in, out := &in.ExpirationSeconds, &out.ExpirationSeconds
+		*out = new(int64)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DopplerOIDCAuth.
+func (in *DopplerOIDCAuth) DeepCopy() *DopplerOIDCAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(DopplerOIDCAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *DopplerProvider) DeepCopyInto(out *DopplerProvider) {
 	*out = *in
@@ -2061,6 +2108,21 @@ func (in *GeneratorRef) DeepCopy() *GeneratorRef {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GenericClusterStoreValidator) DeepCopyInto(out *GenericClusterStoreValidator) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericClusterStoreValidator.
+func (in *GenericClusterStoreValidator) DeepCopy() *GenericClusterStoreValidator {
+	if in == nil {
+		return nil
+	}
+	out := new(GenericClusterStoreValidator)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GenericStoreValidator) DeepCopyInto(out *GenericStoreValidator) {
 	*out = *in
@@ -2318,6 +2380,16 @@ func (in *InfisicalProvider) DeepCopyInto(out *InfisicalProvider) {
 	*out = *in
 	in.Auth.DeepCopyInto(&out.Auth)
 	out.SecretsScope = in.SecretsScope
+	if in.CABundle != nil {
+		in, out := &in.CABundle, &out.CABundle
+		*out = make([]byte, len(*in))
+		copy(*out, *in)
+	}
+	if in.CAProvider != nil {
+		in, out := &in.CAProvider, &out.CAProvider
+		*out = new(CAProvider)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfisicalProvider.
@@ -2541,6 +2613,60 @@ func (in *NTLMProtocol) DeepCopy() *NTLMProtocol {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebiusAuth) DeepCopyInto(out *NebiusAuth) {
+	*out = *in
+	in.ServiceAccountCreds.DeepCopyInto(&out.ServiceAccountCreds)
+	in.Token.DeepCopyInto(&out.Token)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebiusAuth.
+func (in *NebiusAuth) DeepCopy() *NebiusAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(NebiusAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebiusCAProvider) DeepCopyInto(out *NebiusCAProvider) {
+	*out = *in
+	in.Certificate.DeepCopyInto(&out.Certificate)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebiusCAProvider.
+func (in *NebiusCAProvider) DeepCopy() *NebiusCAProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(NebiusCAProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NebiusMysteryboxProvider) DeepCopyInto(out *NebiusMysteryboxProvider) {
+	*out = *in
+	in.Auth.DeepCopyInto(&out.Auth)
+	if in.CAProvider != nil {
+		in, out := &in.CAProvider, &out.CAProvider
+		*out = new(NebiusCAProvider)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NebiusMysteryboxProvider.
+func (in *NebiusMysteryboxProvider) DeepCopy() *NebiusMysteryboxProvider {
+	if in == nil {
+		return nil
+	}
+	out := new(NebiusMysteryboxProvider)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *NgrokAuth) DeepCopyInto(out *NgrokAuth) {
 	*out = *in
@@ -2794,6 +2920,11 @@ func (in *OnePasswordSDKProvider) DeepCopyInto(out *OnePasswordSDKProvider) {
 		*out = new(OnePasswordSDKAuth)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Cache != nil {
+		in, out := &in.Cache, &out.Cache
+		*out = new(CacheConfig)
+		**out = **in
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OnePasswordSDKProvider.
@@ -3122,6 +3253,16 @@ func (in *SecretServerProvider) DeepCopyInto(out *SecretServerProvider) {
 		*out = new(SecretServerProviderRef)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.CABundle != nil {
+		in, out := &in.CABundle, &out.CABundle
+		*out = make([]byte, len(*in))
+		copy(*out, *in)
+	}
+	if in.CAProvider != nil {
+		in, out := &in.CAProvider, &out.CAProvider
+		*out = new(CAProvider)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretServerProvider.
@@ -3276,11 +3417,6 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
 		*out = new(GitlabProvider)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.Alibaba != nil {
-		in, out := &in.Alibaba, &out.Alibaba
-		*out = new(AlibabaProvider)
-		(*in).DeepCopyInto(*out)
-	}
 	if in.OnePassword != nil {
 		in, out := &in.OnePassword, &out.OnePassword
 		*out = new(OnePasswordProvider)
@@ -3376,9 +3512,9 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
 		*out = new(PassboltProvider)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.Device42 != nil {
-		in, out := &in.Device42, &out.Device42
-		*out = new(Device42Provider)
+	if in.DVLS != nil {
+		in, out := &in.DVLS, &out.DVLS
+		*out = new(DVLSProvider)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.Infisical != nil {
@@ -3406,6 +3542,16 @@ func (in *SecretStoreProvider) DeepCopyInto(out *SecretStoreProvider) {
 		*out = new(NgrokProvider)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Barbican != nil {
+		in, out := &in.Barbican, &out.Barbican
+		*out = new(BarbicanProvider)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.NebiusMysterybox != nil {
+		in, out := &in.NebiusMysterybox, &out.NebiusMysterybox
+		*out = new(NebiusMysteryboxProvider)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretStoreProvider.
@@ -3819,6 +3965,11 @@ func (in *VaultAuth) DeepCopyInto(out *VaultAuth) {
 		*out = new(VaultUserPassAuth)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.GCP != nil {
+		in, out := &in.GCP, &out.GCP
+		*out = new(VaultGCPAuth)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultAuth.
@@ -3955,6 +4106,36 @@ func (in *VaultClientTLS) DeepCopy() *VaultClientTLS {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *VaultGCPAuth) DeepCopyInto(out *VaultGCPAuth) {
+	*out = *in
+	if in.SecretRef != nil {
+		in, out := &in.SecretRef, &out.SecretRef
+		*out = new(GCPSMAuthSecretRef)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.WorkloadIdentity != nil {
+		in, out := &in.WorkloadIdentity, &out.WorkloadIdentity
+		*out = new(GCPWorkloadIdentity)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.ServiceAccountRef != nil {
+		in, out := &in.ServiceAccountRef, &out.ServiceAccountRef
+		*out = new(apismetav1.ServiceAccountSelector)
+		(*in).DeepCopyInto(*out)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultGCPAuth.
+func (in *VaultGCPAuth) DeepCopy() *VaultGCPAuth {
+	if in == nil {
+		return nil
+	}
+	out := new(VaultGCPAuth)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *VaultIamAuth) DeepCopyInto(out *VaultIamAuth) {
 	*out = *in

+ 1 - 1
apis/externalsecrets/v1alpha1/pushsecret_types.go

@@ -88,7 +88,7 @@ const (
 // PushSecretSpec configures the behavior of the PushSecret.
 type PushSecretSpec struct {
 	// The Interval to which External Secrets will try to push a secret definition
-	// +kubebuilder:default="1h"
+	// +kubebuilder:default="1h0m0s"
 	RefreshInterval *metav1.Duration `json:"refreshInterval,omitempty"`
 
 	SecretStoreRefs []PushSecretStoreRef `json:"secretStoreRefs"`

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

@@ -428,9 +428,9 @@ type ExternalSecretSpec struct {
 	// RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
 	// specified as Golang Duration strings.
 	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-	// Example values: "1h", "2h30m", "10s"
-	// May be set to zero to fetch and create it once. Defaults to 1h.
-	// +kubebuilder:default="1h"
+	// Example values: "1h0m0s", "2h30m0s", "10m0s"
+	// May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
+	// +kubebuilder:default="1h0m0s"
 	RefreshInterval *metav1.Duration `json:"refreshInterval,omitempty"`
 
 	// Data defines the connection between the Kubernetes Secret keys and the Provider data

+ 13 - 12
apis/externalsecrets/v1beta1/externalsecret_validator.go

@@ -21,32 +21,33 @@ import (
 	"errors"
 	"fmt"
 
-	"k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 )
 
-// ExternalSecretValidator implements webhook validation for ExternalSecret resources.
+// Ensures ExternalSecretValidator implements the admission.CustomValidator interface correctly.
+var _ admission.Validator[*ExternalSecret] = &ExternalSecretValidator{}
+
+// ExternalSecretValidator implements a validating webhook for ExternalSecrets.
 type ExternalSecretValidator struct{}
 
-// ValidateCreate validates an ExternalSecret during creation.
-func (esv *ExternalSecretValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
+// ValidateCreate validates the creation of an external secret object.
+func (in *ExternalSecretValidator) ValidateCreate(_ context.Context, obj *ExternalSecret) (warnings admission.Warnings, err error) {
 	return validateExternalSecret(obj)
 }
 
-// ValidateUpdate validates an ExternalSecret during update.
-func (esv *ExternalSecretValidator) ValidateUpdate(_ context.Context, _, newObj runtime.Object) (admission.Warnings, error) {
+// ValidateUpdate validates the update of an external secret object.
+func (in *ExternalSecretValidator) ValidateUpdate(_ context.Context, _, newObj *ExternalSecret) (warnings admission.Warnings, err error) {
 	return validateExternalSecret(newObj)
 }
 
-// ValidateDelete validates an ExternalSecret during deletion.
-func (esv *ExternalSecretValidator) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
+// ValidateDelete validates the deletion of an external secret object.
+func (in *ExternalSecretValidator) ValidateDelete(_ context.Context, _ *ExternalSecret) (warnings admission.Warnings, err error) {
 	return nil, nil
 }
 
-func validateExternalSecret(obj runtime.Object) (admission.Warnings, error) {
-	es, ok := obj.(*ExternalSecret)
-	if !ok {
-		return nil, errors.New("unexpected type")
+func validateExternalSecret(es *ExternalSecret) (admission.Warnings, error) {
+	if es == nil {
+		return nil, errors.New("external secret cannot be nil during validation")
 	}
 
 	var errs error

+ 2 - 4
apis/externalsecrets/v1beta1/externalsecret_validator_test.go

@@ -18,8 +18,6 @@ package v1beta1
 
 import (
 	"testing"
-
-	"k8s.io/apimachinery/pkg/runtime"
 )
 
 const (
@@ -29,13 +27,13 @@ const (
 func TestValidateExternalSecret(t *testing.T) {
 	tests := []struct {
 		name        string
-		obj         runtime.Object
+		obj         *ExternalSecret
 		expectedErr string
 	}{
 		{
 			name:        "nil",
 			obj:         nil,
-			expectedErr: "unexpected type",
+			expectedErr: "external secret cannot be nil during validation",
 		},
 		{
 			name: "deletion policy delete",

+ 1 - 2
apis/externalsecrets/v1beta1/externalsecret_webhook.go

@@ -22,8 +22,7 @@ import (
 
 // SetupWebhookWithManager registers the ExternalSecret webhook with the controller manager.
 func (es *ExternalSecret) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(es).
+	return ctrl.NewWebhookManagedBy(mgr, es).
 		WithValidator(&ExternalSecretValidator{}).
 		Complete()
 }

+ 4 - 0
apis/externalsecrets/v1beta1/secretstore_beyondtrust_types.go

@@ -54,6 +54,10 @@ type BeyondtrustServer struct {
 	RetrievalType string `json:"retrievalType,omitempty"`
 	// A character that separates the folder names.
 	Separator string `json:"separator,omitempty"`
+	// When true, the response includes the decrypted password. When false, the password field is omitted. This option only applies to the SECRET retrieval type. Default: true.
+	// +optional
+	// +kubebuilder:default=true
+	Decrypt bool `json:"decrypt,omitempty"`
 	// +required - Indicates whether to verify the certificate authority on the Secrets Safe instance. Warning - false is insecure, instructs the BT provider not to verify the certificate authority.
 	VerifyCA bool `json:"verifyCA"`
 	// Timeout specifies a time limit for requests made by this Client. The timeout includes connection time, any redirects, and reading the response body. Defaults to 45 seconds.

+ 5 - 5
apis/externalsecrets/v1beta1/secretstore_types.go

@@ -31,7 +31,7 @@ type SecretStoreSpec struct {
 	// Used to configure the provider. Only one provider may be set
 	Provider *SecretStoreProvider `json:"provider"`
 
-	// Used to configure http retries if failed
+	// Used to configure HTTP retries on failures.
 	// +optional
 	RetrySettings *SecretStoreRetrySettings `json:"retrySettings,omitempty"`
 
@@ -39,7 +39,7 @@ type SecretStoreSpec struct {
 	// +optional
 	RefreshInterval int `json:"refreshInterval,omitempty"`
 
-	// Used to constraint a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore
+	// Used to constrain a ClusterSecretStore to specific namespaces. Relevant only to ClusterSecretStore.
 	// +optional
 	Conditions []ClusterSecretStoreCondition `json:"conditions,omitempty"`
 }
@@ -83,7 +83,7 @@ type SecretStoreProvider struct {
 	// +optional
 	BitwardenSecretsManager *BitwardenSecretsManagerProvider `json:"bitwardensecretsmanager,omitempty"`
 
-	// Vault configures this store to sync secrets using Hashi provider
+	// Vault configures this store to sync secrets using the HashiCorp Vault provider.
 	// +optional
 	Vault *VaultProvider `json:"vault,omitempty"`
 
@@ -107,7 +107,7 @@ type SecretStoreProvider struct {
 	// +optional
 	YandexLockbox *YandexLockboxProvider `json:"yandexlockbox,omitempty"`
 
-	// Github configures this store to push Github Action secrets using Github API provider
+	// Github configures this store to push GitHub Actions secrets using the GitHub API provider.
 	// +optional
 	Github *GithubProvider `json:"github,omitempty"`
 
@@ -139,7 +139,7 @@ type SecretStoreProvider struct {
 	// +optional
 	Senhasegura *SenhaseguraProvider `json:"senhasegura,omitempty"`
 
-	// Scaleway
+	// Scaleway configures this store to sync secrets using the Scaleway provider.
 	// +optional
 	Scaleway *ScalewayProvider `json:"scaleway,omitempty"`
 

+ 26 - 20
apis/externalsecrets/v1beta1/secretstore_validator.go

@@ -22,39 +22,45 @@ import (
 	"fmt"
 	"regexp"
 
-	"k8s.io/apimachinery/pkg/runtime"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 )
 
-var _ admission.CustomValidator = &GenericStoreValidator{}
+var _ admission.Validator[*SecretStore] = &GenericStoreValidator{}
+var _ admission.Validator[*ClusterSecretStore] = &GenericClusterStoreValidator{}
 
-const (
-	errInvalidStore = "invalid store"
-)
-
-// GenericStoreValidator provides validation for SecretStore and ClusterSecretStore resources.
+// GenericStoreValidator provides validation for SecretStore resources.
 type GenericStoreValidator struct{}
 
+// GenericClusterStoreValidator provides validation for ClusterSecretStore resources.
+type GenericClusterStoreValidator struct{}
+
 // ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateCreate(_ context.Context, obj runtime.Object) (admission.Warnings, error) {
-	st, ok := obj.(GenericStore)
-	if !ok {
-		return nil, errors.New(errInvalidStore)
-	}
-	return validateStore(st)
+func (r *GenericClusterStoreValidator) ValidateCreate(_ context.Context, obj *ClusterSecretStore) (admission.Warnings, error) {
+	return validateStore(obj)
 }
 
 // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateUpdate(_ context.Context, _, newObj runtime.Object) (admission.Warnings, error) {
-	st, ok := newObj.(GenericStore)
-	if !ok {
-		return nil, errors.New(errInvalidStore)
-	}
-	return validateStore(st)
+func (r *GenericClusterStoreValidator) ValidateUpdate(_ context.Context, _, newObj *ClusterSecretStore) (admission.Warnings, error) {
+	return validateStore(newObj)
+}
+
+// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericClusterStoreValidator) ValidateDelete(_ context.Context, _ *ClusterSecretStore) (admission.Warnings, error) {
+	return nil, nil
+}
+
+// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericStoreValidator) ValidateCreate(_ context.Context, obj *SecretStore) (admission.Warnings, error) {
+	return validateStore(obj)
+}
+
+// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
+func (r *GenericStoreValidator) ValidateUpdate(_ context.Context, _, newObj *SecretStore) (admission.Warnings, error) {
+	return validateStore(newObj)
 }
 
 // ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
-func (r *GenericStoreValidator) ValidateDelete(_ context.Context, _ runtime.Object) (admission.Warnings, error) {
+func (r *GenericStoreValidator) ValidateDelete(_ context.Context, _ *SecretStore) (admission.Warnings, error) {
 	return nil, nil
 }
 

+ 5 - 1
apis/externalsecrets/v1beta1/secretstore_validator_test.go

@@ -106,7 +106,11 @@ func TestValidateSecretStore(t *testing.T) {
 				})
 			},
 			assertErr: func(t *testing.T, err error) {
-				assert.EqualError(t, err, "failed to compile 0th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\1`\nfailed to compile 1th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\2`")
+				assert.EqualError(
+					t,
+					err,
+					"failed to compile 0th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\1`\nfailed to compile 1th namespace regex in 0th condition: error parsing regexp: invalid escape sequence: `\\2`",
+				)
 			},
 		},
 		{

+ 3 - 5
apis/externalsecrets/v1beta1/secretstore_webhook.go

@@ -22,16 +22,14 @@ import (
 
 // SetupWebhookWithManager configures the webhook manager for the SecretStore.
 func (c *SecretStore) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(c).
+	return ctrl.NewWebhookManagedBy(mgr, c).
 		WithValidator(&GenericStoreValidator{}).
 		Complete()
 }
 
 // SetupWebhookWithManager configures the webhook manager for the ClusterSecretStore.
 func (c *ClusterSecretStore) SetupWebhookWithManager(mgr ctrl.Manager) error {
-	return ctrl.NewWebhookManagedBy(mgr).
-		For(c).
-		WithValidator(&GenericStoreValidator{}).
+	return ctrl.NewWebhookManagedBy(mgr, c).
+		WithValidator(&GenericClusterStoreValidator{}).
 		Complete()
 }

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

@@ -1796,6 +1796,21 @@ func (in *GeneratorRef) DeepCopy() *GeneratorRef {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GenericClusterStoreValidator) DeepCopyInto(out *GenericClusterStoreValidator) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GenericClusterStoreValidator.
+func (in *GenericClusterStoreValidator) DeepCopy() *GenericClusterStoreValidator {
+	if in == nil {
+		return nil
+	}
+	out := new(GenericClusterStoreValidator)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GenericStoreValidator) DeepCopyInto(out *GenericStoreValidator) {
 	*out = *in

+ 2 - 1
apis/generators/v1alpha1/types_mfa.go

@@ -17,8 +17,9 @@ limitations under the License.
 package v1alpha1
 
 import (
-	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	smmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
 )
 
 // MFASpec controls the behavior of the mfa generator.

+ 7 - 0
apis/generators/v1alpha1/types_password.go

@@ -47,6 +47,13 @@ type PasswordSpec struct {
 	// +kubebuilder:default=false
 	AllowRepeat bool `json:"allowRepeat"`
 
+	// SecretKeys defines the keys that will be populated with generated passwords.
+	// Defaults to "password" when not set.
+	// +optional
+	// +kubebuilder:validation:MinItems=1
+	// +kubebuilder:validation:Items:MinLength=1
+	SecretKeys []string `json:"secretKeys,omitempty"`
+
 	// Encoding specifies the encoding of the generated password.
 	// Valid values are:
 	// - "raw" (default): no encoding

+ 4 - 3
apis/generators/v1alpha1/types_sshkey.go

@@ -22,13 +22,14 @@ import (
 
 // SSHKeySpec controls the behavior of the ssh key generator.
 type SSHKeySpec struct {
-	// KeyType specifies the SSH key type (rsa, ed25519)
-	// +kubebuilder:validation:Enum=rsa;ed25519
+	// KeyType specifies the SSH key type (rsa, ecdsa, ed25519)
+	// +kubebuilder:validation:Enum=rsa;ecdsa;ed25519
 	// +kubebuilder:default="rsa"
 	KeyType string `json:"keyType,omitempty"`
 
-	// KeySize specifies the key size for RSA keys (default: 2048)
+	// KeySize specifies the key size for RSA keys (default: 2048) and ECDSA keys (default: 256).
 	// For RSA keys: 2048, 3072, 4096
+	// For ECDSA keys: 256, 384, 521
 	// Ignored for ed25519 keys
 	// +kubebuilder:validation:Minimum=256
 	// +kubebuilder:validation:Maximum=8192

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

@@ -1423,6 +1423,11 @@ func (in *PasswordSpec) DeepCopyInto(out *PasswordSpec) {
 		*out = new(string)
 		**out = **in
 	}
+	if in.SecretKeys != nil {
+		in, out := &in.SecretKeys, &out.SecretKeys
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	if in.Encoding != nil {
 		in, out := &in.Encoding, &out.Encoding
 		*out = new(string)

+ 45 - 37
apis/go.mod

@@ -1,66 +1,74 @@
 module github.com/external-secrets/external-secrets/apis
 
-go 1.25.1
+go 1.25.7
 
 require (
-	github.com/stretchr/testify v1.10.0
-	k8s.io/api v0.34.1
-	k8s.io/apiextensions-apiserver v0.34.1
-	k8s.io/apimachinery v0.34.1
-	sigs.k8s.io/controller-runtime v0.22.3
+	github.com/stretchr/testify v1.11.1
+	k8s.io/api v0.35.0
+	k8s.io/apiextensions-apiserver v0.35.0
+	k8s.io/apimachinery v0.35.0
+	sigs.k8s.io/controller-runtime v0.23.1
 )
 
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
-	github.com/emicklei/go-restful/v3 v3.12.2 // indirect
+	github.com/emicklei/go-restful/v3 v3.13.0 // indirect
 	github.com/evanphx/json-patch/v5 v5.9.11 // indirect
 	github.com/fsnotify/fsnotify v1.9.0 // indirect
 	github.com/fxamacker/cbor/v2 v2.9.0 // indirect
-	github.com/go-logr/logr v1.4.2 // indirect
-	github.com/go-openapi/jsonpointer v0.21.0 // indirect
-	github.com/go-openapi/jsonreference v0.20.2 // indirect
-	github.com/go-openapi/swag v0.23.0 // indirect
-	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
+	github.com/go-openapi/jsonpointer v0.22.4 // indirect
+	github.com/go-openapi/jsonreference v0.21.4 // indirect
+	github.com/go-openapi/swag v0.25.4 // indirect
+	github.com/go-openapi/swag/cmdutils v0.25.4 // indirect
+	github.com/go-openapi/swag/conv v0.25.4 // indirect
+	github.com/go-openapi/swag/fileutils v0.25.4 // indirect
+	github.com/go-openapi/swag/jsonname v0.25.4 // indirect
+	github.com/go-openapi/swag/jsonutils v0.25.4 // indirect
+	github.com/go-openapi/swag/loading v0.25.4 // indirect
+	github.com/go-openapi/swag/mangling v0.25.4 // indirect
+	github.com/go-openapi/swag/netutils v0.25.4 // indirect
+	github.com/go-openapi/swag/stringutils v0.25.4 // indirect
+	github.com/go-openapi/swag/typeutils v0.25.4 // indirect
+	github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
 	github.com/google/btree v1.1.3 // indirect
-	github.com/google/gnostic-models v0.7.0 // indirect
+	github.com/google/gnostic-models v0.7.1 // indirect
 	github.com/google/go-cmp v0.7.0 // indirect
 	github.com/google/uuid v1.6.0 // indirect
-	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/mailru/easyjson v0.7.7 // indirect
+	github.com/kr/text v0.2.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
-	github.com/pkg/errors v0.9.1 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.22.0 // indirect
-	github.com/prometheus/client_model v0.6.1 // indirect
-	github.com/prometheus/common v0.62.0 // indirect
-	github.com/prometheus/procfs v0.15.1 // indirect
-	github.com/spf13/pflag v1.0.6 // indirect
+	github.com/prometheus/client_golang v1.23.2 // indirect
+	github.com/prometheus/client_model v0.6.2 // indirect
+	github.com/prometheus/common v0.67.5 // indirect
+	github.com/prometheus/procfs v0.19.2 // indirect
+	github.com/spf13/pflag v1.0.10 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
-	go.yaml.in/yaml/v2 v2.4.2 // indirect
+	go.yaml.in/yaml/v2 v2.4.3 // indirect
 	go.yaml.in/yaml/v3 v3.0.4 // indirect
-	golang.org/x/net v0.38.0 // indirect
-	golang.org/x/oauth2 v0.27.0 // indirect
-	golang.org/x/sync v0.12.0 // indirect
-	golang.org/x/sys v0.31.0 // indirect
-	golang.org/x/term v0.30.0 // indirect
-	golang.org/x/text v0.23.0 // indirect
-	golang.org/x/time v0.9.0 // indirect
-	gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
-	google.golang.org/protobuf v1.36.5 // indirect
-	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
+	golang.org/x/net v0.49.0 // indirect
+	golang.org/x/oauth2 v0.34.0 // indirect
+	golang.org/x/sync v0.19.0 // indirect
+	golang.org/x/sys v0.40.0 // indirect
+	golang.org/x/term v0.39.0 // indirect
+	golang.org/x/text v0.33.0 // indirect
+	golang.org/x/time v0.14.0 // indirect
+	gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
+	google.golang.org/protobuf v1.36.11 // indirect
+	gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/client-go v0.34.1 // indirect
+	k8s.io/client-go v0.35.0 // indirect
 	k8s.io/klog/v2 v2.130.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
-	k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
-	sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+	k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect
+	k8s.io/utils v0.0.0-20260108192941-914a6e750570 // indirect
+	sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
 	sigs.k8s.io/randfill v1.0.0 // indirect
-	sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect
 	sigs.k8s.io/yaml v1.6.0 // indirect
 )

+ 106 - 120
apis/go.sum

@@ -1,3 +1,5 @@
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -6,8 +8,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
-github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
+github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
 github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
 github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
 github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
@@ -16,54 +18,69 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
 github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
 github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
 github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
-github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
-github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
 github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
-github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
-github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
-github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
-github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
-github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
-github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
-github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
-github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4=
+github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80=
+github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8=
+github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4=
+github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU=
+github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ=
+github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4=
+github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
+github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4=
+github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU=
+github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y=
+github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
+github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI=
+github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
+github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA=
+github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo=
+github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM=
+github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s=
+github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE=
+github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48=
+github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
+github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0=
+github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
+github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8=
+github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
+github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw=
+github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
+github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw=
+github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc=
+github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4=
+github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg=
+github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls=
+github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54=
 github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
-github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
-github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
+github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
+github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
 github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
-github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
 github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
-github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -72,127 +89,96 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFd
 github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
-github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
-github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
-github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
+github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
-github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
-github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
-github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
-github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
-github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
-github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
+github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
+github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
+github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
+github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
+github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
+github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
+github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
 github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
 go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
-go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
+go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
 go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
 go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
-golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
-golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
-golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
-golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
-golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
-golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
-golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
-gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
-google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
+golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
+golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
+golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
+golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
+golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
+golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
+golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
+golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
+golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
+golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
+golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
+gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
+gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
-gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
-gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
+gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
+gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM=
-k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk=
-k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI=
-k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc=
-k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4=
-k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
-k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY=
-k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8=
+k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY=
+k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA=
+k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4=
+k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU=
+k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8=
+k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
+k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE=
+k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
-k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
-k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
-k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y=
-sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
-sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
-sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
+k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
+k8s.io/utils v0.0.0-20260108192941-914a6e750570 h1:JT4W8lsdrGENg9W+YwwdLJxklIuKWdRm+BC+xt33FOY=
+k8s.io/utils v0.0.0-20260108192941-914a6e750570/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
+sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE=
+sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
 sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
 sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
-sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 h1:2WOzJpHUBVrrkDjU4KBT8n5LDcj824eX0I5UKcgeRUs=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
 sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
 sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=

+ 2 - 1
cmd/controller/certcontroller.go

@@ -193,7 +193,8 @@ func init() {
 	certcontrollerCmd.Flags().StringVar(&serviceNamespace, "service-namespace", "default", "Webhook service namespace")
 	certcontrollerCmd.Flags().StringVar(&secretName, "secret-name", "external-secrets-webhook", "Secret to store certs for webhook")
 	certcontrollerCmd.Flags().StringVar(&secretNamespace, "secret-namespace", "default", "namespace of the secret to store certs")
-	certcontrollerCmd.Flags().StringSliceVar(&crdNames, "crd-names", []string{"externalsecrets.external-secrets.io", "clustersecretstores.external-secrets.io", "secretstores.external-secrets.io"}, "CRD names reconciled by the controller")
+	certcontrollerCmd.Flags().
+		StringSliceVar(&crdNames, "crd-names", []string{"externalsecrets.external-secrets.io", "clustersecretstores.external-secrets.io", "secretstores.external-secrets.io"}, "CRD names reconciled by the controller")
 	certcontrollerCmd.Flags().BoolVar(&enablePartialCache, "enable-partial-cache", false,
 		"Enable caching of only the relevant CRDs and Webhook configurations in the Informer to improve memory efficiency")
 	certcontrollerCmd.Flags().BoolVar(&enableLeaderElection, "enable-leader-election", false,

+ 23 - 16
cmd/controller/root.go

@@ -84,6 +84,7 @@ var (
 	zapTimeEncoding                       string
 	namespace                             string
 	enableClusterStoreReconciler          bool
+	enableSecretStoreReconciler           bool
 	enableClusterExternalSecretReconciler bool
 	enableClusterPushSecretReconciler     bool
 	enablePushSecretReconciler            bool
@@ -197,21 +198,24 @@ var rootCmd = &cobra.Command{
 			}
 		}
 
-		ssmetrics.SetUpMetrics()
-		if err = (&secretstore.StoreReconciler{
-			Client:            mgr.GetClient(),
-			Log:               ctrl.Log.WithName("controllers").WithName("SecretStore"),
-			Scheme:            mgr.GetScheme(),
-			ControllerClass:   controllerClass,
-			RequeueInterval:   storeRequeueInterval,
-			PushSecretEnabled: enablePushSecretReconciler,
-		}).SetupWithManager(mgr, controller.Options{
-			MaxConcurrentReconciles: concurrent,
-			RateLimiter:             ctrlcommon.BuildRateLimiter(),
-		}); err != nil {
-			setupLog.Error(err, errCreateController, "controller", "SecretStore")
-			os.Exit(1)
+		if enableSecretStoreReconciler {
+			ssmetrics.SetUpMetrics()
+			if err = (&secretstore.StoreReconciler{
+				Client:            mgr.GetClient(),
+				Log:               ctrl.Log.WithName("controllers").WithName("SecretStore"),
+				Scheme:            mgr.GetScheme(),
+				ControllerClass:   controllerClass,
+				RequeueInterval:   storeRequeueInterval,
+				PushSecretEnabled: enablePushSecretReconciler,
+			}).SetupWithManager(mgr, controller.Options{
+				MaxConcurrentReconciles: concurrent,
+				RateLimiter:             ctrlcommon.BuildRateLimiter(),
+			}); err != nil {
+				setupLog.Error(err, errCreateController, "controller", "SecretStore")
+				os.Exit(1)
+			}
 		}
+
 		if enableClusterStoreReconciler {
 			cssmetrics.SetUpMetrics()
 			if err = (&secretstore.ClusterStoreReconciler{
@@ -352,8 +356,10 @@ func init() {
 	rootCmd.Flags().StringVar(&liveAddr, "live-addr", ":8082", "The address the live endpoint binds to.")
 	rootCmd.Flags().StringVar(&loglevel, "loglevel", "info", "loglevel to use, one of: debug, info, warn, error, dpanic, panic, fatal")
 	rootCmd.Flags().StringVar(&zapTimeEncoding, "zap-time-encoding", "epoch", "Zap time encoding (one of 'epoch', 'millis', 'nano', 'iso8601', 'rfc3339' or 'rfc3339nano')")
-	rootCmd.Flags().StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces")
+	rootCmd.Flags().
+		StringVar(&namespace, "namespace", "", "watch external secrets scoped in the provided namespace only. ClusterSecretStore can be used but only work if it doesn't reference resources from other namespaces")
 	rootCmd.Flags().BoolVar(&enableClusterStoreReconciler, "enable-cluster-store-reconciler", true, "Enable cluster store reconciler.")
+	rootCmd.Flags().BoolVar(&enableSecretStoreReconciler, "enable-secret-store-reconciler", true, "Enable secret store reconciler.")
 	rootCmd.Flags().BoolVar(&enableClusterExternalSecretReconciler, "enable-cluster-external-secret-reconciler", true, "Enable cluster external secret reconciler.")
 	rootCmd.Flags().BoolVar(&enableClusterPushSecretReconciler, "enable-cluster-push-secret-reconciler", true, "Enable cluster push secret reconciler.")
 	rootCmd.Flags().BoolVar(&enablePushSecretReconciler, "enable-push-secret-reconciler", true, "Enable push secret reconciler.")
@@ -366,7 +372,8 @@ func init() {
 	rootCmd.Flags().BoolVar(&enableExtendedMetricLabels, "enable-extended-metric-labels", false, "Enable recommended kubernetes annotations as labels in metrics.")
 	rootCmd.Flags().BoolVar(&enableHTTP2, "enable-http2", false,
 		"If set, HTTP/2 will be enabled for the metrics server")
-	rootCmd.Flags().BoolVar(&allowGenericTargets, "unsafe-allow-generic-targets", false, "Enable support for creating generic resources (ConfigMaps, Custom Resources). WARNING: Using generic resources, please sure all policies are correctly configured.")
+	rootCmd.Flags().
+		BoolVar(&allowGenericTargets, "unsafe-allow-generic-targets", false, "Enable support for creating generic resources (ConfigMaps, Custom Resources). WARNING: Using generic resources, please sure all policies are correctly configured.")
 	fs := feature.Features()
 	for _, f := range fs {
 		rootCmd.Flags().AddFlagSet(f.Flags)

+ 4 - 0
cmd/esoctl/.goreleaser.yaml

@@ -14,6 +14,10 @@ builds:
       - windows
     goarch:
       - amd64
+      - arm64
+    ignore:
+      - goos: windows
+        goarch: arm64
 
 archives:
   - id: default

+ 1 - 1
cmd/esoctl/Makefile

@@ -1,5 +1,5 @@
 # set the shell to bash always
-SHELL         := /bin/bash
+SHELL         := /usr/bin/env bash
 
 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
 ifeq (,$(shell go env GOBIN))

+ 67 - 7
cmd/esoctl/generator/bootstrap.go

@@ -29,6 +29,8 @@ import (
 //go:embed templates/*.tmpl
 var templates embed.FS
 
+const generatorImportPath = "github.com/external-secrets/external-secrets/generators/v1/"
+
 // Config holds the configuration for bootstrapping a generator.
 type Config struct {
 	GeneratorName string
@@ -74,6 +76,11 @@ func Bootstrap(rootDir string, cfg Config) error {
 		return fmt.Errorf("failed to update register kind file: %w", err)
 	}
 
+	// Update ExternalSecret GeneratorRef validation
+	if err := updateExternalSecretGeneratorRef(rootDir, cfg); err != nil {
+		return fmt.Errorf("failed to update ExternalSecret GeneratorRef: %w", err)
+	}
+
 	return nil
 }
 
@@ -179,8 +186,8 @@ func updateRegisterFile(rootDir string, cfg Config) error {
 	}
 
 	// Add import
-	importLine := fmt.Sprintf("\t%s \"github.com/external-secrets/external-secrets/generators/v1/%s\"",
-		cfg.PackageName, cfg.PackageName)
+	importLine := fmt.Sprintf("\t%s \"%s%s\"",
+		cfg.PackageName, generatorImportPath, cfg.PackageName)
 
 	// Find the last import before the closing parenthesis
 	lines := strings.Split(content, "\n")
@@ -192,7 +199,7 @@ func updateRegisterFile(rootDir string, cfg Config) error {
 		newLines = append(newLines, line)
 
 		// Add import after the last generator import
-		if !importAdded && strings.Contains(line, "\"github.com/external-secrets/external-secrets/generators/v1/") {
+		if !importAdded && strings.Contains(line, "\""+generatorImportPath) {
 			// Look ahead to see if next line is still an import or closing paren
 			if i+1 < len(lines) && strings.TrimSpace(lines[i+1]) == ")" {
 				newLines = append(newLines, importLine)
@@ -318,7 +325,8 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 	}
 
 	content := string(data)
-	replaceLine := fmt.Sprintf("\tgithub.com/external-secrets/external-secrets/generators/v1/%s => ./generators/v1/%s",
+	replaceLine := fmt.Sprintf("\t%s%s => ./generators/v1/%s",
+		generatorImportPath,
 		cfg.PackageName, cfg.PackageName)
 
 	// Check if already exists
@@ -334,7 +342,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 
 	// First pass: find where to insert
 	for i, line := range lines {
-		if strings.Contains(line, "github.com/external-secrets/external-secrets/generators/v1/") {
+		if strings.Contains(line, generatorImportPath) {
 			lastGeneratorIdx = i
 			// Extract the package name from the current line
 			currentPkg := extractGeneratorPackage(line)
@@ -350,7 +358,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 		// If this was the last generator and we haven't added yet, add after it
 		if i == lastGeneratorIdx && !added && lastGeneratorIdx != -1 {
 			// Check if next line is NOT a generator (meaning this is the last one)
-			if i+1 >= len(lines) || !strings.Contains(lines[i+1], "github.com/external-secrets/external-secrets/generators/v1/") {
+			if i+1 >= len(lines) || !strings.Contains(lines[i+1], generatorImportPath) {
 				newLines = append(newLines, replaceLine)
 				added = true
 			}
@@ -371,7 +379,7 @@ func updateMainGoMod(rootDir string, cfg Config) error {
 }
 
 func extractGeneratorPackage(line string) string {
-	if !strings.Contains(line, "github.com/external-secrets/external-secrets/generators/v1/") {
+	if !strings.Contains(line, generatorImportPath) {
 		return ""
 	}
 	// Extract package name from line like:
@@ -511,3 +519,55 @@ func updateRegisterKindFile(rootDir string, cfg Config) error {
 
 	return nil
 }
+
+func updateExternalSecretGeneratorRef(rootDir string, cfg Config) error {
+	// Update v1 ExternalSecret types
+	externalSecretFile := filepath.Join(rootDir, "apis", "externalsecrets", "v1", "externalsecret_types.go")
+
+	data, err := os.ReadFile(filepath.Clean(externalSecretFile))
+	if err != nil {
+		return fmt.Errorf("failed to read v1 externalsecret_types.go: %w", err)
+	}
+
+	content := string(data)
+
+	// Check if already exists
+	if strings.Contains(content, ";"+cfg.GeneratorName) {
+		fmt.Printf("⚠ Generator %s already exists in v1 GeneratorRef enum\n", cfg.GeneratorName)
+		return nil
+	}
+
+	lines := strings.Split(content, "\n")
+	newLines := make([]string, 0, len(lines))
+	updated := false
+
+	for _, line := range lines {
+		// Look for the GeneratorRef Kind enum validation line
+		// Pattern: // +kubebuilder:validation:Enum=ACRAccessToken;ClusterGenerator;...
+		if !updated && strings.Contains(line, "+kubebuilder:validation:Enum=") &&
+			strings.Contains(line, "ACRAccessToken") &&
+			strings.Contains(line, "ClusterGenerator") {
+			// This is the enum line we need to update
+			// Add the new generator to the end of the enum list
+			line = strings.TrimRight(line, "\n")
+			line = line + ";" + cfg.GeneratorName
+			updated = true
+		}
+
+		newLines = append(newLines, line)
+	}
+
+	if !updated {
+		fmt.Printf("⚠ Warning: Could not find GeneratorRef Kind enum in v1. Please manually add '%s' to the enum.\n",
+			cfg.GeneratorName)
+		return nil
+	}
+
+	if err := os.WriteFile(filepath.Clean(externalSecretFile), []byte(strings.Join(newLines, "\n")), 0o600); err != nil {
+		return fmt.Errorf("failed to write v1 externalsecret_types.go: %w", err)
+	}
+
+	fmt.Printf("✓ Updated v1 ExternalSecret GeneratorRef enum\n")
+
+	return nil
+}

+ 6 - 6
config/crds/bases/external-secrets.io_clusterexternalsecrets.yaml

@@ -459,13 +459,13 @@ spec:
                       type: object
                     type: array
                   refreshInterval:
-                    default: 1h
+                    default: 1h0m0s
                     description: |-
                       RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
                       specified as Golang Duration strings.
                       Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-                      Example values: "1h", "2h30m", "10s"
-                      May be set to zero to fetch and create it once. Defaults to 1h.
+                      Example values: "1h0m0s", "2h30m0s", "10m0s"
+                      May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
                     type: string
                   refreshPolicy:
                     description: |-
@@ -1276,13 +1276,13 @@ spec:
                       type: object
                     type: array
                   refreshInterval:
-                    default: 1h
+                    default: 1h0m0s
                     description: |-
                       RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
                       specified as Golang Duration strings.
                       Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-                      Example values: "1h", "2h30m", "10s"
-                      May be set to zero to fetch and create it once. Defaults to 1h.
+                      Example values: "1h0m0s", "2h30m0s", "10m0s"
+                      May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
                     type: string
                   refreshPolicy:
                     description: |-

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

@@ -182,7 +182,7 @@ spec:
                     - None
                     type: string
                   refreshInterval:
-                    default: 1h
+                    default: 1h0m0s
                     description: The Interval to which External Secrets will try to
                       push a secret definition
                     type: string

+ 636 - 151
config/crds/bases/external-secrets.io_clustersecretstores.yaml

@@ -59,8 +59,8 @@ spec:
             description: SecretStoreSpec defines the desired state of SecretStore.
             properties:
               conditions:
-                description: Used to constraint a ClusterSecretStore to specific namespaces.
-                  Relevant only to ClusterSecretStore
+                description: Used to constrain a ClusterSecretStore to specific namespaces.
+                  Relevant only to ClusterSecretStore.
                 items:
                   description: |-
                     ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in
@@ -370,101 +370,6 @@ spec:
                     - akeylessGWApiURL
                     - authSecretRef
                     type: object
-                  alibaba:
-                    description: Alibaba configures this store to sync secrets using
-                      Alibaba Cloud provider
-                    properties:
-                      auth:
-                        description: AlibabaAuth contains a secretRef for credentials.
-                        properties:
-                          rrsa:
-                            description: AlibabaRRSAAuth authenticates against Alibaba
-                              using RRSA.
-                            properties:
-                              oidcProviderArn:
-                                type: string
-                              oidcTokenFilePath:
-                                type: string
-                              roleArn:
-                                type: string
-                              sessionName:
-                                type: string
-                            required:
-                            - oidcProviderArn
-                            - oidcTokenFilePath
-                            - roleArn
-                            - sessionName
-                            type: object
-                          secretRef:
-                            description: AlibabaAuthSecretRef holds secret references
-                              for Alibaba credentials.
-                            properties:
-                              accessKeyIDSecretRef:
-                                description: The AccessKeyID is used for authentication
-                                properties:
-                                  key:
-                                    description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
-                                  name:
-                                    description: The name of the Secret resource being
-                                      referred to.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                                    type: string
-                                  namespace:
-                                    description: |-
-                                      The namespace of the Secret resource being referred to.
-                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
-                                    maxLength: 63
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                                    type: string
-                                type: object
-                              accessKeySecretSecretRef:
-                                description: The AccessKeySecret is used for authentication
-                                properties:
-                                  key:
-                                    description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
-                                  name:
-                                    description: The name of the Secret resource being
-                                      referred to.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                                    type: string
-                                  namespace:
-                                    description: |-
-                                      The namespace of the Secret resource being referred to.
-                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
-                                    maxLength: 63
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                                    type: string
-                                type: object
-                            required:
-                            - accessKeyIDSecretRef
-                            - accessKeySecretSecretRef
-                            type: object
-                        type: object
-                      regionID:
-                        description: Alibaba Region to be used for the provider
-                        type: string
-                    required:
-                    - auth
-                    - regionID
-                    type: object
                   aws:
                     description: AWS configures this store to sync secrets using AWS
                       Secret Manager provider
@@ -811,8 +716,11 @@ spec:
                         type: string
                       customCloudConfig:
                         description: |-
-                          CustomCloudConfig defines custom Azure Stack Hub or Azure Stack Edge endpoints.
+                          CustomCloudConfig defines custom Azure endpoints for non-standard clouds.
                           Required when EnvironmentType is AzureStackCloud.
+                          Optional for other environment types - useful for Azure China when using Workload Identity
+                          with AKS, where the OIDC issuer (login.partner.microsoftonline.cn) differs from the
+                          standard China Cloud endpoint (login.chinacloudapi.cn).
                           IMPORTANT: This feature REQUIRES UseAzureSDK to be set to true. Custom cloud
                           configuration is not supported with the legacy go-autorest SDK.
                         properties:
@@ -904,6 +812,103 @@ spec:
                     required:
                     - vaultUrl
                     type: object
+                  barbican:
+                    description: Barbican configures this store to sync secrets using
+                      the OpenStack Barbican provider
+                    properties:
+                      auth:
+                        description: BarbicanAuth contains the authentication information
+                          for Barbican.
+                        properties:
+                          password:
+                            description: BarbicanProviderPasswordRef defines a reference
+                              to a secret containing password for the Barbican provider.
+                            properties:
+                              secretRef:
+                                description: |-
+                                  SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                                  In some instances, `key` is a required field.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            required:
+                            - secretRef
+                            type: object
+                          username:
+                            description: BarbicanProviderUsernameRef defines a reference
+                              to a secret containing username for the Barbican provider.
+                            maxProperties: 1
+                            minProperties: 1
+                            properties:
+                              secretRef:
+                                description: |-
+                                  SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                                  In some instances, `key` is a required field.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                              value:
+                                type: string
+                            type: object
+                        required:
+                        - password
+                        - username
+                        type: object
+                      authURL:
+                        type: string
+                      domainName:
+                        type: string
+                      region:
+                        type: string
+                      tenantName:
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   beyondtrust:
                     description: Beyondtrust configures this store to sync secrets
                       using Password Safe provider.
@@ -1109,6 +1114,13 @@ spec:
                               time, any redirects, and reading the response body.
                               Defaults to 45 seconds.
                             type: integer
+                          decrypt:
+                            default: true
+                            description: 'When true, the response includes the decrypted
+                              password. When false, the password field is omitted.
+                              This option only applies to the SECRET retrieval type.
+                              Default: true.'
+                            type: boolean
                           retrievalType:
                             description: The secret retrieval type. SECRET = Secrets
                               Safe (credential, text, file). MANAGED_ACCOUNT = Password
@@ -1673,67 +1685,66 @@ spec:
                     - clientSecret
                     - tenant
                     type: object
-                  device42:
-                    description: Device42 configures this store to sync secrets using
-                      the Device42 provider
+                  doppler:
+                    description: Doppler configures this store to sync secrets using
+                      the Doppler provider
                     properties:
                       auth:
-                        description: Auth configures how secret-manager authenticates
-                          with a Device42 instance.
+                        description: Auth configures how the Operator authenticates
+                          with the Doppler API
                         properties:
-                          secretRef:
-                            description: Device42SecretRef contains the secret reference
-                              for accessing the Device42 instance.
+                          oidcConfig:
+                            description: OIDCConfig authenticates using Kubernetes
+                              ServiceAccount tokens via OIDC.
                             properties:
-                              credentials:
-                                description: Username / Password is used for authentication.
+                              expirationSeconds:
+                                default: 600
+                                description: |-
+                                  ExpirationSeconds sets the ServiceAccount token validity duration.
+                                  Defaults to 10 minutes.
+                                format: int64
+                                type: integer
+                              identity:
+                                description: Identity is the Doppler Service Account
+                                  Identity ID configured for OIDC authentication.
+                                type: string
+                              serviceAccountRef:
+                                description: ServiceAccountRef specifies the Kubernetes
+                                  ServiceAccount to use for authentication.
                                 properties:
-                                  key:
+                                  audiences:
                                     description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
+                                      Audience specifies the `aud` claim for the service account token
+                                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                      then this audiences will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
                                   name:
-                                    description: The name of the Secret resource being
-                                      referred to.
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
                                     maxLength: 253
                                     minLength: 1
                                     pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                                     type: string
                                   namespace:
                                     description: |-
-                                      The namespace of the Secret resource being referred to.
+                                      Namespace of the resource being referred to.
                                       Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
                                     maxLength: 63
                                     minLength: 1
                                     pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
                                     type: string
+                                required:
+                                - name
                                 type: object
+                            required:
+                            - identity
+                            - serviceAccountRef
                             type: object
-                        required:
-                        - secretRef
-                        type: object
-                      host:
-                        description: URL configures the Device42 instance URL.
-                        type: string
-                    required:
-                    - auth
-                    - host
-                    type: object
-                  doppler:
-                    description: Doppler configures this store to sync secrets using
-                      the Doppler provider
-                    properties:
-                      auth:
-                        description: Auth configures how the Operator authenticates
-                          with the Doppler API
-                        properties:
                           secretRef:
-                            description: DopplerAuthSecretRef contains the secret
-                              reference for accessing the Doppler API.
+                            description: SecretRef authenticates using a Doppler service
+                              token stored in a Kubernetes Secret.
                             properties:
                               dopplerToken:
                                 description: |-
@@ -1768,9 +1779,12 @@ spec:
                             required:
                             - dopplerToken
                             type: object
-                        required:
-                        - secretRef
                         type: object
+                        x-kubernetes-validations:
+                        - message: Exactly one of 'secretRef' or 'oidcConfig' must
+                            be specified
+                          rule: (has(self.secretRef) && !has(self.oidcConfig)) ||
+                            (!has(self.secretRef) && has(self.oidcConfig))
                       config:
                         description: Doppler config (required if not using a Service
                           Token)
@@ -1803,6 +1817,93 @@ spec:
                     required:
                     - auth
                     type: object
+                  dvls:
+                    description: DVLS configures this store to sync secrets using
+                      Devolutions Server provider
+                    properties:
+                      auth:
+                        description: Auth defines the authentication method to use.
+                        properties:
+                          secretRef:
+                            description: SecretRef contains the Application ID and
+                              Application Secret for authentication.
+                            properties:
+                              appId:
+                                description: AppID is the reference to the secret
+                                  containing the Application ID.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                              appSecret:
+                                description: AppSecret is the reference to the secret
+                                  containing the Application Secret.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            required:
+                            - appId
+                            - appSecret
+                            type: object
+                        required:
+                        - secretRef
+                        type: object
+                      insecure:
+                        description: |-
+                          Insecure allows connecting to DVLS over plain HTTP.
+                          This is NOT RECOMMENDED for production use.
+                          Set to true only if you understand the security implications.
+                        type: boolean
+                      serverUrl:
+                        description: ServerURL is the DVLS instance URL (e.g., https://dvls.example.com).
+                        type: string
+                    required:
+                    - auth
+                    - serverUrl
+                    type: object
                   fake:
                     description: Fake configures a store with static key/value pairs
                     properties:
@@ -2102,7 +2203,7 @@ spec:
                     type: object
                   github:
                     description: |-
-                      Github configures this store to push GitHub Action secrets using GitHub API provider.
+                      Github configures this store to push GitHub Actions secrets using the GitHub API provider.
                       Note: This provider only supports write operations (PushSecret) and cannot fetch secrets from GitHub
                     properties:
                       appID:
@@ -2320,6 +2421,9 @@ spec:
                             description: IBMAuthSecretRef contains the secret reference
                               for IBM Cloud API key authentication.
                             properties:
+                              iamEndpoint:
+                                description: The IAM endpoint used to obain a token
+                                type: string
                               secretApiKeySecretRef:
                                 description: The SecretAccessKey is used for authentication
                                 properties:
@@ -3112,6 +3216,51 @@ spec:
                             - clientSecret
                             type: object
                         type: object
+                      caBundle:
+                        description: |-
+                          CABundle is a PEM-encoded CA certificate bundle used to validate
+                          the Infisical server's TLS certificate. Mutually exclusive with CAProvider.
+                        format: byte
+                        type: string
+                      caProvider:
+                        description: |-
+                          CAProvider is a reference to a Secret or ConfigMap that contains a CA certificate.
+                          The certificate is used to validate the Infisical server's TLS certificate.
+                          Mutually exclusive with CABundle.
+                        properties:
+                          key:
+                            description: The key where the CA certificate can be found
+                              in the Secret or ConfigMap.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the object located at the provider
+                              type.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace the Provider type is in.
+                              Can only be defined when used in a ClusterSecretStore.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                          type:
+                            description: The type of provider to use such as "Secret",
+                              or "ConfigMap".
+                            enum:
+                            - Secret
+                            - ConfigMap
+                            type: string
+                        required:
+                        - name
+                        - type
+                        type: object
                       hostAPI:
                         default: https://app.infisical.com/api
                         description: HostAPI specifies the base URL of the Infisical
@@ -3412,6 +3561,127 @@ spec:
                             type: string
                         type: object
                     type: object
+                  nebiusmysterybox:
+                    description: NebiusMysterybox configures this store to sync secrets
+                      using NebiusMysterybox provider
+                    properties:
+                      apiDomain:
+                        description: NebiusMysterybox API endpoint
+                        type: string
+                      auth:
+                        description: Auth defines parameters to authenticate in MysteryBox
+                        properties:
+                          serviceAccountCredsSecretRef:
+                            description: |-
+                              ServiceAccountCreds references a Kubernetes Secret key that contains a JSON
+                              document with service account credentials used to get an IAM token.
+
+                              Expected JSON structure:
+                              {
+                                "subject-credentials": {
+                                  "alg": "RS256",
+                                  "private-key": "-----BEGIN PRIVATE KEY-----\n<private-key>\n-----END PRIVATE KEY-----\n",
+                                  "kid": "<public-key-id>",
+                                  "iss": "<issuer-service-account-id>",
+                                  "sub": "<subject-service-account-id>"
+                                }
+                              }
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                          tokenSecretRef:
+                            description: Token authenticates with Nebius Mysterybox
+                              by presenting a token.
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                        type: object
+                        x-kubernetes-validations:
+                        - message: either serviceAccountCredsSecretRef or tokenSecretRef
+                            must be set
+                          rule: has(self.serviceAccountCredsSecretRef) || has(self.tokenSecretRef)
+                      caProvider:
+                        description: The provider for the CA bundle to use to validate
+                          NebiusMysterybox server certificate.
+                        properties:
+                          certSecretRef:
+                            description: |-
+                              SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                              In some instances, `key` is a required field.
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                        type: object
+                    required:
+                    - apiDomain
+                    - auth
+                    type: object
                   ngrok:
                     description: Ngrok configures this store to sync secrets using
                       the ngrok provider.
@@ -3665,6 +3935,28 @@ spec:
                         required:
                         - serviceAccountSecretRef
                         type: object
+                      cache:
+                        description: |-
+                          Cache configures client-side caching for read operations (GetSecret, GetSecretMap).
+                          When enabled, secrets are cached with the specified TTL.
+                          Write operations (PushSecret, DeleteSecret) automatically invalidate relevant cache entries.
+                          If omitted, caching is disabled (default).
+                          cache: {} is a valid option to set.
+                        properties:
+                          maxSize:
+                            default: 100
+                            description: |-
+                              MaxSize is the maximum number of secrets to cache.
+                              When the cache is full, least-recently-used entries are evicted.
+                            minimum: 1
+                            type: integer
+                          ttl:
+                            default: 5m
+                            description: |-
+                              TTL is the time-to-live for cached secrets.
+                              Format: duration string (e.g., "5m", "1h", "30s")
+                            type: string
+                        type: object
                       integrationInfo:
                         description: |-
                           IntegrationInfo specifies the name and version of the integration built using the 1Password Go SDK.
@@ -4077,7 +4369,8 @@ spec:
                     - project
                     type: object
                   scaleway:
-                    description: Scaleway
+                    description: Scaleway configures this store to sync secrets using
+                      the Scaleway provider.
                     properties:
                       accessKey:
                         description: AccessKey is the non-secret part of the api key.
@@ -4173,6 +4466,50 @@ spec:
                       SecretServer configures this store to sync secrets using SecretServer provider
                       https://docs.delinea.com/online-help/secret-server/start.htm
                     properties:
+                      caBundle:
+                        description: |-
+                          PEM/base64 encoded CA bundle used to validate Secret ServerURL. Only used
+                          if the ServerURL URL is using HTTPS protocol. If not set the system root certificates
+                          are used to validate the TLS connection.
+                        format: byte
+                        type: string
+                      caProvider:
+                        description: The provider for the CA bundle to use to validate
+                          Secret ServerURL certificate.
+                        properties:
+                          key:
+                            description: The key where the CA certificate can be found
+                              in the Secret or ConfigMap.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the object located at the provider
+                              type.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace the Provider type is in.
+                              Can only be defined when used in a ClusterSecretStore.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                          type:
+                            description: The type of provider to use such as "Secret",
+                              or "ConfigMap".
+                            enum:
+                            - Secret
+                            - ConfigMap
+                            type: string
+                        required:
+                        - name
+                        - type
+                        type: object
                       domain:
                         description: Domain is the secret server domain.
                         type: string
@@ -4319,7 +4656,7 @@ spec:
                     type: object
                   vault:
                     description: Vault configures this store to sync secrets using
-                      Hashi provider
+                      the HashiCorp Vault provider.
                     properties:
                       auth:
                         description: Auth configures how secret-manager authenticates
@@ -4477,6 +4814,146 @@ spec:
                                     type: string
                                 type: object
                             type: object
+                          gcp:
+                            description: |-
+                              Gcp authenticates with Vault using Google Cloud Platform authentication method
+                              GCP authentication method
+                            properties:
+                              location:
+                                description: Location optionally defines a location/region
+                                  for the secret
+                                type: string
+                              path:
+                                default: gcp
+                                description: 'Path where the GCP auth method is enabled
+                                  in Vault, e.g: "gcp"'
+                                type: string
+                              projectID:
+                                description: Project ID of the Google Cloud Platform
+                                  project
+                                type: string
+                              role:
+                                description: Vault Role. In Vault, a role describes
+                                  an identity with a set of permissions, groups, or
+                                  policies you want to attach to a user of the secrets
+                                  engine.
+                                type: string
+                              secretRef:
+                                description: Specify credentials in a Secret object
+                                properties:
+                                  secretAccessKeySecretRef:
+                                    description: The SecretAccessKey is used for authentication
+                                    properties:
+                                      key:
+                                        description: |-
+                                          A key in the referenced Secret.
+                                          Some instances of this field may be defaulted, in others it may be required.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[-._a-zA-Z0-9]+$
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                        type: string
+                                      namespace:
+                                        description: |-
+                                          The namespace of the Secret resource being referred to.
+                                          Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                        maxLength: 63
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                        type: string
+                                    type: object
+                                type: object
+                              serviceAccountRef:
+                                description: ServiceAccountRef to a service account
+                                  for impersonation
+                                properties:
+                                  audiences:
+                                    description: |-
+                                      Audience specifies the `aud` claim for the service account token
+                                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                      then this audiences will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
+                                  name:
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      Namespace of the resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                              workloadIdentity:
+                                description: Specify a service account with Workload
+                                  Identity
+                                properties:
+                                  clusterLocation:
+                                    description: |-
+                                      ClusterLocation is the location of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  clusterName:
+                                    description: |-
+                                      ClusterName is the name of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  clusterProjectID:
+                                    description: |-
+                                      ClusterProjectID is the project ID of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  serviceAccountRef:
+                                    description: ServiceAccountSelector is a reference
+                                      to a ServiceAccount resource.
+                                    properties:
+                                      audiences:
+                                        description: |-
+                                          Audience specifies the `aud` claim for the service account token
+                                          If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                          then this audiences will be appended to the list
+                                        items:
+                                          type: string
+                                        type: array
+                                      name:
+                                        description: The name of the ServiceAccount
+                                          resource being referred to.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                        type: string
+                                      namespace:
+                                        description: |-
+                                          Namespace of the resource being referred to.
+                                          Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                        maxLength: 63
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                        type: string
+                                    required:
+                                    - name
+                                    type: object
+                                required:
+                                - serviceAccountRef
+                                type: object
+                            required:
+                            - role
+                            type: object
                           iam:
                             description: |-
                               Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials
@@ -5637,7 +6114,7 @@ spec:
                   Empty or 0 will default to the controller config.
                 type: integer
               retrySettings:
-                description: Used to configure http retries if failed
+                description: Used to configure HTTP retries on failures.
                 properties:
                   maxRetries:
                     format: int32
@@ -5725,8 +6202,8 @@ spec:
             description: SecretStoreSpec defines the desired state of SecretStore.
             properties:
               conditions:
-                description: Used to constraint a ClusterSecretStore to specific namespaces.
-                  Relevant only to ClusterSecretStore
+                description: Used to constrain a ClusterSecretStore to specific namespaces.
+                  Relevant only to ClusterSecretStore.
                 items:
                   description: |-
                     ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in
@@ -6738,6 +7215,13 @@ spec:
                               time, any redirects, and reading the response body.
                               Defaults to 45 seconds.
                             type: integer
+                          decrypt:
+                            default: true
+                            description: 'When true, the response includes the decrypted
+                              password. When false, the password field is omitted.
+                              This option only applies to the SECRET retrieval type.
+                              Default: true.'
+                            type: boolean
                           retrievalType:
                             description: The secret retrieval type. SECRET = Secrets
                               Safe (credential, text, file). MANAGED_ACCOUNT = Password
@@ -7597,8 +8081,8 @@ spec:
                         type: string
                     type: object
                   github:
-                    description: Github configures this store to push Github Action
-                      secrets using Github API provider
+                    description: Github configures this store to push GitHub Actions
+                      secrets using the GitHub API provider.
                     properties:
                       appID:
                         description: appID specifies the Github APP that will be used
@@ -8765,7 +9249,8 @@ spec:
                     - project
                     type: object
                   scaleway:
-                    description: Scaleway
+                    description: Scaleway configures this store to sync secrets using
+                      the Scaleway provider.
                     properties:
                       accessKey:
                         description: AccessKey is the non-secret part of the api key.
@@ -9004,7 +9489,7 @@ spec:
                     type: object
                   vault:
                     description: Vault configures this store to sync secrets using
-                      Hashi provider
+                      the HashiCorp Vault provider.
                     properties:
                       auth:
                         description: Auth configures how secret-manager authenticates
@@ -10147,7 +10632,7 @@ spec:
                   Empty or 0 will default to the controller config.
                 type: integer
               retrySettings:
-                description: Used to configure http retries if failed
+                description: Used to configure HTTP retries on failures.
                 properties:
                   maxRetries:
                     description: MaxRetries is the maximum number of retry attempts.

+ 6 - 6
config/crds/bases/external-secrets.io_externalsecrets.yaml

@@ -439,13 +439,13 @@ spec:
                   type: object
                 type: array
               refreshInterval:
-                default: 1h
+                default: 1h0m0s
                 description: |-
                   RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
                   specified as Golang Duration strings.
                   Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-                  Example values: "1h", "2h30m", "10s"
-                  May be set to zero to fetch and create it once. Defaults to 1h.
+                  Example values: "1h0m0s", "2h30m0s", "10m0s"
+                  May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
                 type: string
               refreshPolicy:
                 description: |-
@@ -1122,13 +1122,13 @@ spec:
                   type: object
                 type: array
               refreshInterval:
-                default: 1h
+                default: 1h0m0s
                 description: |-
                   RefreshInterval is the amount of time before the values are read again from the SecretStore provider,
                   specified as Golang Duration strings.
                   Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
-                  Example values: "1h", "2h30m", "10s"
-                  May be set to zero to fetch and create it once. Defaults to 1h.
+                  Example values: "1h0m0s", "2h30m0s", "10m0s"
+                  May be set to "0s" to fetch and create it once. Defaults to 1h0m0s.
                 type: string
               refreshPolicy:
                 description: |-

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

@@ -104,7 +104,7 @@ spec:
                 - None
                 type: string
               refreshInterval:
-                default: 1h
+                default: 1h0m0s
                 description: The Interval to which External Secrets will try to push
                   a secret definition
                 type: string

+ 636 - 151
config/crds/bases/external-secrets.io_secretstores.yaml

@@ -59,8 +59,8 @@ spec:
             description: SecretStoreSpec defines the desired state of SecretStore.
             properties:
               conditions:
-                description: Used to constraint a ClusterSecretStore to specific namespaces.
-                  Relevant only to ClusterSecretStore
+                description: Used to constrain a ClusterSecretStore to specific namespaces.
+                  Relevant only to ClusterSecretStore.
                 items:
                   description: |-
                     ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in
@@ -370,101 +370,6 @@ spec:
                     - akeylessGWApiURL
                     - authSecretRef
                     type: object
-                  alibaba:
-                    description: Alibaba configures this store to sync secrets using
-                      Alibaba Cloud provider
-                    properties:
-                      auth:
-                        description: AlibabaAuth contains a secretRef for credentials.
-                        properties:
-                          rrsa:
-                            description: AlibabaRRSAAuth authenticates against Alibaba
-                              using RRSA.
-                            properties:
-                              oidcProviderArn:
-                                type: string
-                              oidcTokenFilePath:
-                                type: string
-                              roleArn:
-                                type: string
-                              sessionName:
-                                type: string
-                            required:
-                            - oidcProviderArn
-                            - oidcTokenFilePath
-                            - roleArn
-                            - sessionName
-                            type: object
-                          secretRef:
-                            description: AlibabaAuthSecretRef holds secret references
-                              for Alibaba credentials.
-                            properties:
-                              accessKeyIDSecretRef:
-                                description: The AccessKeyID is used for authentication
-                                properties:
-                                  key:
-                                    description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
-                                  name:
-                                    description: The name of the Secret resource being
-                                      referred to.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                                    type: string
-                                  namespace:
-                                    description: |-
-                                      The namespace of the Secret resource being referred to.
-                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
-                                    maxLength: 63
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                                    type: string
-                                type: object
-                              accessKeySecretSecretRef:
-                                description: The AccessKeySecret is used for authentication
-                                properties:
-                                  key:
-                                    description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
-                                  name:
-                                    description: The name of the Secret resource being
-                                      referred to.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                                    type: string
-                                  namespace:
-                                    description: |-
-                                      The namespace of the Secret resource being referred to.
-                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
-                                    maxLength: 63
-                                    minLength: 1
-                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
-                                    type: string
-                                type: object
-                            required:
-                            - accessKeyIDSecretRef
-                            - accessKeySecretSecretRef
-                            type: object
-                        type: object
-                      regionID:
-                        description: Alibaba Region to be used for the provider
-                        type: string
-                    required:
-                    - auth
-                    - regionID
-                    type: object
                   aws:
                     description: AWS configures this store to sync secrets using AWS
                       Secret Manager provider
@@ -811,8 +716,11 @@ spec:
                         type: string
                       customCloudConfig:
                         description: |-
-                          CustomCloudConfig defines custom Azure Stack Hub or Azure Stack Edge endpoints.
+                          CustomCloudConfig defines custom Azure endpoints for non-standard clouds.
                           Required when EnvironmentType is AzureStackCloud.
+                          Optional for other environment types - useful for Azure China when using Workload Identity
+                          with AKS, where the OIDC issuer (login.partner.microsoftonline.cn) differs from the
+                          standard China Cloud endpoint (login.chinacloudapi.cn).
                           IMPORTANT: This feature REQUIRES UseAzureSDK to be set to true. Custom cloud
                           configuration is not supported with the legacy go-autorest SDK.
                         properties:
@@ -904,6 +812,103 @@ spec:
                     required:
                     - vaultUrl
                     type: object
+                  barbican:
+                    description: Barbican configures this store to sync secrets using
+                      the OpenStack Barbican provider
+                    properties:
+                      auth:
+                        description: BarbicanAuth contains the authentication information
+                          for Barbican.
+                        properties:
+                          password:
+                            description: BarbicanProviderPasswordRef defines a reference
+                              to a secret containing password for the Barbican provider.
+                            properties:
+                              secretRef:
+                                description: |-
+                                  SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                                  In some instances, `key` is a required field.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            required:
+                            - secretRef
+                            type: object
+                          username:
+                            description: BarbicanProviderUsernameRef defines a reference
+                              to a secret containing username for the Barbican provider.
+                            maxProperties: 1
+                            minProperties: 1
+                            properties:
+                              secretRef:
+                                description: |-
+                                  SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                                  In some instances, `key` is a required field.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                              value:
+                                type: string
+                            type: object
+                        required:
+                        - password
+                        - username
+                        type: object
+                      authURL:
+                        type: string
+                      domainName:
+                        type: string
+                      region:
+                        type: string
+                      tenantName:
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   beyondtrust:
                     description: Beyondtrust configures this store to sync secrets
                       using Password Safe provider.
@@ -1109,6 +1114,13 @@ spec:
                               time, any redirects, and reading the response body.
                               Defaults to 45 seconds.
                             type: integer
+                          decrypt:
+                            default: true
+                            description: 'When true, the response includes the decrypted
+                              password. When false, the password field is omitted.
+                              This option only applies to the SECRET retrieval type.
+                              Default: true.'
+                            type: boolean
                           retrievalType:
                             description: The secret retrieval type. SECRET = Secrets
                               Safe (credential, text, file). MANAGED_ACCOUNT = Password
@@ -1673,67 +1685,66 @@ spec:
                     - clientSecret
                     - tenant
                     type: object
-                  device42:
-                    description: Device42 configures this store to sync secrets using
-                      the Device42 provider
+                  doppler:
+                    description: Doppler configures this store to sync secrets using
+                      the Doppler provider
                     properties:
                       auth:
-                        description: Auth configures how secret-manager authenticates
-                          with a Device42 instance.
+                        description: Auth configures how the Operator authenticates
+                          with the Doppler API
                         properties:
-                          secretRef:
-                            description: Device42SecretRef contains the secret reference
-                              for accessing the Device42 instance.
+                          oidcConfig:
+                            description: OIDCConfig authenticates using Kubernetes
+                              ServiceAccount tokens via OIDC.
                             properties:
-                              credentials:
-                                description: Username / Password is used for authentication.
+                              expirationSeconds:
+                                default: 600
+                                description: |-
+                                  ExpirationSeconds sets the ServiceAccount token validity duration.
+                                  Defaults to 10 minutes.
+                                format: int64
+                                type: integer
+                              identity:
+                                description: Identity is the Doppler Service Account
+                                  Identity ID configured for OIDC authentication.
+                                type: string
+                              serviceAccountRef:
+                                description: ServiceAccountRef specifies the Kubernetes
+                                  ServiceAccount to use for authentication.
                                 properties:
-                                  key:
+                                  audiences:
                                     description: |-
-                                      A key in the referenced Secret.
-                                      Some instances of this field may be defaulted, in others it may be required.
-                                    maxLength: 253
-                                    minLength: 1
-                                    pattern: ^[-._a-zA-Z0-9]+$
-                                    type: string
+                                      Audience specifies the `aud` claim for the service account token
+                                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                      then this audiences will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
                                   name:
-                                    description: The name of the Secret resource being
-                                      referred to.
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
                                     maxLength: 253
                                     minLength: 1
                                     pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                                     type: string
                                   namespace:
                                     description: |-
-                                      The namespace of the Secret resource being referred to.
+                                      Namespace of the resource being referred to.
                                       Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
                                     maxLength: 63
                                     minLength: 1
                                     pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
                                     type: string
+                                required:
+                                - name
                                 type: object
+                            required:
+                            - identity
+                            - serviceAccountRef
                             type: object
-                        required:
-                        - secretRef
-                        type: object
-                      host:
-                        description: URL configures the Device42 instance URL.
-                        type: string
-                    required:
-                    - auth
-                    - host
-                    type: object
-                  doppler:
-                    description: Doppler configures this store to sync secrets using
-                      the Doppler provider
-                    properties:
-                      auth:
-                        description: Auth configures how the Operator authenticates
-                          with the Doppler API
-                        properties:
                           secretRef:
-                            description: DopplerAuthSecretRef contains the secret
-                              reference for accessing the Doppler API.
+                            description: SecretRef authenticates using a Doppler service
+                              token stored in a Kubernetes Secret.
                             properties:
                               dopplerToken:
                                 description: |-
@@ -1768,9 +1779,12 @@ spec:
                             required:
                             - dopplerToken
                             type: object
-                        required:
-                        - secretRef
                         type: object
+                        x-kubernetes-validations:
+                        - message: Exactly one of 'secretRef' or 'oidcConfig' must
+                            be specified
+                          rule: (has(self.secretRef) && !has(self.oidcConfig)) ||
+                            (!has(self.secretRef) && has(self.oidcConfig))
                       config:
                         description: Doppler config (required if not using a Service
                           Token)
@@ -1803,6 +1817,93 @@ spec:
                     required:
                     - auth
                     type: object
+                  dvls:
+                    description: DVLS configures this store to sync secrets using
+                      Devolutions Server provider
+                    properties:
+                      auth:
+                        description: Auth defines the authentication method to use.
+                        properties:
+                          secretRef:
+                            description: SecretRef contains the Application ID and
+                              Application Secret for authentication.
+                            properties:
+                              appId:
+                                description: AppID is the reference to the secret
+                                  containing the Application ID.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                              appSecret:
+                                description: AppSecret is the reference to the secret
+                                  containing the Application Secret.
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            required:
+                            - appId
+                            - appSecret
+                            type: object
+                        required:
+                        - secretRef
+                        type: object
+                      insecure:
+                        description: |-
+                          Insecure allows connecting to DVLS over plain HTTP.
+                          This is NOT RECOMMENDED for production use.
+                          Set to true only if you understand the security implications.
+                        type: boolean
+                      serverUrl:
+                        description: ServerURL is the DVLS instance URL (e.g., https://dvls.example.com).
+                        type: string
+                    required:
+                    - auth
+                    - serverUrl
+                    type: object
                   fake:
                     description: Fake configures a store with static key/value pairs
                     properties:
@@ -2102,7 +2203,7 @@ spec:
                     type: object
                   github:
                     description: |-
-                      Github configures this store to push GitHub Action secrets using GitHub API provider.
+                      Github configures this store to push GitHub Actions secrets using the GitHub API provider.
                       Note: This provider only supports write operations (PushSecret) and cannot fetch secrets from GitHub
                     properties:
                       appID:
@@ -2320,6 +2421,9 @@ spec:
                             description: IBMAuthSecretRef contains the secret reference
                               for IBM Cloud API key authentication.
                             properties:
+                              iamEndpoint:
+                                description: The IAM endpoint used to obain a token
+                                type: string
                               secretApiKeySecretRef:
                                 description: The SecretAccessKey is used for authentication
                                 properties:
@@ -3112,6 +3216,51 @@ spec:
                             - clientSecret
                             type: object
                         type: object
+                      caBundle:
+                        description: |-
+                          CABundle is a PEM-encoded CA certificate bundle used to validate
+                          the Infisical server's TLS certificate. Mutually exclusive with CAProvider.
+                        format: byte
+                        type: string
+                      caProvider:
+                        description: |-
+                          CAProvider is a reference to a Secret or ConfigMap that contains a CA certificate.
+                          The certificate is used to validate the Infisical server's TLS certificate.
+                          Mutually exclusive with CABundle.
+                        properties:
+                          key:
+                            description: The key where the CA certificate can be found
+                              in the Secret or ConfigMap.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the object located at the provider
+                              type.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace the Provider type is in.
+                              Can only be defined when used in a ClusterSecretStore.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                          type:
+                            description: The type of provider to use such as "Secret",
+                              or "ConfigMap".
+                            enum:
+                            - Secret
+                            - ConfigMap
+                            type: string
+                        required:
+                        - name
+                        - type
+                        type: object
                       hostAPI:
                         default: https://app.infisical.com/api
                         description: HostAPI specifies the base URL of the Infisical
@@ -3412,6 +3561,127 @@ spec:
                             type: string
                         type: object
                     type: object
+                  nebiusmysterybox:
+                    description: NebiusMysterybox configures this store to sync secrets
+                      using NebiusMysterybox provider
+                    properties:
+                      apiDomain:
+                        description: NebiusMysterybox API endpoint
+                        type: string
+                      auth:
+                        description: Auth defines parameters to authenticate in MysteryBox
+                        properties:
+                          serviceAccountCredsSecretRef:
+                            description: |-
+                              ServiceAccountCreds references a Kubernetes Secret key that contains a JSON
+                              document with service account credentials used to get an IAM token.
+
+                              Expected JSON structure:
+                              {
+                                "subject-credentials": {
+                                  "alg": "RS256",
+                                  "private-key": "-----BEGIN PRIVATE KEY-----\n<private-key>\n-----END PRIVATE KEY-----\n",
+                                  "kid": "<public-key-id>",
+                                  "iss": "<issuer-service-account-id>",
+                                  "sub": "<subject-service-account-id>"
+                                }
+                              }
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                          tokenSecretRef:
+                            description: Token authenticates with Nebius Mysterybox
+                              by presenting a token.
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                        type: object
+                        x-kubernetes-validations:
+                        - message: either serviceAccountCredsSecretRef or tokenSecretRef
+                            must be set
+                          rule: has(self.serviceAccountCredsSecretRef) || has(self.tokenSecretRef)
+                      caProvider:
+                        description: The provider for the CA bundle to use to validate
+                          NebiusMysterybox server certificate.
+                        properties:
+                          certSecretRef:
+                            description: |-
+                              SecretKeySelector is a reference to a specific 'key' within a Secret resource.
+                              In some instances, `key` is a required field.
+                            properties:
+                              key:
+                                description: |-
+                                  A key in the referenced Secret.
+                                  Some instances of this field may be defaulted, in others it may be required.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[-._a-zA-Z0-9]+$
+                                type: string
+                              name:
+                                description: The name of the Secret resource being
+                                  referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  The namespace of the Secret resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            type: object
+                        type: object
+                    required:
+                    - apiDomain
+                    - auth
+                    type: object
                   ngrok:
                     description: Ngrok configures this store to sync secrets using
                       the ngrok provider.
@@ -3665,6 +3935,28 @@ spec:
                         required:
                         - serviceAccountSecretRef
                         type: object
+                      cache:
+                        description: |-
+                          Cache configures client-side caching for read operations (GetSecret, GetSecretMap).
+                          When enabled, secrets are cached with the specified TTL.
+                          Write operations (PushSecret, DeleteSecret) automatically invalidate relevant cache entries.
+                          If omitted, caching is disabled (default).
+                          cache: {} is a valid option to set.
+                        properties:
+                          maxSize:
+                            default: 100
+                            description: |-
+                              MaxSize is the maximum number of secrets to cache.
+                              When the cache is full, least-recently-used entries are evicted.
+                            minimum: 1
+                            type: integer
+                          ttl:
+                            default: 5m
+                            description: |-
+                              TTL is the time-to-live for cached secrets.
+                              Format: duration string (e.g., "5m", "1h", "30s")
+                            type: string
+                        type: object
                       integrationInfo:
                         description: |-
                           IntegrationInfo specifies the name and version of the integration built using the 1Password Go SDK.
@@ -4077,7 +4369,8 @@ spec:
                     - project
                     type: object
                   scaleway:
-                    description: Scaleway
+                    description: Scaleway configures this store to sync secrets using
+                      the Scaleway provider.
                     properties:
                       accessKey:
                         description: AccessKey is the non-secret part of the api key.
@@ -4173,6 +4466,50 @@ spec:
                       SecretServer configures this store to sync secrets using SecretServer provider
                       https://docs.delinea.com/online-help/secret-server/start.htm
                     properties:
+                      caBundle:
+                        description: |-
+                          PEM/base64 encoded CA bundle used to validate Secret ServerURL. Only used
+                          if the ServerURL URL is using HTTPS protocol. If not set the system root certificates
+                          are used to validate the TLS connection.
+                        format: byte
+                        type: string
+                      caProvider:
+                        description: The provider for the CA bundle to use to validate
+                          Secret ServerURL certificate.
+                        properties:
+                          key:
+                            description: The key where the CA certificate can be found
+                              in the Secret or ConfigMap.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[-._a-zA-Z0-9]+$
+                            type: string
+                          name:
+                            description: The name of the object located at the provider
+                              type.
+                            maxLength: 253
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          namespace:
+                            description: |-
+                              The namespace the Provider type is in.
+                              Can only be defined when used in a ClusterSecretStore.
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                          type:
+                            description: The type of provider to use such as "Secret",
+                              or "ConfigMap".
+                            enum:
+                            - Secret
+                            - ConfigMap
+                            type: string
+                        required:
+                        - name
+                        - type
+                        type: object
                       domain:
                         description: Domain is the secret server domain.
                         type: string
@@ -4319,7 +4656,7 @@ spec:
                     type: object
                   vault:
                     description: Vault configures this store to sync secrets using
-                      Hashi provider
+                      the HashiCorp Vault provider.
                     properties:
                       auth:
                         description: Auth configures how secret-manager authenticates
@@ -4477,6 +4814,146 @@ spec:
                                     type: string
                                 type: object
                             type: object
+                          gcp:
+                            description: |-
+                              Gcp authenticates with Vault using Google Cloud Platform authentication method
+                              GCP authentication method
+                            properties:
+                              location:
+                                description: Location optionally defines a location/region
+                                  for the secret
+                                type: string
+                              path:
+                                default: gcp
+                                description: 'Path where the GCP auth method is enabled
+                                  in Vault, e.g: "gcp"'
+                                type: string
+                              projectID:
+                                description: Project ID of the Google Cloud Platform
+                                  project
+                                type: string
+                              role:
+                                description: Vault Role. In Vault, a role describes
+                                  an identity with a set of permissions, groups, or
+                                  policies you want to attach to a user of the secrets
+                                  engine.
+                                type: string
+                              secretRef:
+                                description: Specify credentials in a Secret object
+                                properties:
+                                  secretAccessKeySecretRef:
+                                    description: The SecretAccessKey is used for authentication
+                                    properties:
+                                      key:
+                                        description: |-
+                                          A key in the referenced Secret.
+                                          Some instances of this field may be defaulted, in others it may be required.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[-._a-zA-Z0-9]+$
+                                        type: string
+                                      name:
+                                        description: The name of the Secret resource
+                                          being referred to.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                        type: string
+                                      namespace:
+                                        description: |-
+                                          The namespace of the Secret resource being referred to.
+                                          Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                        maxLength: 63
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                        type: string
+                                    type: object
+                                type: object
+                              serviceAccountRef:
+                                description: ServiceAccountRef to a service account
+                                  for impersonation
+                                properties:
+                                  audiences:
+                                    description: |-
+                                      Audience specifies the `aud` claim for the service account token
+                                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                      then this audiences will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
+                                  name:
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      Namespace of the resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                              workloadIdentity:
+                                description: Specify a service account with Workload
+                                  Identity
+                                properties:
+                                  clusterLocation:
+                                    description: |-
+                                      ClusterLocation is the location of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  clusterName:
+                                    description: |-
+                                      ClusterName is the name of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  clusterProjectID:
+                                    description: |-
+                                      ClusterProjectID is the project ID of the cluster
+                                      If not specified, it fetches information from the metadata server
+                                    type: string
+                                  serviceAccountRef:
+                                    description: ServiceAccountSelector is a reference
+                                      to a ServiceAccount resource.
+                                    properties:
+                                      audiences:
+                                        description: |-
+                                          Audience specifies the `aud` claim for the service account token
+                                          If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                          then this audiences will be appended to the list
+                                        items:
+                                          type: string
+                                        type: array
+                                      name:
+                                        description: The name of the ServiceAccount
+                                          resource being referred to.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                        type: string
+                                      namespace:
+                                        description: |-
+                                          Namespace of the resource being referred to.
+                                          Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                        maxLength: 63
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                        type: string
+                                    required:
+                                    - name
+                                    type: object
+                                required:
+                                - serviceAccountRef
+                                type: object
+                            required:
+                            - role
+                            type: object
                           iam:
                             description: |-
                               Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials
@@ -5637,7 +6114,7 @@ spec:
                   Empty or 0 will default to the controller config.
                 type: integer
               retrySettings:
-                description: Used to configure http retries if failed
+                description: Used to configure HTTP retries on failures.
                 properties:
                   maxRetries:
                     format: int32
@@ -5725,8 +6202,8 @@ spec:
             description: SecretStoreSpec defines the desired state of SecretStore.
             properties:
               conditions:
-                description: Used to constraint a ClusterSecretStore to specific namespaces.
-                  Relevant only to ClusterSecretStore
+                description: Used to constrain a ClusterSecretStore to specific namespaces.
+                  Relevant only to ClusterSecretStore.
                 items:
                   description: |-
                     ClusterSecretStoreCondition describes a condition by which to choose namespaces to process ExternalSecrets in
@@ -6738,6 +7215,13 @@ spec:
                               time, any redirects, and reading the response body.
                               Defaults to 45 seconds.
                             type: integer
+                          decrypt:
+                            default: true
+                            description: 'When true, the response includes the decrypted
+                              password. When false, the password field is omitted.
+                              This option only applies to the SECRET retrieval type.
+                              Default: true.'
+                            type: boolean
                           retrievalType:
                             description: The secret retrieval type. SECRET = Secrets
                               Safe (credential, text, file). MANAGED_ACCOUNT = Password
@@ -7597,8 +8081,8 @@ spec:
                         type: string
                     type: object
                   github:
-                    description: Github configures this store to push Github Action
-                      secrets using Github API provider
+                    description: Github configures this store to push GitHub Actions
+                      secrets using the GitHub API provider.
                     properties:
                       appID:
                         description: appID specifies the Github APP that will be used
@@ -8765,7 +9249,8 @@ spec:
                     - project
                     type: object
                   scaleway:
-                    description: Scaleway
+                    description: Scaleway configures this store to sync secrets using
+                      the Scaleway provider.
                     properties:
                       accessKey:
                         description: AccessKey is the non-secret part of the api key.
@@ -9004,7 +9489,7 @@ spec:
                     type: object
                   vault:
                     description: Vault configures this store to sync secrets using
-                      Hashi provider
+                      the HashiCorp Vault provider.
                     properties:
                       auth:
                         description: Auth configures how secret-manager authenticates
@@ -10147,7 +10632,7 @@ spec:
                   Empty or 0 will default to the controller config.
                 type: integer
               retrySettings:
-                description: Used to configure http retries if failed
+                description: Used to configure HTTP retries on failures.
                 properties:
                   maxRetries:
                     description: MaxRetries is the maximum number of retry attempts.

+ 154 - 2
config/crds/bases/generators.external-secrets.io_clustergenerators.yaml

@@ -899,6 +899,14 @@ spec:
                         default: false
                         description: Set NoUpper to disable uppercase characters
                         type: boolean
+                      secretKeys:
+                        description: |-
+                          SecretKeys defines the keys that will be populated with generated passwords.
+                          Defaults to "password" when not set.
+                        items:
+                          type: string
+                        minItems: 1
+                        type: array
                       symbolCharacters:
                         description: |-
                           SymbolCharacters specifies the special characters that should be used
@@ -969,17 +977,20 @@ spec:
                         type: string
                       keySize:
                         description: |-
-                          KeySize specifies the key size for RSA keys (default: 2048)
+                          KeySize specifies the key size for RSA keys (default: 2048) and ECDSA keys (default: 256).
                           For RSA keys: 2048, 3072, 4096
+                          For ECDSA keys: 256, 384, 521
                           Ignored for ed25519 keys
                         maximum: 8192
                         minimum: 256
                         type: integer
                       keyType:
                         default: rsa
-                        description: KeyType specifies the SSH key type (rsa, ed25519)
+                        description: KeyType specifies the SSH key type (rsa, ecdsa,
+                          ed25519)
                         enum:
                         - rsa
+                        - ecdsa
                         - ed25519
                         type: string
                     type: object
@@ -1332,6 +1343,147 @@ spec:
                                         type: string
                                     type: object
                                 type: object
+                              gcp:
+                                description: |-
+                                  Gcp authenticates with Vault using Google Cloud Platform authentication method
+                                  GCP authentication method
+                                properties:
+                                  location:
+                                    description: Location optionally defines a location/region
+                                      for the secret
+                                    type: string
+                                  path:
+                                    default: gcp
+                                    description: 'Path where the GCP auth method is
+                                      enabled in Vault, e.g: "gcp"'
+                                    type: string
+                                  projectID:
+                                    description: Project ID of the Google Cloud Platform
+                                      project
+                                    type: string
+                                  role:
+                                    description: Vault Role. In Vault, a role describes
+                                      an identity with a set of permissions, groups,
+                                      or policies you want to attach to a user of
+                                      the secrets engine.
+                                    type: string
+                                  secretRef:
+                                    description: Specify credentials in a Secret object
+                                    properties:
+                                      secretAccessKeySecretRef:
+                                        description: The SecretAccessKey is used for
+                                          authentication
+                                        properties:
+                                          key:
+                                            description: |-
+                                              A key in the referenced Secret.
+                                              Some instances of this field may be defaulted, in others it may be required.
+                                            maxLength: 253
+                                            minLength: 1
+                                            pattern: ^[-._a-zA-Z0-9]+$
+                                            type: string
+                                          name:
+                                            description: The name of the Secret resource
+                                              being referred to.
+                                            maxLength: 253
+                                            minLength: 1
+                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                            type: string
+                                          namespace:
+                                            description: |-
+                                              The namespace of the Secret resource being referred to.
+                                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                            maxLength: 63
+                                            minLength: 1
+                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                            type: string
+                                        type: object
+                                    type: object
+                                  serviceAccountRef:
+                                    description: ServiceAccountRef to a service account
+                                      for impersonation
+                                    properties:
+                                      audiences:
+                                        description: |-
+                                          Audience specifies the `aud` claim for the service account token
+                                          If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                          then this audiences will be appended to the list
+                                        items:
+                                          type: string
+                                        type: array
+                                      name:
+                                        description: The name of the ServiceAccount
+                                          resource being referred to.
+                                        maxLength: 253
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                        type: string
+                                      namespace:
+                                        description: |-
+                                          Namespace of the resource being referred to.
+                                          Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                        maxLength: 63
+                                        minLength: 1
+                                        pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                        type: string
+                                    required:
+                                    - name
+                                    type: object
+                                  workloadIdentity:
+                                    description: Specify a service account with Workload
+                                      Identity
+                                    properties:
+                                      clusterLocation:
+                                        description: |-
+                                          ClusterLocation is the location of the cluster
+                                          If not specified, it fetches information from the metadata server
+                                        type: string
+                                      clusterName:
+                                        description: |-
+                                          ClusterName is the name of the cluster
+                                          If not specified, it fetches information from the metadata server
+                                        type: string
+                                      clusterProjectID:
+                                        description: |-
+                                          ClusterProjectID is the project ID of the cluster
+                                          If not specified, it fetches information from the metadata server
+                                        type: string
+                                      serviceAccountRef:
+                                        description: ServiceAccountSelector is a reference
+                                          to a ServiceAccount resource.
+                                        properties:
+                                          audiences:
+                                            description: |-
+                                              Audience specifies the `aud` claim for the service account token
+                                              If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                              then this audiences will be appended to the list
+                                            items:
+                                              type: string
+                                            type: array
+                                          name:
+                                            description: The name of the ServiceAccount
+                                              resource being referred to.
+                                            maxLength: 253
+                                            minLength: 1
+                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                            type: string
+                                          namespace:
+                                            description: |-
+                                              Namespace of the resource being referred to.
+                                              Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                            maxLength: 63
+                                            minLength: 1
+                                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                            type: string
+                                        required:
+                                        - name
+                                        type: object
+                                    required:
+                                    - serviceAccountRef
+                                    type: object
+                                required:
+                                - role
+                                type: object
                               iam:
                                 description: |-
                                   Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials

+ 8 - 0
config/crds/bases/generators.external-secrets.io_passwords.yaml

@@ -82,6 +82,14 @@ spec:
                 default: false
                 description: Set NoUpper to disable uppercase characters
                 type: boolean
+              secretKeys:
+                description: |-
+                  SecretKeys defines the keys that will be populated with generated passwords.
+                  Defaults to "password" when not set.
+                items:
+                  type: string
+                minItems: 1
+                type: array
               symbolCharacters:
                 description: |-
                   SymbolCharacters specifies the special characters that should be used

+ 4 - 2
config/crds/bases/generators.external-secrets.io_sshkeys.yaml

@@ -48,17 +48,19 @@ spec:
                 type: string
               keySize:
                 description: |-
-                  KeySize specifies the key size for RSA keys (default: 2048)
+                  KeySize specifies the key size for RSA keys (default: 2048) and ECDSA keys (default: 256).
                   For RSA keys: 2048, 3072, 4096
+                  For ECDSA keys: 256, 384, 521
                   Ignored for ed25519 keys
                 maximum: 8192
                 minimum: 256
                 type: integer
               keyType:
                 default: rsa
-                description: KeyType specifies the SSH key type (rsa, ed25519)
+                description: KeyType specifies the SSH key type (rsa, ecdsa, ed25519)
                 enum:
                 - rsa
+                - ecdsa
                 - ed25519
                 type: string
             type: object

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

@@ -222,6 +222,143 @@ spec:
                                 type: string
                             type: object
                         type: object
+                      gcp:
+                        description: |-
+                          Gcp authenticates with Vault using Google Cloud Platform authentication method
+                          GCP authentication method
+                        properties:
+                          location:
+                            description: Location optionally defines a location/region
+                              for the secret
+                            type: string
+                          path:
+                            default: gcp
+                            description: 'Path where the GCP auth method is enabled
+                              in Vault, e.g: "gcp"'
+                            type: string
+                          projectID:
+                            description: Project ID of the Google Cloud Platform project
+                            type: string
+                          role:
+                            description: Vault Role. In Vault, a role describes an
+                              identity with a set of permissions, groups, or policies
+                              you want to attach to a user of the secrets engine.
+                            type: string
+                          secretRef:
+                            description: Specify credentials in a Secret object
+                            properties:
+                              secretAccessKeySecretRef:
+                                description: The SecretAccessKey is used for authentication
+                                properties:
+                                  key:
+                                    description: |-
+                                      A key in the referenced Secret.
+                                      Some instances of this field may be defaulted, in others it may be required.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[-._a-zA-Z0-9]+$
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      The namespace of the Secret resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                type: object
+                            type: object
+                          serviceAccountRef:
+                            description: ServiceAccountRef to a service account for
+                              impersonation
+                            properties:
+                              audiences:
+                                description: |-
+                                  Audience specifies the `aud` claim for the service account token
+                                  If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                  then this audiences will be appended to the list
+                                items:
+                                  type: string
+                                type: array
+                              name:
+                                description: The name of the ServiceAccount resource
+                                  being referred to.
+                                maxLength: 253
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                type: string
+                              namespace:
+                                description: |-
+                                  Namespace of the resource being referred to.
+                                  Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                maxLength: 63
+                                minLength: 1
+                                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                type: string
+                            required:
+                            - name
+                            type: object
+                          workloadIdentity:
+                            description: Specify a service account with Workload Identity
+                            properties:
+                              clusterLocation:
+                                description: |-
+                                  ClusterLocation is the location of the cluster
+                                  If not specified, it fetches information from the metadata server
+                                type: string
+                              clusterName:
+                                description: |-
+                                  ClusterName is the name of the cluster
+                                  If not specified, it fetches information from the metadata server
+                                type: string
+                              clusterProjectID:
+                                description: |-
+                                  ClusterProjectID is the project ID of the cluster
+                                  If not specified, it fetches information from the metadata server
+                                type: string
+                              serviceAccountRef:
+                                description: ServiceAccountSelector is a reference
+                                  to a ServiceAccount resource.
+                                properties:
+                                  audiences:
+                                    description: |-
+                                      Audience specifies the `aud` claim for the service account token
+                                      If the service account uses a well-known annotation for e.g. IRSA or GCP Workload Identity
+                                      then this audiences will be appended to the list
+                                    items:
+                                      type: string
+                                    type: array
+                                  name:
+                                    description: The name of the ServiceAccount resource
+                                      being referred to.
+                                    maxLength: 253
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                                    type: string
+                                  namespace:
+                                    description: |-
+                                      Namespace of the resource being referred to.
+                                      Ignored if referent is not cluster-scoped, otherwise defaults to the namespace of the referent.
+                                    maxLength: 63
+                                    minLength: 1
+                                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            required:
+                            - serviceAccountRef
+                            type: object
+                        required:
+                        - role
+                        type: object
                       iam:
                         description: |-
                           Iam authenticates with vault by passing a special AWS request signed with AWS IAM credentials

+ 3 - 3
deploy/charts/external-secrets/Chart.lock

@@ -1,6 +1,6 @@
 dependencies:
 - name: bitwarden-sdk-server
   repository: oci://ghcr.io/external-secrets/charts
-  version: v0.5.1
-digest: sha256:04be6ffa8a097670c52868f5fe98a11841116b7f484501cae98276215294ba50
-generated: "2025-07-18T07:31:51.336505+02:00"
+  version: v0.5.2
+digest: sha256:4c132cc7a8cc3dc3e97766d7bad0bc4d7795e8fdb312f92ff64a9bd93549dc58
+generated: "2025-12-13T11:14:24.649206+01:00"

+ 3 - 3
deploy/charts/external-secrets/Chart.yaml

@@ -2,8 +2,8 @@ apiVersion: v2
 name: external-secrets
 description: External secrets management for Kubernetes
 type: application
-version: "0.20.4"
-appVersion: "v0.20.4"
+version: "2.1.0"
+appVersion: "v2.1.0"
 kubeVersion: ">= 1.19.0-0"
 keywords:
   - kubernetes-external-secrets
@@ -15,6 +15,6 @@ maintainers:
     email: kellinmcavoy@gmail.com
 dependencies:
   - name: bitwarden-sdk-server
-    version: v0.5.1
+    version: v0.5.2
     repository: oci://ghcr.io/external-secrets/charts
     condition: bitwarden-sdk-server.enabled

+ 30 - 13
deploy/charts/external-secrets/README.md

@@ -4,7 +4,7 @@
 
 [//]: # (README.md generated by gotmpl. DO NOT EDIT.)
 
-![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.20.4](https://img.shields.io/badge/Version-0.20.4-informational?style=flat-square)
+![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 2.1.0](https://img.shields.io/badge/Version-2.1.0-informational?style=flat-square)
 
 External secrets management for Kubernetes
 
@@ -45,10 +45,12 @@ The command removes all the Kubernetes components associated with the chart and
 | certController.extraInitContainers | list | `[]` |  |
 | certController.extraVolumeMounts | list | `[]` |  |
 | certController.extraVolumes | list | `[]` |  |
+| certController.hostAliases | list | `[]` | Specifies `hostAliases` to cert-controller deployment |
 | certController.hostNetwork | bool | `false` | Run the certController on the host network |
+| certController.hostUsers | bool | `nil` | Specifies if certController pod should use hostUsers or not. If hostNetwork is true, hostUsers should be too. Only available in Kubernetes ≥ 1.33. @schema type: [boolean, null] |
 | certController.image.flavour | string | `""` |  |
 | certController.image.pullPolicy | string | `"IfNotPresent"` |  |
-| certController.image.repository | string | `"oci.external-secrets.io/external-secrets/external-secrets"` |  |
+| certController.image.repository | string | `"ghcr.io/external-secrets/external-secrets"` |  |
 | certController.image.tag | string | `""` |  |
 | certController.imagePullSecrets | list | `[]` |  |
 | certController.log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifies Log Params to the Certificate Controller |
@@ -92,11 +94,13 @@ The command removes all the Kubernetes components associated with the chart and
 | controllerClass | string | `""` | If set external secrets will filter matching Secret Stores with the appropriate controller values. |
 | crds.annotations | object | `{}` |  |
 | crds.conversion.enabled | bool | `false` | Conversion is disabled by default as we stopped supporting v1alpha1. |
-| crds.createClusterExternalSecret | bool | `true` | If true, create CRDs for Cluster External Secret. |
-| crds.createClusterGenerator | bool | `true` | If true, create CRDs for Cluster Generator. |
-| crds.createClusterPushSecret | bool | `true` | If true, create CRDs for Cluster Push Secret. |
-| crds.createClusterSecretStore | bool | `true` | If true, create CRDs for Cluster Secret Store. |
-| crds.createPushSecret | bool | `true` | If true, create CRDs for Push Secret. |
+| crds.createClusterExternalSecret | bool | `true` | If true, create CRDs for Cluster External Secret. If set to false you must also set processClusterExternalSecret: false. |
+| crds.createClusterGenerator | bool | `true` | If true, create CRDs for Cluster Generator. If set to false you must also set processClusterGenerator: false. |
+| crds.createClusterPushSecret | bool | `true` | If true, create CRDs for Cluster Push Secret. If set to false you must also set processClusterPushSecret: false. |
+| crds.createClusterSecretStore | bool | `true` | If true, create CRDs for Cluster Secret Store. If set to false you must also set processClusterStore: false. |
+| crds.createPushSecret | bool | `true` | If true, create CRDs for Push Secret. If set to false you must also set processPushSecret: false. |
+| crds.createSecretStore | bool | `true` | If true, create CRDs for Secret Store. If set to false you must also set processSecretStore: false. |
+| crds.unsafeServeV1Beta1 | bool | `false` | If true, enable v1beta1 API version serving for ExternalSecret, ClusterExternalSecret, SecretStore, and ClusterSecretStore CRDs. v1beta1 is deprecated. Only enable this for backward compatibility if you have existing v1beta1 resources. Warning: This flag will be removed on 2026.05.01. |
 | createOperator | bool | `true` | Specifies whether an external secret operator deployment be created. |
 | deploymentAnnotations | object | `{}` | Annotations to add to Deployment |
 | dnsConfig | object | `{}` | Specifies `dnsOptions` to deployment |
@@ -116,7 +120,12 @@ The command removes all the Kubernetes components associated with the chart and
 | genericTargets.resources | list | `[]` | List of additional resource types to grant permissions for. Each entry should specify apiGroup, resources, and verbs. Example: resources:   - apiGroup: "argoproj.io"     resources: ["applications"]     verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] |
 | global.affinity | object | `{}` |  |
 | global.compatibility.openshift.adaptSecurityContext | string | `"auto"` | Manages the securityContext properties to make them compatible with OpenShift. Possible values: auto - Apply configurations if it is detected that OpenShift is the target platform. force - Always apply configurations. disabled - No modification applied. |
+| global.hostAliases | list | `[]` | Global hostAliases to be applied to all deployments |
+| global.imagePullSecrets | list | `[]` | Global imagePullSecrets to be applied to all deployments |
 | global.nodeSelector | object | `{}` |  |
+| global.podAnnotations | object | `{}` | Global pod annotations to be applied to all deployments |
+| global.podLabels | object | `{}` | Global pod labels to be applied to all deployments |
+| global.repository | string | `""` | Global image repository to be applied to all deployments |
 | global.tolerations | list | `[]` |  |
 | global.topologySpreadConstraints | list | `[]` |  |
 | grafanaDashboard.annotations | object | `{}` | Annotations that ConfigMaps can have to get configured in Grafana, See: sidecar.dashboards.folderAnnotation for specifying the dashboard folder. https://github.com/grafana/helm-charts/tree/main/charts/grafana |
@@ -124,23 +133,26 @@ The command removes all the Kubernetes components associated with the chart and
 | grafanaDashboard.extraLabels | object | `{}` | Extra labels to add to the Grafana dashboard ConfigMap. |
 | grafanaDashboard.sidecarLabel | string | `"grafana_dashboard"` | Label that ConfigMaps should have to be loaded as dashboards. |
 | grafanaDashboard.sidecarLabelValue | string | `"1"` | Label value that ConfigMaps should have to be loaded as dashboards. |
+| hostAliases | list | `[]` | Specifies `hostAliases` to deployment |
 | hostNetwork | bool | `false` | Run the controller on the host network |
+| hostUsers | bool | `nil` | Specifies if controller pod should use hostUsers or not. If hostNetwork is true, hostUsers should be too. Only available in Kubernetes ≥ 1.33. @schema type: [boolean, null] |
 | image.flavour | string | `""` | The flavour of tag you want to use There are different image flavours available, like distroless and ubi. Please see GitHub release notes for image tags for these flavors. By default, the distroless image is used. |
 | image.pullPolicy | string | `"IfNotPresent"` |  |
-| image.repository | string | `"oci.external-secrets.io/external-secrets/external-secrets"` |  |
+| image.repository | string | `"ghcr.io/external-secrets/external-secrets"` |  |
 | image.tag | string | `""` | The image tag to use. The default is the chart appVersion. |
 | imagePullSecrets | list | `[]` |  |
 | installCRDs | bool | `true` | If set, install and upgrade CRDs through helm chart. |
 | leaderElect | bool | `false` | If true, external-secrets will perform leader election between instances to ensure no more than one instance of external-secrets operates at a time. |
 | livenessProbe.enabled | bool | `false` | Enabled determines if the liveness probe should be used or not. By default it's disabled. |
-| livenessProbe.spec | object | `{"address":"","failureThreshold":5,"httpGet":{"path":"/healthz","port":8082},"initialDelaySeconds":10,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":5}` | The body of the liveness probe settings. |
+| livenessProbe.spec | object | `{"address":"","failureThreshold":5,"httpGet":{"path":"/healthz","port":"live"},"initialDelaySeconds":10,"periodSeconds":10,"port":8082,"successThreshold":1,"timeoutSeconds":5}` | The body of the liveness probe settings. |
 | livenessProbe.spec.address | string | `""` | Address for liveness probe. |
 | livenessProbe.spec.failureThreshold | int | `5` | Number of consecutive probe failures that should occur before considering the probe as failed. |
-| livenessProbe.spec.httpGet | object | `{"path":"/healthz","port":8082}` | Handler for liveness probe. |
+| livenessProbe.spec.httpGet | object | `{"path":"/healthz","port":"live"}` | Handler for liveness probe. |
 | livenessProbe.spec.httpGet.path | string | `"/healthz"` | Path for liveness probe. |
-| livenessProbe.spec.httpGet.port | int | `8082` | Set this value to 8082 to active liveness probes. @schema type: [string, integer] |
+| livenessProbe.spec.httpGet.port | string | `"live"` | Set this value to 'live' (for named port) or an an integer for liveness probes. @schema type: [string, integer] |
 | livenessProbe.spec.initialDelaySeconds | int | `10` | Delay in seconds for the container to start before performing the initial probe. |
 | livenessProbe.spec.periodSeconds | int | `10` | Period in seconds for K8s to start performing probes. |
+| livenessProbe.spec.port | int | `8082` | Named port for liveness probe. |
 | livenessProbe.spec.successThreshold | int | `1` | Number of successful probes to mark probe successful. |
 | livenessProbe.spec.timeoutSeconds | int | `5` | Specify the maximum amount of time to wait for a probe to respond before considering it fails. |
 | log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifies Log Params to the External Secrets Operator |
@@ -167,6 +179,7 @@ The command removes all the Kubernetes components associated with the chart and
 | processClusterPushSecret | bool | `true` | if true, the operator will process cluster push secret. Else, it will ignore them. |
 | processClusterStore | bool | `true` | if true, the operator will process cluster store. Else, it will ignore them. |
 | processPushSecret | bool | `true` | if true, the operator will process push secret. Else, it will ignore them. |
+| processSecretStore | bool | `true` | if true, the operator will process secret store. Else, it will ignore them. |
 | rbac.aggregateToEdit | bool | `true` | Specifies whether permissions are aggregated to the edit ClusterRole |
 | rbac.aggregateToView | bool | `true` | Specifies whether permissions are aggregated to the view ClusterRole |
 | rbac.create | bool | `true` | Specifies whether role and rolebinding resources should be created. |
@@ -197,7 +210,7 @@ The command removes all the Kubernetes components associated with the chart and
 | serviceMonitor.metricRelabelings | list | `[]` | Metric relabel configs to apply to samples before ingestion. [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs) |
 | serviceMonitor.namespace | string | `""` | namespace where you want to install ServiceMonitors |
 | serviceMonitor.relabelings | list | `[]` | Relabel configs to apply to samples before ingestion. [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) |
-| serviceMonitor.renderMode | string | `"skipIfMissing"` | How should we react to missing CRD "`monitoring.coreos.com/v1/ServiceMonitor`" Possible values: - `skipIfMissing`: Only render ServiceMonitor resources if CRD is present, skip if missing. - `failIfMissing`: Fail Helm install if CRD is not present. - `alwaysRender` : Always render ServiceMonitor resources, do not check for CRD. @schema enum: - skipIfMissing - failIfMissing - alwaysRender @schema |
+| serviceMonitor.renderMode | string | `"skipIfMissing"` | How should we react to missing CRD "`monitoring.coreos.com/v1/ServiceMonitor`"  Possible values: - `skipIfMissing`: Only render ServiceMonitor resources if CRD is present, skip if missing. - `failIfMissing`: Fail Helm install if CRD is not present. - `alwaysRender` : Always render ServiceMonitor resources, do not check for CRD. @schema enum: - skipIfMissing - failIfMissing - alwaysRender @schema |
 | serviceMonitor.scrapeTimeout | string | `"25s"` | Timeout if metrics can't be retrieved in given time interval |
 | strategy | object | `{}` | Set deployment strategy |
 | systemAuthDelegator | bool | `false` | If true the system:auth-delegator ClusterRole will be added to RBAC |
@@ -212,8 +225,10 @@ The command removes all the Kubernetes components associated with the chart and
 | webhook.certManager.cert.create | bool | `true` | Create a certificate resource within this chart. See https://cert-manager.io/docs/usage/certificate/ |
 | webhook.certManager.cert.duration | string | `"8760h0m0s"` | Set the requested duration (i.e. lifetime) of the Certificate. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec One year by default. |
 | webhook.certManager.cert.issuerRef | object | `{"group":"cert-manager.io","kind":"Issuer","name":"my-issuer"}` | For the Certificate created by this chart, setup the issuer. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.IssuerSpec |
+| webhook.certManager.cert.privateKey | object | `{}` | Specific settings on the privateKey and its generation |
 | webhook.certManager.cert.renewBefore | string | `""` | How long before the currently issued certificate’s expiry cert-manager should renew the certificate. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec Note that renewBefore should be greater than .webhook.lookaheadInterval since the webhook will check this far in advance that the certificate is valid. |
 | webhook.certManager.cert.revisionHistoryLimit | int | `0` | Set the revisionHistoryLimit on the Certificate. See https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec Defaults to 0 (ignored). |
+| webhook.certManager.cert.signatureAlgorithm | string | `""` | Specific settings on the signatureAlgorithm used on the cert. signatureAlgorithm is only valid for cert-manager v1.18.0+ |
 | webhook.certManager.enabled | bool | `false` | Enabling cert-manager support will disable the built in secret and switch to using cert-manager (installed separately) to automatically issue and renew the webhook certificate. This chart does not install cert-manager for you, See https://cert-manager.io/docs/ |
 | webhook.create | bool | `true` | Specifies whether a webhook deployment be created. If set to false, crds.conversion.enabled should also be set to false otherwise the kubeapi will be hammered because the conversion is looking for a webhook endpoint. |
 | webhook.deploymentAnnotations | object | `{}` | Annotations to add to Deployment |
@@ -223,10 +238,12 @@ The command removes all the Kubernetes components associated with the chart and
 | webhook.extraVolumeMounts | list | `[]` |  |
 | webhook.extraVolumes | list | `[]` |  |
 | webhook.failurePolicy | string | `"Fail"` | Specifies whether validating webhooks should be created with failurePolicy: Fail or Ignore |
+| webhook.hostAliases | list | `[]` | Specifies `hostAliases` to webhook deployment |
 | webhook.hostNetwork | bool | `false` | Specifies if webhook pod should use hostNetwork or not. |
+| webhook.hostUsers | bool | `nil` | Specifies if webhook pod should use hostUsers or not. If hostNetwork is true, hostUsers should be too. Only available in Kubernetes ≥ 1.33. @schema type: [boolean, null] |
 | webhook.image.flavour | string | `""` | The flavour of tag you want to use |
 | webhook.image.pullPolicy | string | `"IfNotPresent"` |  |
-| webhook.image.repository | string | `"oci.external-secrets.io/external-secrets/external-secrets"` |  |
+| webhook.image.repository | string | `"ghcr.io/external-secrets/external-secrets"` |  |
 | webhook.image.tag | string | `""` | The image tag to use. The default is the chart appVersion. |
 | webhook.imagePullSecrets | list | `[]` |  |
 | webhook.log | object | `{"level":"info","timeEncoding":"epoch"}` | Specifies Log Params to the Webhook |

+ 8 - 2
deploy/charts/external-secrets/templates/_helpers.tpl

@@ -173,10 +173,16 @@ Create the name of the service account to use
 Determine the image to use, including if using a flavour.
 */}}
 {{- define "external-secrets.image" -}}
+{{- $repository := "" -}}
+{{- if .context.Values.global.repository -}}
+{{- $repository = .context.Values.global.repository -}}
+{{- else -}}
+{{- $repository = .image.repository -}}
+{{- end -}}
 {{- if .image.flavour -}}
-{{ printf "%s:%s-%s" .image.repository (.image.tag | default .chartAppVersion) .image.flavour }}
+{{ printf "%s:%s-%s" $repository (.image.tag | default .chartAppVersion) .image.flavour }}
 {{- else }}
-{{ printf "%s:%s" .image.repository (.image.tag | default .chartAppVersion) }}
+{{ printf "%s:%s" $repository (.image.tag | default .chartAppVersion) }}
 {{- end }}
 {{- end }}
 

+ 46 - 11
deploy/charts/external-secrets/templates/cert-controller-deployment.yaml

@@ -22,22 +22,35 @@ spec:
   {{- end }}
   template:
     metadata:
-      {{- with .Values.certController.podAnnotations }}
+      {{- if .Values.certController.podAnnotations }}
       annotations:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.certController.podAnnotations | nindent 8 }}
+      {{- else if .Values.global.podAnnotations }}
+      annotations:
+        {{- toYaml .Values.global.podAnnotations | nindent 8 }}
       {{- end }}
       labels:
         {{- include "external-secrets-cert-controller.labels" . | nindent 8 }}
-        {{- with .Values.certController.podLabels }}
-          {{- toYaml . | nindent 8 }}
+        {{- if .Values.certController.podLabels }}
+        {{- toYaml .Values.certController.podLabels | nindent 8 }}
+        {{- else if .Values.global.podLabels }}
+        {{- toYaml .Values.global.podLabels | nindent 8 }}
         {{- end }}
     spec:
-      {{- with .Values.certController.imagePullSecrets }}
+      {{- if .Values.certController.imagePullSecrets }}
       imagePullSecrets:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.certController.imagePullSecrets | nindent 8 }}
+      {{- else if .Values.global.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
       {{- end }}
       serviceAccountName: {{ include "external-secrets-cert-controller.serviceAccountName" . }}
       automountServiceAccountToken: {{ .Values.certController.serviceAccount.automount }}
+      {{- if (semverCompare ">= 1.33-0" .Capabilities.KubeVersion.Version) }}
+      {{- if kindIs "bool" .Values.certController.hostUsers }}
+      hostUsers: {{ .Values.certController.hostUsers }}
+      {{- end }}
+      {{- end }}
       {{- with .Values.certController.podSecurityContext }}
        {{- if and (.enabled) (gt (keys . | len) 1) }}
       securityContext:
@@ -53,7 +66,7 @@ spec:
             {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }}
           {{- end }}
           {{- end }}
-          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.certController.image) | trim }}
+          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.certController.image "context" .) | trim }}
           imagePullPolicy: {{ .Values.certController.image.pullPolicy }}
           args:
           - certcontroller
@@ -76,6 +89,9 @@ spec:
           {{- if .Values.enableHTTP2 }}
           - --enable-http2=true
           {{- end }}
+          {{- if .Values.leaderElect }}
+          - --enable-leader-election=true
+          {{- end }}
           {{- range $key, $value := .Values.certController.extraArgs }}
             {{- if $value }}
           - --{{ $key }}={{ $value }}
@@ -87,9 +103,17 @@ spec:
             - containerPort: {{ .Values.certController.metrics.listen.port }}
               protocol: TCP
               name: metrics
+            - containerPort: {{ .Values.certController.readinessProbe.port }}
+              protocol: TCP
+              name: ready
+            {{- if and .Values.certController.startupProbe.enabled (not .Values.certController.startupProbe.useReadinessProbePort) }}
+            - containerPort: {{ .Values.certController.startupProbe.port }}
+              protocol: TCP
+              name: startup
+            {{- end }}
           readinessProbe:
             httpGet:
-              port: {{ .Values.certController.readinessProbe.port }}
+              port: ready
               path: /readyz
             initialDelaySeconds: 20
             periodSeconds: 5
@@ -97,9 +121,9 @@ spec:
           startupProbe:
             httpGet:
               {{- if .Values.certController.startupProbe.useReadinessProbePort }}
-              port: {{ .Values.certController.readinessProbe.port }}
+              port: ready
               {{- else }}
-              port: {{ .Values.certController.startupProbe.port }}
+              port: startup
               {{- end }}
               path: /readyz
             initialDelaySeconds: 20
@@ -125,6 +149,10 @@ spec:
       volumes:
       {{- toYaml .Values.certController.extraVolumes | nindent 8 }}
       {{- end }}
+      {{- with .Values.certController.hostAliases | default .Values.global.hostAliases }}
+      hostAliases:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
       {{- with .Values.certController.nodeSelector | default .Values.global.nodeSelector }}
       nodeSelector:
         {{- toYaml . | nindent 8 }}
@@ -139,7 +167,14 @@ spec:
       {{- end }}
       {{- with .Values.certController.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }}
       topologySpreadConstraints:
-        {{- toYaml . | nindent 8 }}
+        {{- range $constraint := . }}
+        - {{ toYaml $constraint | nindent 10 | trim }}
+          {{- if not $constraint.labelSelector }}
+          labelSelector:
+            matchLabels:
+              {{- include "external-secrets-cert-controller.selectorLabels" $ | nindent 14 }}
+          {{- end }}
+        {{- end }}
       {{- end }}
       {{- if .Values.certController.priorityClassName }}
       priorityClassName: {{ .Values.certController.priorityClassName }}

+ 1 - 1
deploy/charts/external-secrets/templates/cert-controller-service.yaml

@@ -11,7 +11,7 @@ metadata:
   namespace: {{ template "external-secrets.namespace" . }}
   labels:
     {{- include "external-secrets-cert-controller.labels" . | nindent 4 }}
-  {{- with .Values.metrics.service.annotations }}
+  {{- with .Values.certController.metrics.service.annotations }}
   annotations:
     {{- toYaml . | nindent 4 }}
   {{- end }}

+ 49 - 9
deploy/charts/external-secrets/templates/deployment.yaml

@@ -23,22 +23,35 @@ spec:
   {{- end }}
   template:
     metadata:
-      {{- with .Values.podAnnotations }}
+      {{- if .Values.podAnnotations }}
       annotations:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.podAnnotations | nindent 8 }}
+      {{- else if .Values.global.podAnnotations }}
+      annotations:
+        {{- toYaml .Values.global.podAnnotations | nindent 8 }}
       {{- end }}
       labels:
         {{- include "external-secrets.labels" . | nindent 8 }}
-        {{- with .Values.podLabels }}
-          {{- toYaml . | nindent 8 }}
+        {{- if .Values.podLabels }}
+        {{- toYaml .Values.podLabels | nindent 8 }}
+        {{- else if .Values.global.podLabels }}
+        {{- toYaml .Values.global.podLabels | nindent 8 }}
         {{- end }}
     spec:
-      {{- with .Values.imagePullSecrets }}
+      {{- if .Values.imagePullSecrets }}
       imagePullSecrets:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.imagePullSecrets | nindent 8 }}
+      {{- else if .Values.global.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
       {{- end }}
       serviceAccountName: {{ include "external-secrets.serviceAccountName" . }}
       automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
+      {{- if (semverCompare ">= 1.33-0" .Capabilities.KubeVersion.Version) }}
+      {{- if kindIs "bool" .Values.hostUsers }}
+      hostUsers: {{ .Values.hostUsers }}
+      {{- end }}
+      {{- end }}
       {{- with .Values.podSecurityContext }}
       {{- if and (.enabled) (gt (keys . | len) 1) }}
       securityContext:
@@ -54,7 +67,7 @@ spec:
             {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }}
           {{- end }}
           {{- end }}
-          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.image) | trim }}
+          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.image "context" .) | trim }}
           imagePullPolicy: {{ .Values.image.pullPolicy }}
           {{- if or (.Values.leaderElect) (.Values.scopedNamespace) (.Values.processClusterStore) (.Values.processClusterExternalSecret) (.Values.processClusterPushSecret) (.Values.concurrent) (.Values.extraArgs) }}
           args:
@@ -82,6 +95,9 @@ spec:
           {{- if not .Values.processPushSecret }}
           - --enable-push-secret-reconciler=false
           {{- end }}
+          {{- if not .Values.processSecretStore }}
+          - --enable-secret-store-reconciler=false
+          {{- end }}
           {{- if .Values.controllerClass }}
           - --controller-class={{ .Values.controllerClass }}
           {{- end }}
@@ -109,8 +125,12 @@ spec:
           - --loglevel={{ .Values.log.level }}
           - --zap-time-encoding={{ .Values.log.timeEncoding }}
           {{- if .Values.livenessProbe.enabled }}
+          {{- if eq (kindOf .Values.livenessProbe.spec.httpGet.port) "string" }}
+          - --live-addr={{ .Values.livenessProbe.spec.address }}:{{ .Values.livenessProbe.spec.port }}
+          {{- else }}
           - --live-addr={{ .Values.livenessProbe.spec.address }}:{{ .Values.livenessProbe.spec.httpGet.port }}
           {{- end }}
+          {{- end }}
           {{- if .Values.metrics.listen.secure.enabled }}
           - --metrics-secure=true
           - --metrics-cert-dir={{ .Values.metrics.listen.secure.certDir }}
@@ -121,9 +141,18 @@ spec:
             - containerPort: {{ .Values.metrics.listen.port }}
               protocol: TCP
               name: metrics
+            {{- if .Values.livenessProbe.enabled }}
+            - name: live
+              protocol: TCP
+              {{- if eq (kindOf .Values.livenessProbe.spec.httpGet.port) "string" }}
+              containerPort: {{ .Values.livenessProbe.spec.port }}
+              {{- else }}
+              containerPort: {{ .Values.livenessProbe.spec.httpGet.port }}
+              {{- end }}
+            {{- end }}
           {{- if .Values.livenessProbe.enabled }}
           livenessProbe:
-          {{- toYaml (omit .Values.livenessProbe.spec "address") | nindent 12 }}
+          {{- toYaml (omit .Values.livenessProbe.spec "address" "port") | nindent 12 }}
           {{- end }}
           {{- with .Values.extraEnv }}
           env:
@@ -149,6 +178,10 @@ spec:
       dnsConfig:
           {{- toYaml .Values.dnsConfig | nindent 8 }}
       {{- end }}
+      {{- with .Values.hostAliases | default .Values.global.hostAliases }}
+      hostAliases:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
       {{- if .Values.extraVolumes }}
       volumes:
       {{- toYaml .Values.extraVolumes | nindent 8 }}
@@ -167,7 +200,14 @@ spec:
       {{- end }}
       {{- with .Values.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }}
       topologySpreadConstraints:
-        {{- toYaml . | nindent 8 }}
+        {{- range $constraint := . }}
+        - {{ toYaml $constraint | nindent 10 | trim }}
+          {{- if not $constraint.labelSelector }}
+          labelSelector:
+            matchLabels:
+              {{- include "external-secrets.selectorLabels" $ | nindent 14 }}
+          {{- end }}
+        {{- end }}
       {{- end }}
       {{- if .Values.priorityClassName }}
       priorityClassName: {{ .Values.priorityClassName }}

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

@@ -31,6 +31,7 @@ webhooks:
   admissionReviewVersions: ["v1", "v1beta1"]
   sideEffects: None
   timeoutSeconds: 5
+  failurePolicy: {{ .Values.webhook.failurePolicy }}
 
 - name: "validate.clustersecretstore.external-secrets.io"
   rules:

+ 7 - 0
deploy/charts/external-secrets/templates/webhook-certificate.yaml

@@ -23,6 +23,13 @@ spec:
   {{- with .Values.webhook.certManager.cert.duration }}
   duration: {{ . | quote }}
   {{- end }}
+  {{- with .Values.webhook.certManager.cert.privateKey }}
+  privateKey:
+{{ toYaml . | indent 4 }}
+  {{- end }}
+  {{- if .Values.webhook.certManager.cert.signatureAlgorithm }}
+  signatureAlgorithm: {{ .Values.webhook.certManager.cert.signatureAlgorithm }}
+  {{- end }}
   {{- with .Values.webhook.certManager.cert.renewBefore }}
   renewBefore: {{ . | quote }}
   {{- end }}

+ 36 - 9
deploy/charts/external-secrets/templates/webhook-deployment.yaml

@@ -22,23 +22,36 @@ spec:
   {{- end }}
   template:
     metadata:
-      {{- with .Values.webhook.podAnnotations }}
+      {{- if .Values.webhook.podAnnotations }}
       annotations:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.webhook.podAnnotations | nindent 8 }}
+      {{- else if .Values.global.podAnnotations }}
+      annotations:
+        {{- toYaml .Values.global.podAnnotations | nindent 8 }}
       {{- end }}
       labels:
         {{- include "external-secrets-webhook.labels" . | nindent 8 }}
-        {{- with .Values.webhook.podLabels }}
-          {{- toYaml . | nindent 8 }}
+        {{- if .Values.webhook.podLabels }}
+        {{- toYaml .Values.webhook.podLabels | nindent 8 }}
+        {{- else if .Values.global.podLabels }}
+        {{- toYaml .Values.global.podLabels | nindent 8 }}
         {{- end }}
     spec:
-      {{- with .Values.webhook.imagePullSecrets }}
+      {{- if .Values.webhook.imagePullSecrets }}
       imagePullSecrets:
-        {{- toYaml . | nindent 8 }}
+        {{- toYaml .Values.webhook.imagePullSecrets | nindent 8 }}
+      {{- else if .Values.global.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
       {{- end }}
       hostNetwork: {{ .Values.webhook.hostNetwork}}
       serviceAccountName: {{ include "external-secrets-webhook.serviceAccountName" . }}
       automountServiceAccountToken: {{ .Values.webhook.serviceAccount.automount }}
+      {{- if (semverCompare ">= 1.33-0" .Capabilities.KubeVersion.Version) }}
+      {{- if kindIs "bool" .Values.webhook.hostUsers }}
+      hostUsers: {{ .Values.webhook.hostUsers }}
+      {{- end }}
+      {{- end }}
       {{- with .Values.webhook.podSecurityContext }}
       {{- if and (.enabled) (gt (keys . | len) 1) }}
       securityContext:
@@ -53,7 +66,7 @@ spec:
             {{- include "external-secrets.renderSecurityContext" (dict "securityContext" . "context" $) | nindent 12 }}
           {{- end }}
           {{- end }}
-          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.webhook.image) | trim }}
+          image: {{ include "external-secrets.image" (dict "chartAppVersion" .Chart.AppVersion "image" .Values.webhook.image "context" .) | trim }}
           imagePullPolicy: {{ .Values.webhook.image.pullPolicy }}
           args:
           - webhook
@@ -85,9 +98,12 @@ spec:
             - containerPort: {{ .Values.webhook.port }}
               protocol: TCP
               name: webhook
+            - containerPort: {{ .Values.webhook.readinessProbe.port }}
+              protocol: TCP
+              name: ready
           readinessProbe:
             httpGet:
-              port: {{ .Values.webhook.readinessProbe.port }}
+              port: ready
               path: /readyz
             initialDelaySeconds: 20
             periodSeconds: 5
@@ -117,6 +133,10 @@ spec:
       {{- if .Values.webhook.extraVolumes }}
       {{- toYaml .Values.webhook.extraVolumes | nindent 8 }}
       {{- end }}
+      {{- with .Values.webhook.hostAliases | default .Values.global.hostAliases }}
+      hostAliases:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
       {{- with .Values.webhook.nodeSelector | default .Values.global.nodeSelector }}
       nodeSelector:
         {{- toYaml . | nindent 8 }}
@@ -131,7 +151,14 @@ spec:
       {{- end }}
       {{- with .Values.webhook.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }}
       topologySpreadConstraints:
-        {{- toYaml . | nindent 8 }}
+        {{- range $constraint := . }}
+        - {{ toYaml $constraint | nindent 10 | trim }}
+          {{- if not $constraint.labelSelector }}
+          labelSelector:
+            matchLabels:
+              {{- include "external-secrets-webhook.selectorLabels" $ | nindent 14 }}
+          {{- end }}
+        {{- end }}
       {{- end }}
       {{- if .Values.webhook.priorityClassName }}
       priorityClassName: {{ .Values.webhook.priorityClassName }}

+ 9 - 6
deploy/charts/external-secrets/tests/__snapshot__/cert_controller_test.yaml.snap

@@ -7,8 +7,8 @@ should match snapshot of default values:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/name: external-secrets-cert-controller
-        app.kubernetes.io/version: v0.20.4
-        helm.sh/chart: external-secrets-0.20.4
+        app.kubernetes.io/version: v2.1.0
+        helm.sh/chart: external-secrets-2.1.0
       name: RELEASE-NAME-external-secrets-cert-controller
       namespace: NAMESPACE
     spec:
@@ -24,8 +24,8 @@ should match snapshot of default values:
             app.kubernetes.io/instance: RELEASE-NAME
             app.kubernetes.io/managed-by: Helm
             app.kubernetes.io/name: external-secrets-cert-controller
-            app.kubernetes.io/version: v0.20.4
-            helm.sh/chart: external-secrets-0.20.4
+            app.kubernetes.io/version: v2.1.0
+            helm.sh/chart: external-secrets-2.1.0
         spec:
           automountServiceAccountToken: true
           containers:
@@ -41,17 +41,20 @@ should match snapshot of default values:
                 - --loglevel=info
                 - --zap-time-encoding=epoch
                 - --enable-partial-cache=true
-              image: oci.external-secrets.io/external-secrets/external-secrets:v0.20.2
+              image: ghcr.io/external-secrets/external-secrets:v2.1.0
               imagePullPolicy: IfNotPresent
               name: cert-controller
               ports:
                 - containerPort: 8080
                   name: metrics
                   protocol: TCP
+                - containerPort: 8081
+                  protocol: TCP
+                  name: ready
               readinessProbe:
                 httpGet:
                   path: /readyz
-                  port: 8081
+                  port: ready
                 initialDelaySeconds: 20
                 periodSeconds: 5
               securityContext:

+ 5 - 5
deploy/charts/external-secrets/tests/__snapshot__/controller_test.yaml.snap

@@ -7,8 +7,8 @@ should match snapshot of default values:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/name: external-secrets
-        app.kubernetes.io/version: v0.20.4
-        helm.sh/chart: external-secrets-0.20.4
+        app.kubernetes.io/version: v2.1.0
+        helm.sh/chart: external-secrets-2.1.0
       name: RELEASE-NAME-external-secrets
       namespace: NAMESPACE
     spec:
@@ -24,8 +24,8 @@ should match snapshot of default values:
             app.kubernetes.io/instance: RELEASE-NAME
             app.kubernetes.io/managed-by: Helm
             app.kubernetes.io/name: external-secrets
-            app.kubernetes.io/version: v0.20.4
-            helm.sh/chart: external-secrets-0.20.4
+            app.kubernetes.io/version: v2.1.0
+            helm.sh/chart: external-secrets-2.1.0
         spec:
           automountServiceAccountToken: true
           containers:
@@ -34,7 +34,7 @@ should match snapshot of default values:
                 - --metrics-addr=:8080
                 - --loglevel=info
                 - --zap-time-encoding=epoch
-              image: oci.external-secrets.io/external-secrets/external-secrets:v0.20.2
+              image: ghcr.io/external-secrets/external-secrets:v2.1.0
               imagePullPolicy: IfNotPresent
               name: external-secrets
               ports:

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.