This is a master key left in the build room, not a front-door lock that opens from the street
CVE-2026-10840 is a permissioning flaw in the OpenShift Pipelines operator, mapped to CWE-732. In practical terms, the operator can leave the default pipeline service account or related RBAC objects with more authority than a pipeline execution path should have. The prompt identifies the vendor impact as CRITICAL 9.6 with PR:L, which already tells you this is not unauthenticated internet exploitation; the attacker needs a valid foothold inside OpenShift with enough rights to create or influence pipeline activity in a namespace that runs the vulnerable operator.
The vendor score overstates day-one enterprise urgency for most estates because the hardest part is not the bug mechanics, it is the attacker position requirement. This is a post-auth, in-cluster privilege escalation against a subset of OpenShift deployments that actually run Pipelines and delegate pipeline authoring broadly. That said, once the attacker gets to abuse a CI/CD identity, the blast radius can jump fast into secrets, image mutation, deployment tampering, and supply-chain persistence, so this is still a HIGH and not routine backlog material.
4 steps from start to impact.
Land in a namespace that uses Pipelines
oc or the Kubernetes API directly; nothing exotic is required if the adversary already has developer credentials or a compromised token. This step is the big severity brake because it implies prior access, not open internet reachability.- Authenticated OpenShift access
- Access to a namespace where the Pipelines operator is deployed and usable
- Ability to create, edit, or trigger pipeline-related resources
- Many enterprises do not grant pipeline authoring to broad user populations
- MFA, SSO, and short-lived tokens often gate initial access
- Some clusters do not run OpenShift Pipelines at all
PipelineRun, TaskRun, or related Tekton objects. External scanners will not reliably surface this because the weakness is RBAC state, not a banner-grabbable network service.Abuse the overprivileged pipeline identity
pipeline service account or another operator-managed identity carrying excessive permissions. Common operator tooling here is oc apply, kubectl, or an inline curl against the Kubernetes API from within the task pod using the mounted service account token. The weapon is the token, not memory corruption.- The vulnerable RBAC assignment must actually exist
- The pipeline execution path must inherit or select the overprivileged service account
- The attacker must be able to run a task or pipeline step under that identity
- Well-run deployments use custom service accounts with tighter roles
- Admission controls may block dangerous pod specs or image choices
- Namespace isolation can limit what the token can reach
oc, kubectl, curl, or reading /var/run/secrets/kubernetes.io/serviceaccount/token. Cluster posture tools that inventory RBAC bindings can often catch the risky bindings before exploitation.Pivot from build pod to control-plane actions
oc auth can-i, oc get secret, oc patch, or direct REST requests.- RBAC grants beyond the intended build-and-push scope
- Reachability from the pod to the cluster API
- Resources of value exist in the token's effective scope
- Least-privilege RBAC can contain the blast radius to a single namespace
- Secret encryption and external secret stores reduce immediate credential value
- OPA/Gatekeeper/Kyverno policies may block some mutating actions
list/get/watch against secrets or unexpected patch/update/delete on deployments, role bindings, or image streams from a pipeline service account subject.Translate RBAC abuse into supply-chain impact
- The compromised identity can write to build, image, or deployment paths
- The targeted namespace participates in real deployment workflows
- Downstream systems trust pipeline artifacts or config changes
- Signed image enforcement and admission verification can stop artifact tampering
- Change control on production namespaces may require separate approvals
- Segregated build and deploy identities reduce end-to-end blast radius
The supporting signals.
| In-the-wild status | No public evidence of active exploitation was identified in the reviewed sources. CISA KEV does not list this CVE. |
|---|---|
| KEV status | Not KEV-listed. CISA's catalog search source reviewed: Known Exploited Vulnerabilities Catalog. |
| Proof-of-concept availability | No public exploit or GitHub PoC specific to CVE-2026-10840 was found in the reviewed sources. Treat that as no public PoC found, not proof of non-exploitability. |
| EPSS | No public EPSS value for CVE-2026-10840 was visible in the reviewed searchable sources at assessment time. In practice, treat EPSS as not yet modeled or not yet surfaced publicly, so do not let a missing score suppress action. |
| CVSS vector readout | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:H means low-complexity exploitation over network-reachable control-plane APIs, but only after valid low-privilege access exists. Integrity and availability dominate; confidentiality is not the primary story. |
| Affected exposure population | Only OpenShift estates running the OpenShift Pipelines operator are in scope, and the practical attacker population narrows further to users who can influence pipeline execution. That makes this far less exposed than an unauthenticated appliance bug. |
| Affected component behavior | Red Hat documentation shows that OpenShift Pipelines creates a default pipeline service account and associated SCC/RBAC behavior. That matters because this vulnerability is about what that identity is allowed to do, not about a parser or daemon crash. |
| Fixed versions | A precise vendor-fixed version for CVE-2026-10840 was not publicly confirmed in the reviewed indexed sources. Track the Red Hat advisory/errata stream for the exact operator release and any OCP channel backports. |
| Scanning and exposure data | Internet exposure engines such as Shodan/Censys are the wrong lens here. This is an RBAC and service-account privilege condition inside authenticated OpenShift clusters, so exposure must be measured from cluster inventory and RBAC audits, not open-port telemetry. |
| Disclosure | Prompt-provided disclosure date: 2026-06-04. The prompt also maps the flaw to CWE-732 and vendor severity CRITICAL 9.6. |
noisgate verdict.
The decisive factor is that exploitation requires authenticated access to an OpenShift environment that actually runs Pipelines and lets the attacker influence pipeline execution. That is meaningful downward pressure from the vendor's critical baseline, but CI/CD identities can still mutate builds, deployments, and secrets quickly enough to keep this firmly in HIGH territory.
Why this verdict
- Start from the vendor's 9.6 because abusing an overprivileged CI/CD identity can directly damage integrity and availability across build and deployment paths.
- Downward adjustment for attacker position: the chain starts at
PR:L, which implies authenticated remote or internal access to OpenShift. This is not an internet-to-cluster compromise by itself; it is a post-initial-access privilege escalation. - Downward adjustment for reachable population: only organizations running the OpenShift Pipelines operator are exposed, and only namespaces where attackers can author or influence pipeline execution are realistically exploitable.
- Downward adjustment for modern controls: RBAC hygiene, custom service accounts, admission policies, and audit logging all meaningfully disrupt or expose the chain in mature clusters.
- Upward adjustment for blast radius: once the
pipelineidentity is too powerful, an attacker can tamper with images, secrets, and deployment logic, which is exactly how CI/CD bugs turn into supply-chain incidents.
Why not higher?
This is not higher because the vulnerability does not remove the need for a valid OpenShift foothold. Requiring authenticated access plus a deployed operator plus pipeline influence is too much compounding friction for a CRITICAL internet-priority rating in most 10,000-host environments.
Why not lower?
This is not lower because CI/CD service accounts sit on trust boundaries that matter more than their raw count in the fleet. If the pipeline identity is over-scoped, a low-privilege user can punch above their weight and alter software delivery paths, which is a materially dangerous enterprise outcome.
What to do — in priority order.
- Audit
pipelinebindings now — EnumerateRoleBindingandClusterRoleBindingobjects that reference thepipelineservice account and remove wildcard,admin,edit, or broader-than-needed grants. For a HIGH verdict, deploy this control within 30 days if you cannot patch immediately. - Force custom service accounts — Stop relying on the default
pipelineidentity for sensitive namespaces. Bind task and pipeline runs to narrowly scoped custom service accounts so a single operator-created default cannot become a shared escalation path; deploy within 30 days. - Restrict who can create PipelineRuns — Treat pipeline authoring as privileged administration, not generic developer access. Limit
createandupdateon Tekton resources to trusted groups and deploy this entitlement reduction within 30 days. - Fence CI/CD namespaces — Apply namespace isolation, admission policy, and egress controls around pipeline pods so a compromised task cannot freely pivot to broader API misuse. This is a strong containment measure to deploy within 30 days.
- Alert on service-account abuse — Create detections for
system:serviceaccount:*:pipelineperforming unusualget/list/watchon secrets or mutating deployments, RBAC, or image resources. Detection is not remediation, but it shortens dwell time and should be enabled within 30 days.
- A WAF does not help because the exploit path is authenticated use of Kubernetes/OpenShift APIs and RBAC semantics, not malicious HTTP payloads against a public web app.
- External vulnerability scanners alone will miss most of this risk because they do not understand effective service-account permissions inside the cluster.
- Patching worker nodes or the base OS without fixing the operator/RBAC state does not remove the overprivileged token path.
Crowdsourced verification payload.
Run this on an admin workstation with the oc CLI authenticated to the target OpenShift cluster. Invoke it as bash check_cve_2026_10840.sh; it needs rights to read service accounts, role bindings, cluster role bindings, roles, and cluster roles across namespaces.
#!/usr/bin/env bash
# check_cve_2026_10840.sh
# Heuristic check for overprivileged OpenShift Pipelines service-account bindings.
# Outputs: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
if ! command -v oc >/dev/null 2>&1; then
echo "UNKNOWN: oc CLI not found"
exit 2
fi
if ! oc whoami >/dev/null 2>&1; then
echo "UNKNOWN: not logged into an OpenShift cluster"
exit 2
fi
if ! oc get ns >/dev/null 2>&1; then
echo "UNKNOWN: insufficient privileges to query namespaces"
exit 2
fi
found_pipeline_sa=0
vuln=0
unknown=0
notes=""
is_dangerous_clusterrole() {
local cr="$1"
case "$cr" in
cluster-admin|admin|edit)
return 0
;;
*)
return 1
;;
esac
}
check_role_rules() {
local kind="$1"
local name="$2"
local ns="$3"
local jsonpath='{range .rules[*]}{.verbs}{"|"}{.resources}{"\n"}{end}'
local out
if [[ "$kind" == "Role" ]]; then
out=$(oc -n "$ns" get role "$name" -o jsonpath="$jsonpath" 2>/dev/null) || return 2
else
out=$(oc get clusterrole "$name" -o jsonpath="$jsonpath" 2>/dev/null) || return 2
fi
while IFS= read -r line; do
[[ -z "$line" ]] && continue
verbs="${line%%|*}"
resources="${line#*|}"
if [[ "$verbs" == *"*"* ]] || [[ "$resources" == *"*"* ]]; then
return 0
fi
if [[ "$resources" == *"secrets"* && ( "$verbs" == *"create"* || "$verbs" == *"update"* || "$verbs" == *"patch"* || "$verbs" == *"delete"* ) ]]; then
return 0
fi
if [[ "$resources" == *"roles"* || "$resources" == *"rolebindings"* || "$resources" == *"clusterroles"* || "$resources" == *"clusterrolebindings"* ]]; then
if [[ "$verbs" == *"create"* || "$verbs" == *"update"* || "$verbs" == *"patch"* || "$verbs" == *"delete"* || "$verbs" == *"bind"* || "$verbs" == *"escalate"* ]]; then
return 0
fi
fi
done <<< "$out"
return 1
}
for ns in $(oc get sa -A --no-headers 2>/dev/null | awk '$2=="pipeline" {print $1}'); do
found_pipeline_sa=1
# Namespace RoleBindings
while IFS='|' read -r rb_name role_ref_kind role_ref_name; do
[[ -z "$rb_name" ]] && continue
if [[ "$role_ref_kind" == "ClusterRole" ]] && is_dangerous_clusterrole "$role_ref_name"; then
vuln=1
notes+="namespace/$ns rolebinding/$rb_name -> dangerous clusterrole $role_ref_name; "
continue
fi
if check_role_rules "$role_ref_kind" "$role_ref_name" "$ns"; then
vuln=1
notes+="namespace/$ns rolebinding/$rb_name -> overbroad $role_ref_kind/$role_ref_name; "
else
rc=$?
if [[ $rc -eq 2 ]]; then
unknown=1
fi
fi
done < <(oc -n "$ns" get rolebinding -o jsonpath='{range .items[?(@.subjects)]}{.metadata.name}{"|"}{.roleRef.kind}{"|"}{.roleRef.name}{"\n"}{end}' 2>/dev/null | while IFS='|' read -r name kind ref; do
if oc -n "$ns" get rolebinding "$name" -o jsonpath='{range .subjects[*]}{.kind}{"|"}{.namespace}{"|"}{.name}{"\n"}{end}' 2>/dev/null | grep -q '^ServiceAccount|'"$ns"'|pipeline$'; then
echo "$name|$kind|$ref"
fi
done)
done
# ClusterRoleBindings that reference any pipeline service account
while IFS='|' read -r crb_name cr_name subject_ns; do
[[ -z "$crb_name" ]] && continue
found_pipeline_sa=1
if is_dangerous_clusterrole "$cr_name"; then
vuln=1
notes+="clusterrolebinding/$crb_name -> dangerous clusterrole $cr_name for pipeline SA in $subject_ns; "
continue
fi
if check_role_rules "ClusterRole" "$cr_name" "$subject_ns"; then
vuln=1
notes+="clusterrolebinding/$crb_name -> overbroad clusterrole/$cr_name for pipeline SA in $subject_ns; "
else
rc=$?
if [[ $rc -eq 2 ]]; then
unknown=1
fi
fi
done < <(oc get clusterrolebinding -o jsonpath='{range .items[?(@.subjects)]}{.metadata.name}{"|"}{.roleRef.name}{"\n"}{end}' 2>/dev/null | while IFS='|' read -r name ref; do
matches=$(oc get clusterrolebinding "$name" -o jsonpath='{range .subjects[*]}{.kind}{"|"}{.namespace}{"|"}{.name}{"\n"}{end}' 2>/dev/null | awk -F'|' '$1=="ServiceAccount" && $3=="pipeline" {print $2}')
if [[ -n "$matches" ]]; then
while IFS= read -r m; do
echo "$name|$ref|$m"
done <<< "$matches"
fi
done)
if [[ $found_pipeline_sa -eq 0 ]]; then
echo "UNKNOWN: no pipeline service accounts found; OpenShift Pipelines may not be installed or access is incomplete"
exit 2
fi
if [[ $vuln -eq 1 ]]; then
echo "VULNERABLE: $notes"
exit 1
fi
if [[ $unknown -eq 1 ]]; then
echo "UNKNOWN: no clearly dangerous binding found, but some RBAC objects could not be inspected"
exit 2
fi
echo "PATCHED: no obviously overprivileged bindings found for pipeline service accounts"
exit 0
If you remember one thing.
pipeline service-account bindings first; per the noisgate mitigation SLA, get those compensating controls in place within 30 days. Then complete vendor remediation by upgrading to the fixed operator release and any required OpenShift backports within 180 days per the noisgate remediation SLA; if you discover the pipeline identity already has broad write access to secrets, RBAC, or deployment objects in production namespaces, compress that work to the front of the queue rather than waiting for the long window.Sources
- Red Hat OpenShift Pipelines 1.21 - Configuring the security context for pods
- Red Hat OpenShift Container Platform 4.7 - Pipelines documentation
- Red Hat OpenShift Pipelines 1.20 - Securing OpenShift Pipelines
- Red Hat Security Data
- Red Hat Notifications and Advisories
- CISA Known Exploited Vulnerabilities Catalog
- FIRST EPSS API documentation
- OffSeq summary of prior OpenShift Pipelines operator RBAC issue
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.