Skip to content

Commit

Permalink
Create NPEP-122 for Tenancy API update.
Browse files Browse the repository at this point in the history
Signed-off-by: Nadia Pinaeva <[email protected]>
  • Loading branch information
npinaeva committed Jul 11, 2023
1 parent 429a9e6 commit 00e5d26
Showing 1 changed file with 174 additions and 0 deletions.
174 changes: 174 additions & 0 deletions npep/npep-122.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# NPEP-122: NPEP template

* Issue: [#122](https://github.com/kubernetes-sigs/network-policy-api/issues/122)
* Status: Implementable

## TLDR

Change Tenancy implementation from SameLabels/NotSameLabels ANP peers to a separate object
that will define Tenancy considering subject and peers are related.

## Goals

- Clarify tenancy use cases
- Define what a Tenant is
- Separate ANP subject from Tenancy subject/peer

## Non-Goals

- extend Tenancy API

## Introduction

The KEP doesn’t say a whole lot about tenants…

From the Goals:

As a cluster administrator, I want to have the option to enforce in-cluster network level access controls that
facilitate network multi-tenancy and strict network level isolation between multiple teams and tenants sharing
a cluster via use of namespaces or groupings of namespaces per tenant.

Example: I would like to define two tenants in my cluster, one composed of the pods in foo-ns-1 and foo-ns-2
and the other with pods in bar-ns-1, where inter-tenant traffic is denied.

From the User Stories:

Story 4: Create and Isolate multiple tenants in a cluster

As a cluster admin, I want to build tenants in my cluster that are isolated from each other by default.
Tenancy may be modeled as 1:1, where 1 tenant is mapped to a single Namespace, or 1:n, where a single tenant
may own more than 1 Namespace.

Elsewhere:

AdminNetworkPolicy Pass rules allows an admin to delegate security posture for certain traffic to the Namespace
owners by overriding any lower precedence Allow or Deny rules. For example, intra-tenant traffic management can be
delegated to tenant admins explicitly with the use of Pass rules.

So really, the only solidly-agreed-upon use case is that either you should be able to create enforced isolation
between particular sets of namespaces.

### What we currently have

AdminNetworkPolicy has the “SameLabels” and “NotSameLabels” fields to support the use cases involving tenancy. For example:

**User story**

Traffic should be disallowed by default between user namespaces owned by different users.

**Policy**
```
kind: BaselineAdminNetworkPolicy
apiVersion: policy.networking.k8s.io/v1alpha1
metadata:
name: user-based-tenancy
spec:
subject:
namespaces:
matchExpressions:
- key: user
operator: Exists
ingress:
- action: Deny
from:
- namespaces:
notSameLabels:
- user
```

**Meaning**

In namespaces that have a “user” label, by default, deny ingress from namespaces that have a different “user” label.

There are two problems with this implementation of tenancy, relative to the user stories that it exists to support

First, it never explicitly defines what a tenant is. Although the object correctly implements the desired tenancy
policy, it doesn’t really make it obvious that that’s what it’s doing.

Second, the syntax is very general purpose / powerful. ANP has subjects and peers, which are different,
and currently Tenancy is defined on the peers side. Tenancy by itself has the same subject and peer,
at least for the existing use cases, and having separate selectors for subject and peer allows for more
configurations than needed.

## API

We suggest to define a separate API for tenancy, as in the following example:

```
kind: AdminNetworkPolicyTenancy
apiVersion: policy.networking.k8s.io/v1alpha1
metadata:
name: user-based
spec:
namespaceSelector:
matchExpression:
- key: system-namespace
operator: DoesNotExist
- key: user
operator: Exists
tenancyLabels:
- user
priority: 99
ingress:
- action: Deny
from:
- NotSameTenant
```

that will define a tenant as follows:
- first, select namespaces that will be split into tenants, and have the defined policy applied. `spec.namespaceSelector`
is used for this purpose. This also solves the problem we had for empty or unset labels: if tenancy is defined based on label `user`,
and namespaces without this label should not be affected, `key: user, operator: Exists` selector can be used.
- second, selected namespaces are split into tenants based on label values, `spec.tenancyLabels` field is used for that purpose.
Tenants with the same listed label values will form a tenant. Unset label and empty string label are also values, therefore
in case namespaces with these label values are selected, they will be split into a separate tenant.

> Example: say we define a tenancy based on `label1` and `label2`, and the following namespaces are selected by `spec.namespaceSelector`
> ```
> ns1{label1=A, label2=B, label3=C}
> ns2{label1=A, label2=B, label4=D}
> ns3{label1=_, label2=B}
> ns4{label1=_, label2=""}
> ns5{label1=_, label2=_}
> ns6{label1=A, label2=B}
> ```
> where `_` means the label is not set, and `""` means empty string value.
>
> The following tenants will be created for `tenancyLabels: [label1, label2]`
> ```
> tenant{label1=A, label2=B} = [ns1, ns2, ns6]
> tenant{label1=_, label2=B} = [ns3]
> tenant{label1=_, label2=""} = [ns4]
> tenant{label1=_, label2=_} = [ns5]
> ```

- third, define policy rules. This includes setting ports, action, and peer tenants.
For now, we only have `SameTenant` and `NotSameTenant` as a peer option.

**Note** with the new tenancy definition there is no need to have `sameLabels` and `notSameLabels`, because
these selectors will define the same tenants, but it is replaces with `SameTenant` and `NotSameTenant` for similar use cases.

Existing API allows defining tenancy for BANP, we need to decide if the tenancy actually makes sense for that priority.
BANP is overridable by the namespace owners, so the question is if there is a use case for a tenancy policy that can be
overridden?

## Conformance Details

TBD
<!---
(This section describes the names to be used for the feature or
features in conformance tests and profiles.
These should be `CamelCase` names that specify the feature as
precisely as possible, and are particularly important for
Extended features, since they may be surfaced to users.)
-->

## Alternatives

Other alternatives were mentioned https://docs.google.com/document/d/113xBe7VMK7hMYdIdB9gobp7JwVkWQLnqdMPNkamfaK8/edit,
but none of them covers all the Goals defined in this NPEP.

## References

- https://docs.google.com/document/d/113xBe7VMK7hMYdIdB9gobp7JwVkWQLnqdMPNkamfaK8

0 comments on commit 00e5d26

Please sign in to comment.