Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
check_type: Platform

failure_reason: |-
One or more bridge NetworkAttachmentDefinitions do not set
'macspoofchk: true' in their CNI configuration, allowing guests to
spoof layer-2 identities.

inputs:
- name: nads
kubernetes_input_spec:
api_version: k8s.cni.cncf.io/v1
resource: network-attachment-definitions

expression: |
nads.items.all(n,
!has(n.spec.config) ||
!("type" in parseJSON(n.spec.config)) ||
parseJSON(n.spec.config).type != "bridge" ||
("macspoofchk" in parseJSON(n.spec.config) && parseJSON(n.spec.config).macspoofchk == true)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# CEL rule unit-test fixtures. Evaluated by tests/unit/kubernetes/test_cel_rules.py
# via celctl (cel-go, the Compliance Operator scanner engine).
# Seeded from real API objects; see provenance. Versions only, nothing cluster-identifiable.
provenance:
fetched_with: modeled on real API objects (celctl cac scaffold format)
date: '2026-07-24'
openshift_version: 4.21.0
kubernetes_version: v1.34
source_api_versions:
nads: k8s.cni.cncf.io/v1
cases:
- name: no NADs -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items: []
- name: bridge nad with macspoofchk true -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: bridge-ok
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "bridge", "bridge": "br1",
"macspoofchk": true}'
- name: non-bridge nad is ignored -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: ovn-a
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "ovn-k8s-cni-overlay", "topology":
"layer2", "netAttachDefName": "default/ovn-a"}'
- name: nad config without type key is ignored -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: plugins-nad
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "name": "br-net", "plugins": [{"type":
"cnv-bridge", "bridge": "br1"}]}'
- name: bridge nad without macspoofchk -> non-compliant
expect: false
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: bridge-nofilter
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "bridge", "bridge": "br2"}'
- name: bridge nad with macspoofchk false -> non-compliant
expect: false
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: bridge-off
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "bridge", "bridge": "br3",
"macspoofchk": false}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
documentation_complete: true

title: 'Bridge Network Attachments Must Enable MAC Spoof Filtering'

description: |-
Bridge-type NetworkAttachmentDefinitions must set 'macspoofchk: true'
in their CNI configuration so the bridge drops frames whose source MAC
differs from the address assigned to the interface. Without it, a
compromised guest can impersonate other workloads or infrastructure at
layer 2 (ARP spoofing, man-in-the-middle).

rationale: |-
Layer-2 identity is the basis for switching decisions on secondary
networks. A guest that can spoof MAC addresses can intercept or
redirect other workloads' traffic on the same segment.

severity: medium

ocil_clause: 'a bridge NetworkAttachmentDefinition does not enable macspoofchk'

ocil: |-
Run the following command:
<pre>$ oc get network-attachment-definitions -A -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.config}{"\n"}{end}'</pre>
Every config with '"type":"bridge"' should set '"macspoofchk": true'.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
check_type: Platform

failure_reason: |-
One or more localnet NetworkAttachmentDefinitions do not declare a
'vlanID' in their CNI configuration, leaving virtual machine traffic on
the untagged provider segment.

inputs:
- name: nads
kubernetes_input_spec:
api_version: k8s.cni.cncf.io/v1
resource: network-attachment-definitions

expression: |
nads.items.all(n,
!has(n.spec.config) ||
!("topology" in parseJSON(n.spec.config)) ||
parseJSON(n.spec.config).topology != "localnet" ||
("vlanID" in parseJSON(n.spec.config) && parseJSON(n.spec.config).vlanID > 0)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# CEL rule unit-test fixtures. Evaluated by tests/unit/kubernetes/test_cel_rules.py
# via celctl (cel-go, the Compliance Operator scanner engine).
# Seeded from real API objects; see provenance. Versions only, nothing cluster-identifiable.
provenance:
fetched_with: modeled on real API objects (celctl cac scaffold format)
date: '2026-07-24'
openshift_version: 4.21.0
kubernetes_version: v1.34
source_api_versions:
nads: k8s.cni.cncf.io/v1
cases:
- name: no NADs -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items: []
- name: localnet nad with vlanID -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: localnet-a
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "ovn-k8s-cni-overlay", "topology":
"localnet", "vlanID": 200, "netAttachDefName": "default/localnet-a"}'
- name: non-localnet nad without vlan is ignored -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: bridge-a
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "bridge", "bridge": "br1"}'
- name: nad config without topology key is ignored -> compliant
expect: true
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: plugins-nad
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "name": "br-net", "plugins": [{"type":
"cnv-bridge", "bridge": "br1"}]}'
- name: localnet nad without vlanID -> non-compliant
expect: false
inputs:
nads:
apiVersion: v1
kind: List
items:
- apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: localnet-untagged
namespace: default
spec:
config: '{"cniVersion": "0.3.1", "type": "ovn-k8s-cni-overlay", "topology":
"localnet", "netAttachDefName": "default/localnet-untagged"}'
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
documentation_complete: true

title: 'Localnet Network Attachments Must Declare a Dedicated VLAN'

description: |-
NetworkAttachmentDefinitions with the OVN 'localnet' topology bridge
virtual machine traffic onto the physical provider network. Such
attachments must declare a 'vlanID' in their CNI configuration so the
traffic is segmented on a dedicated VLAN rather than the untagged
provider segment. Environments that intentionally use untagged provider
networks should waive this rule for those objects.

rationale: |-
Without VLAN segmentation, workloads attached to localnet networks
share a broadcast domain with other traffic, enabling lateral movement,
sniffing and spoofing between tenants and toward the infrastructure.

severity: medium

ocil_clause: 'a localnet NetworkAttachmentDefinition does not declare a vlanID'

ocil: |-
Run the following command:
<pre>$ oc get network-attachment-definitions -A -o jsonpath='{range .items[*]}{.metadata.name}: {.spec.config}{"\n"}{end}'</pre>
Every config with '"topology":"localnet"' should declare a non-zero vlanID.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
check_type: Platform

failure_reason: |-
One or more SriovNetwork resources do not set '.spec.spoofChk' to "on",
allowing guests to spoof layer-2 identities.

inputs:
- name: sriovnets
kubernetes_input_spec:
api_version: sriovnetwork.openshift.io/v1
resource: sriovnetworks

expression: |
sriovnets.items.all(n,
has(n.spec.spoofChk) && n.spec.spoofChk == "on"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# CEL rule unit-test fixtures. Evaluated by tests/unit/kubernetes/test_cel_rules.py
# via celctl (cel-go, the Compliance Operator scanner engine).
# Seeded from real API objects; see provenance. Versions only, nothing cluster-identifiable.
provenance:
fetched_with: modeled on real API objects (celctl cac scaffold format)
date: '2026-07-24'
openshift_version: 4.21.0
kubernetes_version: v1.34
source_api_versions:
sriovnets: sriovnetwork.openshift.io/v1
cases:
- name: no SriovNetworks -> compliant
expect: true
inputs:
sriovnets:
apiVersion: v1
kind: List
items: []
- name: sriov spoofChk on -> compliant
expect: true
inputs:
sriovnets:
apiVersion: v1
kind: List
items:
- apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
name: net-a
namespace: openshift-sriov-network-operator
spec:
spoofChk: 'on'
resourceName: sriov_a
- name: sriov spoofChk off -> non-compliant
expect: false
inputs:
sriovnets:
apiVersion: v1
kind: List
items:
- apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
name: net-off
namespace: openshift-sriov-network-operator
spec:
spoofChk: 'off'
resourceName: sriov_b
- name: sriov spoofChk unset -> non-compliant (benchmark requires explicit on)
expect: false
inputs:
sriovnets:
apiVersion: v1
kind: List
items:
- apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
name: net-unset
namespace: openshift-sriov-network-operator
spec:
resourceName: sriov_c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
documentation_complete: true

title: 'SR-IOV Networks Must Enable MAC Spoof Checking'

description: |-
SR-IOV networks must set '.spec.spoofChk' to "on" so the NIC rejects
frames whose source MAC differs from the address assigned to the
virtual function. Without it, a compromised guest can impersonate other
workloads or infrastructure at layer 2.

NOTE: this rule reads SriovNetwork resources and therefore requires the
SR-IOV Network Operator. On clusters without the operator the resource
type does not exist and the check reports an error; CPE applicability
for CEL rules (CMP-4483) will mark it Not Applicable instead.

rationale: |-
Layer-2 identity is the basis for switching decisions on secondary
networks. A guest that can spoof MAC addresses can intercept or
redirect other workloads' traffic on the same segment.

severity: medium

ocil_clause: 'an SriovNetwork does not set spoofChk to on'

ocil: |-
Run the following command:
<pre>$ oc get sriovnetwork -A -o jsonpath='{range .items[*]}{.metadata.name}: spoofChk={.spec.spoofChk}{"\n"}{end}'</pre>
Every SR-IOV network should set spoofChk to "on".
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
check_type: Platform

failure_reason: |-
One or more SriovNetwork resources do not declare a dedicated VLAN in
'.spec.vlan', leaving virtual machine traffic unsegmented.

inputs:
- name: sriovnets
kubernetes_input_spec:
api_version: sriovnetwork.openshift.io/v1
resource: sriovnetworks

expression: |
sriovnets.items.all(n,
has(n.spec.vlan) && n.spec.vlan > 0
)
Loading
Loading