Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

security requirements of the container-native operators #1967

Merged
Merged
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
72 changes: 68 additions & 4 deletions CATALOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be

## Test cases summary

### Total test cases: 109
### Total test cases: 113

### Total suites: 10

Expand All @@ -19,7 +19,7 @@ Depending on the workload type, not all tests are required to pass to satisfy be
|manageability|2|
|networking|11|
|observability|4|
|operator|7|
|operator|11|
|performance|6|
|platform-alteration|13|
|preflight|17|
Expand All @@ -36,11 +36,11 @@ Depending on the workload type, not all tests are required to pass to satisfy be
|---|---|
|7|1|

### Non-Telco specific tests only: 62
### Non-Telco specific tests only: 66

|Mandatory|Optional|
|---|---|
|42|20|
|46|20|

### Telco specific tests only: 27

Expand Down Expand Up @@ -1122,6 +1122,22 @@ Tags|telco,observability

### operator

#### operator-automount-tokens

Property|Description
---|---
Unique ID|operator-automount-tokens
Description|Tests that check that the pods disable the automount service account token."
Suggested Remediation|Ensure that the pods have the automount service account token disabled.
Best Practice Reference|https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-cnf-operator-requirements
Exception Process|No exceptions
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-crd-openapi-schema

Property|Description
Expand Down Expand Up @@ -1202,6 +1218,54 @@ Tags|common,operator
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-read-only-file-system

Property|Description
---|---
Unique ID|operator-read-only-file-system
Description|Tests that check that the pods have the read-only root filesystem setting enabled.
Suggested Remediation|Ensure that the pods have the read-only root filesystem setting enabled.
Best Practice Reference|https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-cnf-operator-requirements
Exception Process|No exceptions
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-run-as-non-root

Property|Description
---|---
Unique ID|operator-run-as-non-root
Description|Tests that checks the pods ensure they are run as non root.
Suggested Remediation|Ensure that the pods are running as non root.
Best Practice Reference|https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-cnf-operator-requirements
Exception Process|No exceptions
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-run-as-user-id

Property|Description
---|---
Unique ID|operator-run-as-user-id
Description|Tests that checks the user id of the pods ensure it is not 0.
Suggested Remediation|Ensure that the user ID of the pods is not 0.
Best Practice Reference|https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-cnf-operator-requirements
Exception Process|No exceptions
Tags|common,operator
|**Scenario**|**Optional/Mandatory**|
|Extended|Mandatory|
|Far-Edge|Mandatory|
|Non-Telco|Mandatory|
|Telco|Mandatory|

#### operator-semantic-versioning

Property|Description
Expand Down
2 changes: 1 addition & 1 deletion cnf-certification-test/accesscontrol/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import (

"github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol/namespace"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol/rbac"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol/resources"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/accesscontrol/securitycontextcontainer"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/common"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/common/rbac"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/identifiers"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/networking/netutil"
"github.com/test-network-function/cnf-certification-test/cnf-certification-test/networking/services"
Expand Down
4 changes: 4 additions & 0 deletions cnf-certification-test/identifiers/doclinks.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ const (
TestOperatorCrdSchemaIdentifierDocLink = DocOperatorRequirement
TestOperatorCrdVersioningIdentifierDocLink = DocOperatorRequirement
TestOperatorSingleCrdOwnerIdentifierDocLink = DocOperatorRequirement
TestOperatorRunAsUserIDDocLink = DocOperatorRequirement
TestOperatorRunAsNonRootDocLink = DocOperatorRequirement
TestOperatorAutomountTokensDocLink = DocOperatorRequirement
TestOperatorReadOnlyFilesystemDocLink = DocOperatorRequirement

// Observability Test Suite
TestLoggingIdentifierDocLink = "https://test-network-function.github.io/cnf-best-practices-guide/#cnf-best-practices-logging"
Expand Down
68 changes: 68 additions & 0 deletions cnf-certification-test/identifiers/identifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ var (
TestHelmIsCertifiedIdentifier claim.Identifier
TestOperatorIsInstalledViaOLMIdentifier claim.Identifier
TestOperatorHasSemanticVersioningIdentifier claim.Identifier
TestOperatorReadOnlyFilesystem claim.Identifier
TestOperatorAutomountTokens claim.Identifier
TestOperatorRunAsNonRoot claim.Identifier
TestOperatorRunAsUserID claim.Identifier
TestOperatorCrdVersioningIdentifier claim.Identifier
TestOperatorCrdSchemaIdentifier claim.Identifier
TestOperatorSingleCrdOwnerIdentifier claim.Identifier
Expand Down Expand Up @@ -930,6 +934,70 @@ that Node's kernel may not have the same hacks.'`,
},
TagCommon)

TestOperatorRunAsUserID = AddCatalogEntry(
"run-as-user-id",
common.OperatorTestKey,
`Tests that checks the user id of the pods ensure it is not 0.`,
OperatorRunAsUserID,
NoExceptions,
TestOperatorRunAsUserIDDocLink,
true,
map[string]string{
FarEdge: Mandatory,
Telco: Mandatory,
NonTelco: Mandatory,
Extended: Mandatory,
},
TagCommon)

TestOperatorRunAsNonRoot = AddCatalogEntry(
"run-as-non-root",
common.OperatorTestKey,
`Tests that checks the pods ensure they are run as non root.`,
OperatorRunAsNonRoot,
NoExceptions,
TestOperatorRunAsNonRootDocLink,
true,
map[string]string{
FarEdge: Mandatory,
Telco: Mandatory,
NonTelco: Mandatory,
Extended: Mandatory,
},
TagCommon)

TestOperatorAutomountTokens = AddCatalogEntry(
"automount-tokens",
common.OperatorTestKey,
`Tests that check that the pods disable the automount service account token."`,
OperatorAutomountTokens,
NoExceptions,
TestOperatorAutomountTokensDocLink,
true,
map[string]string{
FarEdge: Mandatory,
Telco: Mandatory,
NonTelco: Mandatory,
Extended: Mandatory,
},
TagCommon)

TestOperatorReadOnlyFilesystem = AddCatalogEntry(
"read-only-file-system",
common.OperatorTestKey,
`Tests that check that the pods have the read-only root filesystem setting enabled.`,
OperatorReadOnlyFilesystem,
NoExceptions,
TestOperatorReadOnlyFilesystemDocLink,
true,
map[string]string{
FarEdge: Mandatory,
Telco: Mandatory,
NonTelco: Mandatory,
Extended: Mandatory,
},
TagCommon)

TestOperatorCrdVersioningIdentifier = AddCatalogEntry(
"crd-versioning",
common.OperatorTestKey,
Expand Down
8 changes: 8 additions & 0 deletions cnf-certification-test/identifiers/remediation.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ const (

OperatorCrdSchemaIdentifierRemediation = `Ensure that the Operator CRD is defined with OpenAPI spec.`

OperatorRunAsUserID = `Ensure that the user ID of the pods is not 0.`

OperatorRunAsNonRoot = `Ensure that the pods are running as non root.`

OperatorAutomountTokens = `Ensure that the pods have the automount service account token disabled.`

OperatorReadOnlyFilesystem = `Ensure that the pods have the read-only root filesystem setting enabled.`

OperatorCrdVersioningRemediation = `Ensure that the Operator CRD has a valid version.`

OperatorSingleCrdOwnerRemediation = `Ensure that a CRD is owned by only one Operator`
Expand Down
47 changes: 47 additions & 0 deletions cnf-certification-test/operator/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (C) 2020-2024 Red Hat, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

/*
Package operator provides CNFCERT tests used to validate operator CNF facets.
*/

package operator

import "strings"

// CsvResult holds the results of the splitCsv function.
type CsvResult struct {
NameCsv string
Namespace string
}

// splitCsv splits the input string to extract namecsv and namespace.
func SplitCsv(csv string) CsvResult {
// Split by comma to separate components
parts := strings.Split(csv, ",")
var result CsvResult

for _, part := range parts {
part = strings.TrimSpace(part)

if strings.HasPrefix(part, "ns=") {
result.Namespace = strings.TrimPrefix(part, "ns=")
} else {
result.NameCsv = part
}
}
return result
}
69 changes: 69 additions & 0 deletions cnf-certification-test/operator/helper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (C) 2020-2024 Red Hat, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

/*
Package operator provides CNFCERT tests used to validate operator CNF facets.
*/

package operator

import "testing"

func TestSplitCsv(t *testing.T) {
tests := []struct {
input string
expectedCsv string
expectedNs string
}{
{
input: "hazelcast-platform-operator.v5.12.0, ns=tnf",
expectedCsv: "hazelcast-platform-operator.v5.12.0",
expectedNs: "tnf",
},
{
input: "example-operator.v1.0.0, ns=example-ns",
expectedCsv: "example-operator.v1.0.0",
expectedNs: "example-ns",
},
{
input: "another-operator.v2.3.1, ns=another-ns",
expectedCsv: "another-operator.v2.3.1",
expectedNs: "another-ns",
},
{
input: "no-namespace",
expectedCsv: "no-namespace",
expectedNs: "",
},
{
input: "ns=onlynamespace",
expectedCsv: "",
expectedNs: "onlynamespace",
},
}

for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
result := SplitCsv(tt.input)
if result.NameCsv != tt.expectedCsv {
t.Errorf("splitCsv(%q) got namecsv %q, want %q", tt.input, result.NameCsv, tt.expectedCsv)
}
if result.Namespace != tt.expectedNs {
t.Errorf("splitCsv(%q) got namespace %q, want %q", tt.input, result.Namespace, tt.expectedNs)
}
})
}
}
Loading
Loading