Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Define access control #16

Merged
merged 5 commits into from
May 2, 2019
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
41 changes: 24 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
## Service Mesh Interface (code name Smeagol)
## Service Mesh Interface

The Service Mesh Interface (SMI) is a specification for service meshes that run
on Kubernetes. It defines a common standard that can be implemented by a variety
of providers. This allows for both standardization for end-users and innovation
by providers of Service Mesh Technology. It enables flexibility and
interoperability.

This specification consists of multiple APIs:

* [Traffic Specs](traffic-specs.md) - define how traffic looks on a per-protocol
basis. These resources work in concert with access control and other types of
policy to manage traffic at a protocol level.
* [Traffic Access Control](traffic-policy.md) - configure access to specific
pods and routes based on the identity of a client for locking down
applications to only allowed users and services.
* [Traffic Split](traffic-split.md) - incrementally direct percentages of
traffic between various services to assist in building out canary rollouts.
* [Traffic Metrics](traffic-metrics.md) - expose common traffic metrics for use
by tools such as dashboards and autoscalers.

See the individual documents for the details. Each document outlines:

* Specification
* Possible use cases
* Example implementations
* Tradeoffs

### Technical Overview

The SMI is specified as a collection of Kubernetes Custom Resource Definitions
(CRD) and Extension API Servers. These APIs (details below) can be installed
onto any Kubernetes cluster and manipulated using standard tools. The APIs
require an SMI provider to do something.
(CRD) and Extension API Servers. These APIs can be installed onto any Kubernetes
cluster and manipulated using standard tools. The APIs require an SMI provider
to do something.

To activate these APIs an SMI provider is run in the Kubernetes cluster. For the
resources that enable configuration, the SMI provider reflects back on their
Expand All @@ -38,16 +58,3 @@ useful subset. If SMI providers want to add provider specific extensions and
APIs beyond the SMI spec, they are welcome to do so We expect that, over time,
as more functionality becomes commonly accepted as part of what it means to be a
Service Mesh, those definitions will migrate into the SMI specification.

### Specification

The SMI specification outlines three basic resource types:

* MutualTLS - a resource for managing and configuring encryption between services
* TrafficSplit - a resource for splitting traffic between different backends.
The primary use case is executing canary rollouts of new applications
versions.
* TrafficMetrics - a resource that normalizes the metrics surfaced by
implementations.

The details of the APIs can be founded in [Specification.md](specification.md)
129 changes: 129 additions & 0 deletions traffic-access-control.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
## Traffic Access Control

This resource allows users to define policies that control access to resources
for clients.

## Specification

### TrafficRole

```yaml
kind: TrafficRole
apiVersion: v1beta1
metadata:
name: path-specific
namespace: default
resource:
name: foo
kind: Deployment
port: 8080
rules:
- kind: HTTPRoutes
name: the-routes
specs:
- metrics
```

This example associates a set of routes with a set of pods. It will match the
routes arriving at these pods on the specified port (8080). While `the-routes`
definition contains multiple elements, only a single element is referenced in
this role. This example could be used in conjunction with a TrafficRoleBinding
to provide Prometheus the access to scrape metrics on the `foo` deployment.

### TrafficRoleBinding

```yaml
kind: TrafficRoleBinding
apiVersion: v1beta1
metadata:
name: account-specific
namespace: default
subjects:
- kind: ServiceAccount
name: bar
namespace: default
roleRef:
kind: TrafficRole
name: path-specific
```

This example grants the ability to access the routes in `path-specific` to any
client providing the identity `bar` based on a ServiceAccount.

As access control is additive, it is important to provide definitions that allow
non-authenticated traffic access. Imagine rolling a service mesh out
incrementally. It is important to not immediately block any traffic that is not
from an authenticated client. In this world, groups are important as a source of
identity.

```yaml
kind: TrafficRoleBinding
apiVersion: v1beta1
metadata:
name: account-specific
namespace: default
subjects:
- kind: Group
name: system:unauthenticated
roleRef:
kind: TrafficRole
name: path-specific
```

This example allows any unauthenticated client access to the rules defined in
`path-specific`.

Note: this specification defines that access control is *always* enforced on the
*server* side of a connection. It is up to implementations to decide whether
they would also like to enforce access control on the *client* side
of the connection as well.

## Use Cases

## Admission Control

TODO ...

## RBAC

TODO ...

## Example Implementation

## Tradeoffs

* Additive policy - policy that denies instead of only allows is valuable
sometimes. Unfortunately, it makes it extremely difficult to reason about what
is allowed or denied in a configuration.

* It would be possible to support `kind: Namespace`. This ends up having some
special casing as to references and doesn't cover all cases. Instead, there
has been a conscious decision to allow `*` kinds instead of supporting
non-namespaced resources (for example, namespaces). This solves the same user
goal and is slightly more flexible.

* Namespaces are explicitly left out of the resource reference (`namespace:
foobar`). This is because the reference could be used to point to a resource
in a different namespace that a user might not have permissions to access or
define.It also ends up being somewhat redundant as `namespace: foobar` is
defined by the location of the resource itself.

## Out of scope

* Egress policy - while this specification allows for the possibility of
defining egress configuration, this functionality is currently out of scope.

* Non-HTTP traffic - this specification will need to be expanded to support
traffic such as Kafka or MySQL.

## Open Questions

* Why include namespace in the reference *and* role? Is there any reason a user
would create a role in one namespace that references another?

* Namespaces should *not* be possible to define on `TrafficRole` for resource
references but are required for `ClusterTrafficRole`. Is it okay only allow
this key in `ClusterTrafficRole` references?

* I'm not sure `kind: pod` and `name: *` is the best solution for generic allow
policies. Is there a better way to do it? `kind: *` feels wrong as well.
Loading