-
Notifications
You must be signed in to change notification settings - Fork 175
[MTB] added block other tenant resources benchmark #1318
Changes from 2 commits
be6e2fb
a606f7a
e1dbabe
b6b4129
05f8796
ca7681d
bb174d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Block access to other tenant resources <small>[MTB-PL1-CC-TI-2] </small> | ||
|
||
**Profile Applicability:** | ||
|
||
2 | ||
|
||
**Type:** | ||
|
||
Configuration | ||
|
||
**Category:** | ||
|
||
Tenant Protection | ||
|
||
**Description:** | ||
|
||
Access controls should be configured so that a tenant cannot view, edit, create, or delete namespaced resources belonging to another tenant. | ||
|
||
**Rationale:** | ||
|
||
Tenant resources should be isolated from other tenants. | ||
|
||
|
||
**Audit:** | ||
|
||
Run the following commands to retrieve the list of namespaced resources available in Tenant B | ||
```bash | ||
kubectl --kubeconfig tenant-b api-resources --namespaced=true | ||
``` | ||
For each namespaced resource, and each verb (get, list, create, update, patch, watch, delete, and deletecollection) issue the following command | ||
```bash | ||
kubectl --kubeconfig tenant-a -n b1 <verb> <resource> | ||
``` | ||
Each command must return 'no' | ||
|
||
|
||
**namespaceRequired:** | ||
|
||
2 | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,94 @@ | ||||||||||||||||||||||
package blockothertenantresources | ||||||||||||||||||||||
|
||||||||||||||||||||||
import ( | ||||||||||||||||||||||
"fmt" | ||||||||||||||||||||||
"k8s.io/apimachinery/pkg/runtime/schema" | ||||||||||||||||||||||
"sigs.k8s.io/multi-tenancy/benchmarks/kubectl-mtb/test/utils" | ||||||||||||||||||||||
"sigs.k8s.io/multi-tenancy/benchmarks/kubectl-mtb/types" | ||||||||||||||||||||||
|
||||||||||||||||||||||
"sigs.k8s.io/multi-tenancy/benchmarks/kubectl-mtb/bundle/box" | ||||||||||||||||||||||
"sigs.k8s.io/multi-tenancy/benchmarks/kubectl-mtb/pkg/benchmark" | ||||||||||||||||||||||
"sigs.k8s.io/multi-tenancy/benchmarks/kubectl-mtb/test" | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
var verbs = []string{"get", "update"} | ||||||||||||||||||||||
|
||||||||||||||||||||||
var b = &benchmark.Benchmark{ | ||||||||||||||||||||||
|
||||||||||||||||||||||
PreRun: func(options types.RunOptions) error { | ||||||||||||||||||||||
|
||||||||||||||||||||||
return nil | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
|
||||||||||||||||||||||
Run: func(options types.RunOptions) error { | ||||||||||||||||||||||
var primaryNamespaceResources []utils.GroupResource | ||||||||||||||||||||||
|
||||||||||||||||||||||
lists, err := options.KClient.Discovery().ServerPreferredResources() | ||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||
options.Logger.Debug(err.Error()) | ||||||||||||||||||||||
return err | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
for _, list := range lists { | ||||||||||||||||||||||
if len(list.APIResources) == 0 { | ||||||||||||||||||||||
continue | ||||||||||||||||||||||
} | ||||||||||||||||||||||
gv, err := schema.ParseGroupVersion(list.GroupVersion) | ||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||
continue | ||||||||||||||||||||||
} | ||||||||||||||||||||||
for _, resource := range list.APIResources { | ||||||||||||||||||||||
if len(resource.Verbs) == 0 { | ||||||||||||||||||||||
continue | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
if resource.Namespaced { | ||||||||||||||||||||||
continue | ||||||||||||||||||||||
} | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please refactor as suggested. |
||||||||||||||||||||||
primaryNamespaceResources = append(primaryNamespaceResources, utils.GroupResource{ | ||||||||||||||||||||||
APIGroup: gv.Group, | ||||||||||||||||||||||
APIResource: resource, | ||||||||||||||||||||||
}) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
for _, resource := range primaryNamespaceResources { | ||||||||||||||||||||||
for _, verb := range verbs { | ||||||||||||||||||||||
access, msg, err := utils.RunAccessCheck(options.OClient, options.TenantNamespace, resource, verb) | ||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||
options.Logger.Debug(err.Error()) | ||||||||||||||||||||||
return err | ||||||||||||||||||||||
} | ||||||||||||||||||||||
if access { | ||||||||||||||||||||||
return fmt.Errorf(msg) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
for _, resource := range primaryNamespaceResources { | ||||||||||||||||||||||
for _, verb := range verbs { | ||||||||||||||||||||||
access, msg, err := utils.RunAccessCheck(options.TClient, options.OtherNamespace, resource, verb) | ||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||
options.Logger.Debug(err.Error()) | ||||||||||||||||||||||
return err | ||||||||||||||||||||||
} | ||||||||||||||||||||||
if access { | ||||||||||||||||||||||
return fmt.Errorf(msg) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these two for loops can be clubbed into a single for loop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this can be made a separate function, right now this particular piece of duplicated at three places There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please refactor as suggested. |
||||||||||||||||||||||
|
||||||||||||||||||||||
return nil | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
func init() { | ||||||||||||||||||||||
// Get the []byte representation of a file, or an error if it doesn't exist: | ||||||||||||||||||||||
err := b.ReadConfig(box.Get("block_other_tenant_resources/config.yaml")) | ||||||||||||||||||||||
if err != nil { | ||||||||||||||||||||||
fmt.Println(err) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
test.BenchmarkSuite.Add(b); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package blockothertenantresources |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
id: MTB-PL1-CC-TI-2 | ||
title: Block access to other tenant resources | ||
benchmarkType: Configuration | ||
category: Tenant Protection | ||
description: Access controls should be configured so that a tenant cannot view, edit, create, or delete namespaced resources belonging to another tenant. | ||
remediation: | ||
profileLevel: 2 | ||
namespaceRequired: 2 | ||
rationale: Tenant resources should be isolated from other tenants. | ||
Audit: | | ||
Run the following commands to retrieve the list of namespaced resources available in Tenant B | ||
```bash | ||
kubectl --kubeconfig tenant-b api-resources --namespaced=true | ||
``` | ||
For each namespaced resource, and each verb (get, list, create, update, patch, watch, delete, and deletecollection) issue the following command | ||
```bash | ||
kubectl --kubeconfig tenant-a -n b1 <verb> <resource> | ||
``` | ||
Each command must return 'no' |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,5 +23,5 @@ Set `imagePullPolicy` to `always` for the container. | |
|
||
**namespaceRequired:** | ||
|
||
2 | ||
1 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,5 +14,6 @@ type RunOptions struct { | |
Label string | ||
KClient *kubernetes.Clientset | ||
TClient *kubernetes.Clientset | ||
OClient *kubernetes.Clientset | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we be a little bit more descriptive while naming different clients? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, agreed. What would be good names here? Something like:
|
||
Logger *zap.SugaredLogger | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can add the arguments in a list itself like
-n test test2 --as bob-k8s-access bob2-k8s-access
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great idea! @phoenixking25 what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the Cobra CLI package allows this:
spf13/cobra#661