CloudNatix logo

User Guide

Secure Session and RBAC Management

Overview

This document describes CloudNatix Secure Session and RBAC (Role Based Access Control) Management.

Secure Session Management

Secure session management is a mechanism for providing secure access to users’ K8s clusters. The users can interactively access K8s clusters with existing tools such as kubectl or they can use CloudNatix Multi-Cluster GUI (e.g., application of workload rightsizing recommendations).

The secure session is established via CloudNatix Global Controller. There is no need to open any incoming ports. Only outgoing HTTPS requests to cloudnatix.com are required.

Using a Secure Session with kubectl

To use a secure session with kubectl, type the following command to generate a kubeconfig.

cnatix clusters export-config --cluster <cluster-name>

The generated kubeconfig has <cluster-uuid>.connect.cloudnatix.com as a K8s API server address so that all requests are sent to CloudNatix Global Controller (and forwarded to a target k8s cluster).

The kubeconfig uses OpenID Connect (OIDC) as an authenticator. ID tokens are issued by CloudNatix (https://login.cloudnatix.com/) and validated by CloudNatix Global Controller as well as Cluster Controller.

Here is an example kubeconfig generated.

apiVersion: v1
clusters:
  - cluster:
      server: https://46dbb93d-e4b1-4a90-9479-84a0fbba0d5f.connect.cloudnatix.com:443
    name: my-cluster.k8s.local
contexts:
  - context:
      cluster: my-cluster.k8s.local
      user: my-cluster.k8s.local
    name: my-cluster.k8s.local
current-context: my-cluster.k8s.local
kind: Config
preferences: {}
users:
  - name: my-cluster.k8s.local
    user:
      auth-provider:
        config:
          client-id: 0oa17m60zdJLsJUG14x7
          id-token: ...
          idp-issuer-url: https://login.cloudnatix.com/oauth2/aus202ft6fhz9alff4x7
          refresh-token: ...
        name: oidc

System Architecture

CloudNatix Global Controller and Cluster Controller consist of multiple components. Connect Proxy in Global Controller and Connect Agent in Cluster Controller are responsible for managing secure sessions.

The following diagram illustrates the system architecture.

img

Connect Agent in Cluster Controller runs in users’ K8s clusters. It establishes a TCP connection with Connect Proxy, and it initiates a TLS handshake to establish a secure session.

Once the secure session is established, Connect Proxy starts forwarding requests coming from clients (e.g., kubectl) to Connect Agent running in the target cluster. Connect Agent then forwards requests to K8s API server (https://kubernetes.default.svc.cluster.local).

Authentication and Authorization

Authentication and authorization are performed at multiple layers in the above request flow.

  • Connect Proxy validates access tokens in the Authorization header of HTTPS requests coming from clients. Connect Proxy accepts a request only if its access token is successfully validated and it has access permission to the target K8s cluster (with the “tenant_id” claim of the access token).
  • Connect Agent validates access tokens in requests coming from Connect Proxy via secure session. It accepts a request only if its access token is successfully validated.
  • K8s API server validates access tokens in requests coming from Connect Agent. Connect Agent uses its service account to generate access tokens.

Connect Agent does not use original access tokens in requests initiated by clients as K8s API server does not accept access tokens issued by CloudNatix. Instead we use a service account of Connect Agent for authentication/authorization and use impersonation to map requests to users who made original requests.

RBAC Management

The CloudNatix RBAC (Role Based Access Control) mechanism enables users to configure access permission in K8s clusters using CloudNatix IAM.

The configured RBAC is applied when users access K8s API server via secure sessions established by Connect Proxy and Connect Agent. IAM Concepts and Semantics

The major concepts of CloudNatix IAM are following:

  • User is a login account associated with a CloudNatix email address.
  • Org is an entity that represents a business unit or a team. It can take hierarchical structure.
  • Role controls the access privilege.The value can be viewer, user, or admin.
  • RoleBinding maps an org to a role. Each user is associated with one or more than one role binding.
  • Namespace is a federated K8s namespace. Each namespace is associated with an org.

Suppose that we have the following org hierarchy:

img

When a namespace is created and associated with org "Team 1", the namespace is accessible from users whose role binding includes the following orgs:

  • Team 1
  • Prod
  • Root org

The actual permission of the user against the namespace depends on a role.

  • The viewer role is read-only privilege. The user has read-only access to see most objects in the namespace.
  • The user is read-write privilege. The user has read/write access to most objects in a namespace.This role does not allow viewing or modifying roles or role bindings
  • The admin is an admin privilege. It allows read/write access to most resources in a namespace, including the ability to create roles and role bindings within the namespace.

The namespace is created in all K8s clusters owned by "Team1", "Prod", or "Root org".

Mapping from CloudNatix RBAC to K8s RBAC

CloudNatix creates K8s RoleBindings to enforce the above role bindings in a K8s cluster. The RoleBindings are applied when a user accesses a K8s cluster with a kubeconfig generated by cnatix clusters export-config.

As described previously, Connect Agent uses the K8s impersonation mechanism to map each request to a user who originally issues the request. Suppose that a user sends a request to K8s API server and the user has the following role binding:

  • Team 1: Viewer

Connect Agent retrieves the role binding information from an access token it receives from Connect Proxy. Then Connect Agent sets the Impersonate-Group header to <UUID of Team1>:view. When K8s API server receives the request, it applies a K8s RoleBinding created by Cluster Controller and gives the viewer access to the namespaces where Team 1 is allowed to access.

Example K8s RoleBindings

Suppose that we have the following orgs and the namespace:

$ cnatix iam orgs list

+--------------------------------------+--------+-------------+-------------+
|                 UUID                 | NAME   | DESCRIPTION | PARENT ORG  |
+--------------------------------------+--------+-------------+-------------+
| c4943aca-7991-4346-806c-215b4cc73886 | Root   | Root Org    |             |
| bf304557-f975-43d3-b885-97d9bc4a92e3 | Prod   | Production  | Root        |
| 16af77ad-d146-4bd9-87dc-92f71c7e6778 | Team 1 | Team 1      | Prod        |
| fd2b96ba-9639-49d2-acb8-ac9d8f010d7c | Team 2 | Team 2      | Prod        |
+--------------------------------------+--------+-------------+-------------+

$ cnatix iam namespaces list
+--------------------------------------+--------------+--------+--------+
|                 UUID                 |    NAME      | ORG    | LABELS |
+--------------------------------------+--------------+--------+--------+

| 37f9527f-3558-4320-a851-bf60f03d4916 | my-namespace | Team 1 |        |
+--------------------------------------+--------------+--------+--------+

The my-namespace namespace has the three RoleBindings created by CloudNatix:

$ kubectl get rolebindings -n my-namespace

NAME                 ROLE                AGE
my-namespace:admin   ClusterRole/admin   13d
my-namespace:edit    ClusterRole/edit    13d
my-namespace:view    ClusterRole/view    13d

The RoleBindings allow a user who has a role binding to Team 1 and its ancestor orgs to access the namespace (with an associated role). The Subjects section of the RoleBindings has a list of <orgUUID>:<role> where <org UUID> is the UUID of Team 1 or its ancestor org.

$ kubectl get rolebindings -n my-namespace my-namespace:admin -o yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    cloudnatix.com/managed-by: clusteragent
  name: my-namespace:admin
  namespace: my-namespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: 16af77ad-d146-4bd9-87dc-92f71c7e6778:admin  # “Root” org
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: bf304557-f975-43d3-b885-97d9bc4a92e3:admin  # “Prod” org
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: c4943aca-7991-4346-806c-215b4cc73886:admin  # “Team 1” org
Previous
Access Control with Orgs and Roles
Next
Checking Kubernetes Deprecated APIs