Skip to content

[cherry-pick: release-v0.79.x] fix(openshift): block SCC escalation via annotations - #4073

Open
tekton-robot wants to merge 1 commit into
release-v0.79.xfrom
cherry-pick-3994-to-release-v0.79.x
Open

[cherry-pick: release-v0.79.x] fix(openshift): block SCC escalation via annotations#4073
tekton-robot wants to merge 1 commit into
release-v0.79.xfrom
cherry-pick-3994-to-release-v0.79.x

Conversation

@tekton-robot

Copy link
Copy Markdown
Contributor

This is a cherry-pick of #3994


Changes

Fixes a security vulnerability where empty maxAllowed in
TektonConfig.spec.platforms.openshift.scc allowed privilege
escalation to any SCC (including privileged) via namespace
annotations.

Implemented three-layer defense-in-depth:

  • Layer 1: Default maxAllowed to match default SCC (prevents empty configuration)
  • Layer 2: Namespace webhook validates the maxAllowed if it is empty then allow only default SCC.
  • Layer 3: RBAC reconciler treats empty maxAllowed as default SCC (final enforcement)

This prevents attackers from annotating namespaces with
operator.tekton.dev/scc=privileged to gain node-level access.

Also documents the new behavior: empty maxAllowed is now treated
as "only the default SCC is allowed" to prevent privilege escalation
via the operator.tekton.dev/scc namespace annotation. Notes that
requesting a less restrictive SCC such as anyuid now requires
setting maxAllowed explicitly in TektonConfig.

Manual Testing on OpenShift Cluster

Prerequisites

  • Deploy operator with these changes on Openshift cluster
  • Verify TektonConfig exists and status is True: oc get tektonconfig config

Test Cases

✅ Test 1: Default SCC Should Be Allowed

cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: test-default-scc
  annotations:
    operator.tekton.dev/scc: "pipelines-scc"
EOF

Expected: Namespace created successfully
Cleanup: oc delete namespace test-default-scc


❌ Test 2: Privileged SCC Should Be Blocked (Security Fix)

cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: test-privileged
  annotations:
    operator.tekton.dev/scc: "privileged"
EOF

Expected: Error message:

Error from server: admission webhook denied the request: 
namespace test-privileged requested SCC privileged, but maxAllowed 
is not configured. Only the default SCC pipelines-scc is permitted

❌ Test 3: Anyuid SCC Should Be Blocked (Security Fix)

cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: test-anyuid
  annotations:
    operator.tekton.dev/scc: "anyuid"
EOF

Expected: Similar rejection with anyuid in the error message


✅ Test 4: Set maxAllowed - Verify Normal Flow Still Works

# Update TektonConfig
oc patch tektonconfig config --type=merge -p '
{
  "spec": {
    "platforms": {
      "openshift": {
        "scc": {
          "maxAllowed": "anyuid"
        }
      }
    }
  }
}'

# Wait 10 seconds for webhook to update
sleep 10

# Now anyuid should be allowed
cat <<EOF | oc apply -f -
apiVersion: v1
kind: Namespace
metadata:
  name: test-anyuid-allowed
  annotations:
    operator.tekton.dev/scc: "anyuid"
EOF

Expected: Namespace created successfully
Cleanup: oc delete namespace test-anyuid-allowed


Submitter Checklist

These are the criteria that every PR should meet, please check them off as you
review them:

See the contribution guide for more details.

Release Notes

-->

Fixed privilege escalation vulnerability in namespace SCC validation. When `maxAllowed` SCC is not configured, namespaces can now only use the default SCC (`pipelines-scc`), preventing unauthorized privilege escalation via namespace annotations.

Fixes a security vulnerability where empty maxAllowed in
TektonConfig.spec.platforms.openshift.scc allowed privilege
escalation to any SCC (including privileged) via namespace
annotations.

Implemented three-layer defense-in-depth:
- Layer 1: Default maxAllowed to match default SCC (prevents
  empty configuration)
- Layer 2: Namespace webhook validates the maxAllowed if it is empty
  then allow only default SCC.
- Layer 3: RBAC reconciler treats empty maxAllowed as default
  SCC (final enforcement)

This prevents attackers from annotating namespaces with
operator.tekton.dev/scc=privileged to gain node-level access.

Also documents the new behavior: empty maxAllowed is now treated
as "only the default SCC is allowed" to prevent privilege escalation
via the operator.tekton.dev/scc namespace annotation. Notes that
requesting a less restrictive SCC such as anyuid now requires
setting maxAllowed explicitly in TektonConfig.

Co-authored-by: Anitha Natarajan <anataraj@redhat.com>
Signed-off-by: pratap0007 <shverma@redhat.com>
@tekton-robot tekton-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Sep 11, 2026
@tekton-robot

Copy link
Copy Markdown
Contributor Author

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign jkhelil after the PR has been reviewed.
You can assign the PR to them by writing /assign @jkhelil in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants