[{"data":1,"prerenderedAt":35},["ShallowReactive",2],{"post-data-external-secrets-operator-cve-2026-109546":3},{"post":4,"relatedPosts":19},{"id":5,"title":6,"content":7,"hashtags":8,"coverImage":15,"createdAt":16,"seoTitle":17,"seoDescription":18},"Y1OC08Gisg3wnOTuiMJQ","External Secrets Operator CVE-2026-109546: Can Someone Who Creates an ExternalSecret Get a Service Account Token?","\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> before version 2.13.0, yes, in some configurations. Advisory GHSA-v6x5-m838-gqph (CVE-2026-109546) says that a user who can only create \u003Ccode>ExternalSecret\u003C\u002Fcode> resources could escalate privileges. That user could make External Secrets Operator (ESO) create a Secret that Kubernetes fills with a long-lived token for a service account, and so impersonate any service account in that namespace. Versions 2.4.0 through 2.12.0 are listed as affected, and 2.13.0 contains the fix. Upgrade first, then check who may create ExternalSecrets. The advisory rates the issue moderate (CVSS 4.9, high attack complexity, low privileges required), because the attacker needs permissions that are already close to powerful.\u003C\u002Fp>\n\u003Cp>This article is based on the advisories, release notes, source code and documentation, all opened on October 27, 2026. We did not have a cluster, did not reproduce the issue and did not test any command below. Snippets marked \"untested\" are our own drafts. Check them in a non-production cluster first.\u003C\u002Fp>\n\u003Ch2 id=\"what-does-the-advisory-say-\">What does the advisory say?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> it describes a privilege escalation from \"can create ExternalSecrets\" to \"can act as any service account in the namespace\", fixed in 2.13.0.\u003C\u002Fp>\n\u003Cp>Facts from the advisory, published on October 16, 2026:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Severity: Moderate, CVSS 4.9 (\u003Ccode>CVSS:3.1\u002FAV:N\u002FAC:H\u002FPR:L\u002FUI:N\u002FS:C\u002FC:L\u002FI:L\u002FA:N\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>Affected: \u003Ccode>&gt;= 2.4.0, &lt;= 2.12.0\u003C\u002Fcode>. Patched: \u003Ccode>2.13.0\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Impact, in the advisory's words: the user can cause the operator to create a Secret that Kubernetes will \"automatically populate with a long-lived token for the specified service account\". The user does not need direct permission to create Secrets of that type or to call \u003Ccode>TokenRequest\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Cause: it is a follow-up to CVE-2026-42876 (GHSA-fq7h-9x26-6j22, published May 5, 2026, fixed in 2.4.1). That earlier fix validated input before a Secret was created or updated. According to the new advisory, the guard could be bypassed with a target that behaves like \u003Ccode>Annotations\u003C\u002Fcode> without matching that exact string, such as \u003Ccode>metadata.annotations\u003C\u002Fcode> or a mixed-case \u003Ccode>Metadata.Annotations\u003C\u002Fcode>. The fix rejects path-style targets for Secrets.\u003C\u002Fli>\n\u003Cli>Workarounds listed: add admission control that blocks templates targeting undesired types, remove service account token generation through \u003Ccode>kube-controller-manager\u003C\u002Fcode> flags, and restrict user RBAC in production clusters and sensitive namespaces.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The advisory contains no proof of concept, and neither does this article.\u003C\u002Fp>\n\u003Ch2 id=\"how-does-an-operator-that-syncs-secrets-end-up-minting-tokens-\">How does an operator that syncs secrets end up minting tokens?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> the operator only writes a Secret of a special type; a Kubernetes controller fills in the token.\u003C\u002Fp>\n\u003Cp>Kubernetes documents \u003Ccode>kubernetes.io\u002Fservice-account-token\u003C\u002Fcode> as a legacy Secret type that \"provides long-lived ServiceAccount credentials\". The Secret must carry the annotation \u003Ccode>kubernetes.io\u002Fservice-account.name\u003C\u002Fcode> with the name of an existing service account. After it is created, \"a Kubernetes controller fills in\" the \u003Ccode>token\u003C\u002Fcode> key and related annotations. That controller is the token controller inside \u003Ccode>kube-controller-manager\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>ESO lets an ExternalSecret shape the Secret it produces through \u003Ccode>spec.target.template\u003C\u002Fcode>, which can set the Secret's type, metadata and data. This is intended and useful. It also means that whoever writes an ExternalSecret influences what kind of Secret the operator creates with its own, broader permissions. So ESO's validation refuses the dangerous combination: in the code at v2.13.0, a template of type \u003Ccode>kubernetes.io\u002Fservice-account-token\u003C\u002Fcode> is rejected when it carries the service-account annotation, and the type \u003Ccode>bootstrap.kubernetes.io\u002Ftoken\u003C\u002Fcode> is always rejected. The advisory is about inputs that slipped past this check in versions up to 2.12.0.\u003C\u002Fp>\n\u003Ch2 id=\"where-does-the-code-differ-between-2-12-0-and-2-13-0-\">Where does the code differ between 2.12.0 and 2.13.0?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> 2.13.0 adds a check on the final Secret and tightens which template targets are allowed. We could not map the advisory to one exact input.\u003C\u002Fp>\n\u003Cp>The 2.13.0 release notes list three relevant changes by one author: \"fix: validate manifest Secret candidates\" (#7066), \"fix: Restrict v1beta1 Secret template targets\" (#7067, which concerns the v1beta1 validator) and a test for the reconcile step (#7068). The release notes do not mention the CVE.\u003C\u002Fp>\n\u003Cp>The pull request descriptions frame the gap in two ways. #7066 says that an ExternalSecret targeting a core\u002Fv1 Secret through \u003Ccode>manifest\u003C\u002Fcode> \"can be used to bypass the protections used by the normal Secret reconciliation path\". #7067 says the v1beta1 validator \"previously allowed templateFrom targets outside the well-known Secret data, annotation, and label destinations\". The advisory talks about path-style annotation targets. These are probably related, but we have not confirmed that they describe the same input, so treat the mapping as our inference.\u003C\u002Fp>\n\u003Cp>There is one more oddity. The validator in v2.11.0 and v2.12.0 already contains an allowlist (targets \u003Ccode>Data\u003C\u002Fcode>, \u003Ccode>Annotations\u003C\u002Fcode> or \u003Ccode>Labels\u003C\u002Fcode>), yet the advisory lists them as affected. Do not rely on your own reading of the code to decide that you are safe. Follow the advisory's range.\u003C\u002Fp>\n\u003Cp>The code comment says the controller calls the same rules \"so the same set is enforced when no webhook sits in front of it\". That suggests the check exists both in the admission webhook and in the controller. If you run ESO with the webhook disabled or with \u003Ccode>failurePolicy: Ignore\u003C\u002Fcode>, only the controller-side checks apply. The chart default is \u003Ccode>webhook.create: true\u003C\u002Fcode> with \u003Ccode>failurePolicy: Fail\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"are-you-affected-\">Are you affected?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> you are if you run ESO 2.4.0 to 2.12.0 and anyone who is not a cluster admin can create or update ExternalSecrets.\u003C\u002Fp>\n\u003Cp>Work through these in order:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Version.\u003C\u002Fstrong> Check the image tag of the controller deployment. Anything from 2.4.0 to 2.12.0 is in the advisory's range. Versions before 2.4.1 are listed as affected by the earlier CVE-2026-42876, so upgrade them too.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Who can write ExternalSecrets?\u003C\u002Fstrong> In many clusters, developers get \u003Ccode>create\u003C\u002Fcode> on \u003Ccode>externalsecrets\u003C\u002Fcode> in their team namespace. Those are exactly the users the advisory is about. \u003Ccode>kubectl auth can-i create externalsecrets.external-secrets.io -n &lt;namespace&gt; --as=&lt;user&gt;\u003C\u002Fcode> answers it for one user, but it needs impersonation rights. Also look at \u003Ccode>ClusterExternalSecret\u003C\u002Fcode>, which creates ExternalSecrets in many namespaces.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Existing objects.\u003C\u002Fstrong> An audit sketch (untested, needs \u003Ccode>jq\u003C\u002Fcode>):\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode class=\"lang-sh\">\u003Cspan class=\"hljs-comment\"># ExternalSecrets with unusual templates (read-only)\u003C\u002Fspan>\nkubectl get externalsecrets -A -o json | jq -r '\n  .items[] | select(\n    (.spec.target.\u003Cspan class=\"hljs-keyword\">template\u003C\u002Fspan>.\u003Cspan class=\"hljs-keyword\">type\u003C\u002Fspan> \u002F\u002F \u003Cspan class=\"hljs-string\">\"\"\u003C\u002Fspan> | test(\u003Cspan class=\"hljs-string\">\"service-account-token|bootstrap\"\u003C\u002Fspan>; \u003Cspan class=\"hljs-string\">\"i\"\u003C\u002Fspan>))\n    \u003Cspan class=\"hljs-keyword\">or\u003C\u002Fspan> (.spec.target.\u003Cspan class=\"hljs-keyword\">template\u003C\u002Fspan>.metadata.annotations \u002F\u002F {} | keys | \u003Cspan class=\"hljs-built_in\">any\u003C\u002Fspan>(test(\u003Cspan class=\"hljs-string\">\"service-account\"\u003C\u002Fspan>; \u003Cspan class=\"hljs-string\">\"i\"\u003C\u002Fspan>)))\n    \u003Cspan class=\"hljs-keyword\">or\u003C\u002Fspan> ([.spec.target.\u003Cspan class=\"hljs-keyword\">template\u003C\u002Fspan>.templateFrom[]?.target \u002F\u002F \u003Cspan class=\"hljs-string\">\"\"\u003C\u002Fspan>]\n        | \u003Cspan class=\"hljs-built_in\">any\u003C\u002Fspan>(test(\u003Cspan class=\"hljs-string\">\"^(|data|annotations|labels)$\"\u003C\u002Fspan>; \u003Cspan class=\"hljs-string\">\"i\"\u003C\u002Fspan>) | \u003Cspan class=\"hljs-keyword\">not\u003C\u002Fspan>))\n    \u003Cspan class=\"hljs-keyword\">or\u003C\u002Fspan> (.spec.target.manifest != null)\n  ) | \u003Cspan class=\"hljs-string\">\"\\(.metadata.namespace)\u002F\\(.metadata.name)\"\u003C\u002Fspan>'\n\n\u003Cspan class=\"hljs-comment\"># Service account token Secrets owned by an ExternalSecret\u003C\u002Fspan>\nkubectl get secrets -A -o json | jq -r '\n  .items[]\n  | select(.\u003Cspan class=\"hljs-keyword\">type\u003C\u002Fspan> == \u003Cspan class=\"hljs-string\">\"kubernetes.io\u002Fservice-account-token\"\u003C\u002Fspan>)\n  | select(\u003Cspan class=\"hljs-built_in\">any\u003C\u002Fspan>(.metadata.ownerReferences[]?; .kind == \u003Cspan class=\"hljs-string\">\"ExternalSecret\"\u003C\u002Fspan>))\n  | \u003Cspan class=\"hljs-string\">\"\\(.metadata.namespace)\u002F\\(.metadata.name)\"\u003C\u002Fspan>'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The second query assumes the default \u003Ccode>creationPolicy\u003C\u002Fcode>, under which the operator sets an owner reference. We did not verify that, so a Secret created under another policy may not appear. A hit in either list is a reason to look, not proof of abuse; legitimate uses of \u003Ccode>manifest\u003C\u002Fcode> exist. If the cluster has audit logging, search it for create and update events on \u003Ccode>externalsecrets\u003C\u002Fcode> whose template type contains \u003Ccode>service-account\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"what-should-you-do-\">What should you do?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> upgrade, narrow who can write ExternalSecrets, consider a native agent, and add an admission rule for template types.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>1.Upgrade to 2.13.0 or later.\u003C\u002Fstrong> The latest release when we checked was 2.14.0 (October 23, 2026). Its notes list some security-related hardening, for example \"Sanitize Controller Status and Event Errors\", but nothing about this advisory. So 2.14.0 is a normal upgrade target, not a second fix. Read the notes for your jump, because version 2.13.0 also bumped the Go toolchain.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>2. Restrict RBAC.\u003C\u002Fstrong> Treat \u003Ccode>create\u003C\u002Fcode> and \u003Ccode>update\u003C\u002Fcode> on \u003Ccode>externalsecrets\u003C\u002Fcode> as a sensitive permission. ESO's security guide says: \"It is crucial to properly restrict access to ESO resources such as ExternalSecret and SecretStore where necessary\". The chart supports \u003Ccode>scopedRBAC\u003C\u002Fcode> and \u003Ccode>scopedNamespace\u003C\u002Fcode> to limit what the controller reconciles. For \u003Ccode>ClusterSecretStore\u003C\u002Fcode>, the docs show \u003Ccode>conditions\u003C\u002Fcode> with a \u003Ccode>namespaceSelector\u003C\u002Fcode>, so only labelled namespaces may reference it.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>3. Add admission control.\u003C\u002Fstrong> This is a workaround from the advisory, and ESO's docs do not ship a ready policy for template types. As an example, a native \u003Ccode>ValidatingAdmissionPolicy\u003C\u002Fcode> could deny templates that produce the two risky types. This is our draft and untested:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"lang-yaml\">\u003Cspan class=\"hljs-attribute\">apiVersion\u003C\u002Fspan>: admissionregistration.k8s.io\u002Fv1\n\u003Cspan class=\"hljs-attribute\">kind\u003C\u002Fspan>: ValidatingAdmissionPolicy\n\u003Cspan class=\"hljs-attribute\">metadata\u003C\u002Fspan>:\n  \u003Cspan class=\"hljs-attribute\">name\u003C\u002Fspan>: eso-deny-sa-token-template\n\u003Cspan class=\"hljs-attribute\">spec\u003C\u002Fspan>:\n  \u003Cspan class=\"hljs-attribute\">failurePolicy\u003C\u002Fspan>: Fail\n  \u003Cspan class=\"hljs-attribute\">matchConstraints\u003C\u002Fspan>:\n    \u003Cspan class=\"hljs-attribute\">resourceRules\u003C\u002Fspan>:\n    - \u003Cspan class=\"hljs-attribute\">apiGroups\u003C\u002Fspan>: [\u003Cspan class=\"hljs-string\">\"external-secrets.io\"\u003C\u002Fspan>]\n      \u003Cspan class=\"hljs-attribute\">apiVersions\u003C\u002Fspan>: [\u003Cspan class=\"hljs-string\">\"*\"\u003C\u002Fspan>]\n      \u003Cspan class=\"hljs-attribute\">operations\u003C\u002Fspan>: [\u003Cspan class=\"hljs-string\">\"CREATE\"\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">\"UPDATE\"\u003C\u002Fspan>]\n      \u003Cspan class=\"hljs-attribute\">resources\u003C\u002Fspan>: [\u003Cspan class=\"hljs-string\">\"externalsecrets\"\u003C\u002Fspan>]\n  \u003Cspan class=\"hljs-attribute\">validations\u003C\u002Fspan>:\n  - \u003Cspan class=\"hljs-attribute\">expression\u003C\u002Fspan>: &gt;-\n      !has(object.spec.target) || !has(object.spec.target.template) ||\n      !has(object.spec.target.template.type) ||\n      !(object.spec.target.template.type in\n        [\u003Cspan class=\"hljs-string\">\"kubernetes.io\u002Fservice-account-token\"\u003C\u002Fspan>, \u003Cspan class=\"hljs-string\">\"bootstrap.kubernetes.io\u002Ftoken\"\u003C\u002Fspan>])\n    \u003Cspan class=\"hljs-attribute\">message\u003C\u002Fspan>: \u003Cspan class=\"hljs-string\">\"ExternalSecret templates must not create service account token or bootstrap token Secrets\"\u003C\u002Fspan>\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>It also needs a \u003Ccode>ValidatingAdmissionPolicyBinding\u003C\u002Fcode> with \u003Ccode>validationActions: [Deny]\u003C\u002Fcode>. It does not cover \u003Ccode>spec.target.manifest\u003C\u002Fcode>, a type set through other fields, or \u003Ccode>ClusterExternalSecret\u003C\u002Fcode>, where the spec is nested under \u003Ccode>spec.externalSecretSpec\u003C\u002Fcode>. Use it as a starting point and extend it, or write the equivalent in Kyverno or Gatekeeper.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>4. Consider disabling legacy token generation.\u003C\u002Fstrong> The Kubernetes docs say the token controller needs \u003Ccode>--service-account-private-key-file\u003C\u002Fcode>, and the reference describes that flag as \"Enables legacy secret-based tokens when set\". \u003Ccode>--controllers=*,-serviceaccount-token-controller\u003C\u002Fcode> is a documented way to disable that controller. We could not verify the side effects. Workloads or CI jobs that still use legacy token Secrets would break, and managed Kubernetes services may not expose these flags.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>5. Evaluate native sync agents over custom operators.\u003C\u002Fstrong> This CVE highlights the inherent risk of using Custom Resource Definitions (CRDs) like \u003Ccode>ExternalSecret\u003C\u002Fcode> as an intermediary layer for secret management. If a user can write to the CRD, they can manipulate the operator's broader permissions. As an architectural alternative, \u003Ca href=\"https:\u002F\u002Fennote.io\u002Fagent\u002F\">Ennote's Kubernetes Smart Agent\u003C\u002Fa> eliminates the need for External Secrets Operator entirely. It uses an outbound gRPC stream to push secrets directly into native Kubernetes Secrets in under one second without requiring \u003Ccode>ExternalSecret\u003C\u002Fcode> custom resources, sidecars, or inbound firewall rules.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>6. Rotate if you find a suspicious token.\u003C\u002Fstrong> Delete the Secret and any ExternalSecret that produced it, then review what the token could reach. The Kubernetes docs say the token controller removes the token Secrets of a deleted ServiceAccount. We did not verify whether deleting a legacy token Secret alone revokes the token, so also consider recreating the affected ServiceAccount. For the general order of actions after a credential has leaked, see our guide on \u003Ca href=\"https:\u002F\u002Fennote.io\u002Fblog\u002Fleaked-openai-or-anthropic-api-key-what-to-do-in-the-first-hour\">what to do when an API key leaks\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"what-does-not-help-\">What does not help?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Short answer:\u003C\u002Fstrong> \u003Ccode>rbac.serviceAccountTokenCreate: false\u003C\u002Fcode> is not a mitigation for this advisory, as far as we can tell.\u003C\u002Fp>\n\u003Cp>ESO's security guide mentions that the controller role includes a blanket \u003Ccode>serviceaccounts\u002Ftoken: create\u003C\u002Fcode> permission and that you can turn it off with \u003Ccode>rbac.serviceAccountTokenCreate: false\u003C\u002Fcode>. The chart comment describes it as the \u003Ccode>serviceaccounts\u002Ftoken\u003C\u002Fcode> create permission, needed for ServiceAccounts referenced in SecretStore specs (\u003Ccode>serviceAccountRef\u003C\u002Fcode>). The token in this advisory is a different thing: a legacy Secret populated by \u003Ccode>kube-controller-manager\u003C\u002Fcode>. Reading the chart and the Kubernetes docs, the setting does not touch that path. This is our reasoning, and ESO's docs do not say either way. Turn it off for least privilege, but not as a fix for this advisory.\u003C\u002Fp>\n\u003Cp>According to the advisory, the first fix could be bypassed with an alternative spelling of the target, so validation now also runs on the final Secret. The practical lesson is defense in depth: the cluster, not only the operator, should refuse to hand a user a long-lived credential they should not hold.\u003C\u002Fp>\n\u003Ch2 id=\"sources\">Sources\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>Advisories, opened October 27, 2026: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Fsecurity\u002Fadvisories\u002FGHSA-v6x5-m838-gqph\">GHSA-v6x5-m838-gqph\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Fsecurity\u002Fadvisories\u002FGHSA-fq7h-9x26-6j22\">GHSA-fq7h-9x26-6j22\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>ESO releases: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Freleases\u002Ftag\u002Fv2.13.0\">v2.13.0\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Freleases\u002Ftag\u002Fv2.14.0\">v2.14.0\u003C\u002Fa>; pull requests \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Fpull\u002F7066\">#7066\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fexternal-secrets\u002Fexternal-secrets\u002Fpull\u002F7067\">#7067\u003C\u002Fa>; validator and controller code at tags v2.12.0 and v2.13.0\u003C\u002Fli>\n\u003Cli>ESO docs: \u003Ca href=\"https:\u002F\u002Fexternal-secrets.io\u002Flatest\u002Fguides\u002Fsecurity-best-practices\u002F\">Security best practices\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fexternal-secrets.io\u002Flatest\u002Fguides\u002Ftemplating\u002F\">Templating\u003C\u002Fa>; Helm chart \u003Ccode>values.yaml\u003C\u002Fcode> at v2.13.0\u003C\u002Fli>\n\u003Cli>Kubernetes docs: \u003Ca href=\"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Fconcepts\u002Fconfiguration\u002Fsecret\u002F\">Secrets\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Faccess-authn-authz\u002Fservice-accounts-admin\u002F\">Managing service accounts\u003C\u002Fa>, \u003Ca href=\"https:\u002F\u002Fkubernetes.io\u002Fdocs\u002Freference\u002Fcommand-line-tools-reference\u002Fkube-controller-manager\u002F\">kube-controller-manager\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>Not done: no cluster, no reproduction, no test of the snippets above\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Chr>\n\u003Cp>\u003Cstrong>Keep long-lived credentials out of cluster-wide reach.\u003C\u002Fstrong> Ennote is a secret manager for passwords, API keys, and environment variables, with role-based access, an audit log, and native Kubernetes synchronization. By replacing custom operators with our Smart Agent, you remove the RBAC complexity that leads to privilege escalation. \u003Ca href=\"https:\u002F\u002Fapp.ennote.io\u002F?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=external-secrets-operator-cve-2026-109546&amp;utm_content=footer\">Start for free\u003C\u002Fa> on the Developer plan.\u003C\u002Fp>",[9,10,11,12,13,14],"ExternalSecretsOperator","KubernetesSecurity","CVE2026109546","DevSecOps","InfoSec","CloudSecurity","https:\u002F\u002Ffirebasestorage.googleapis.com\u002Fv0\u002Fb\u002Fblog-01-c712e.firebasestorage.app\u002Fo\u002Fblog-covers%2F1793292894487_Gemini_Generated_Image_v9an5gv9an5gv9an.jpeg?alt=media&token=d460485e-a484-42d3-9479-176b07f00824",1793292896475,"ESO CVE-2026-109546: Service Account Token Escalation","External Secrets Operator before 2.13.0 let ExternalSecret creators get service account tokens. What the advisory says, how to check exposure, what to harden",[20,25,30],{"title":21,"slug":22,"coverImage":23,"createdAt":24},"The Evolution of Kubernetes Secret Delivery (And Why Polling is Dead)","the-evolution-of-kubernetes-secret-delivery-and-why-polling-is-dead","https:\u002F\u002Ffirebasestorage.googleapis.com\u002Fv0\u002Fb\u002Fblog-01-c712e.firebasestorage.app\u002Fo\u002Fblog-covers%2F1777523487463_diagramm%20(2).jpg?alt=media&token=5b01f974-cfe5-4890-b68f-5e178b422c6e",1777523490608,{"title":26,"slug":27,"coverImage":28,"createdAt":29},"The Identity-Driven Cryptography Behind Ennote's Zero-Persistence Vault","the-identity-driven-cryptography-behind-ennote-s-zero-persistence-vault","https:\u002F\u002Ffirebasestorage.googleapis.com\u002Fv0\u002Fb\u002Fblog-01-c712e.firebasestorage.app\u002Fo\u002Fblog-covers%2F1778396426354_og-image.png?alt=media&token=4bd31d6a-d525-443b-8879-5178a80b5335",1778396428194,{"title":31,"slug":32,"coverImage":33,"createdAt":34},"Where to Store MCP Server API Keys in Claude Code Without Committing Them","mcp-server-api-keys-claude-code","https:\u002F\u002Ffirebasestorage.googleapis.com\u002Fv0\u002Fb\u002Fblog-01-c712e.firebasestorage.app\u002Fo\u002Fblog-covers%2F1793122242811_Gemini_Generated_Image_wp95o4wp95o4wp95.jpeg?alt=media&token=43d78904-0e34-492b-927f-45e8ff52d992",1793122244638,1793299631568]