Security

Overview

The security model in Kyma uses the Service Mesh component to enforce authorization through Kubernetes Role Based Authentication (RBAC) in the cluster. The identity federation is managed through Dex, which is an open-source, OpenID Connect identity provider.

Dex implements a system of connectors that allow you to delegate authentication to external OpenID Connect and SAML2-compliant Identity Providers and use their user stores. Read the Add an Identity Provider to Dex document to learn how to enable authentication with an external Identity Provider by using a Dex connector.

Out of the box, Kyma comes with its own static user store used by Dex to authenticate users. This solution is designed for use with local Kyma deployments as it allows to easily create predefined users' credentials by creating Secret objects with a custom dex-user-config label. Read the Manage static users in Dex document to learn how to manage users in the static store used by Dex.

Kyma uses a group-based approach to managing authorizations. To give users that belong to a group access to resources in Kyma, you must create:

  • Role and RoleBinding - for resources in a given Namespace or Environment.
  • ClusterRole and ClusterRoleBinding - for resources available in the entire cluster.

The RoleBinding or ClusterRoleBinding must have a group specified as their subject. See this document to learn how to manage Roles and RoleBindings.

NOTE: You cannot define groups for the static user store. Instead, bind the user directly to a role or a cluster role by setting the user as the subject of a RoleBinding or ClusterRoleBinding.

The system creates two default roles in every Environment:

  • kyma-admin-role - this role gives the user full access to the Environment.
  • kyma-reader-role - this role gives the user the right to read all resources in the given Environment.

For more details about Environments, read the Environments document in the Kyma topic.

NOTE: The Global permissions section in the Administration view of the Kyma Console UI allows you to manage user-group bindings.

Architecture

The following diagram illustrates the authorization and authentication flow in Kyma. The representation assumes the Kyma Console UI as the user's point of entry.

authorization-authentication-flow

  1. The user opens the Kyma Console UI. If the Console application doesn't find a JWT token in the browser session storage, it redirects the user's browser to the Open ID Connect (OIDC) provider, Dex.
  2. Dex lists all defined Identity Provider connectors to the user. The user selects the Identity Provider to authenticate with. After successful authentication, the browser is redirected back to the OIDC provider which issues a JWT token to the user. After obtaining the token, the browser is redirected back to the Console UI. The Console UI stores the token in the Session Storage and uses it for all subsequent requests.
  3. The Authorization Proxy validates the JWT token passed in the Authorization Bearer request header. It extracts the user and groups details, the requested resource path, and the request method from the token. The Proxy uses this data to build an attributes record, which it sends to the Kubernetes Authorization API.
  4. The Proxy sends the attributes record to the Kubernetes Authorization API. If the authorization fails, the flow ends with a 403 code response.
  5. If the authorization succeeds, the request is forwarded to the Kubernetes API Server.

NOTE: The Authorization Proxy can verify JWT tokens issued by Dex because Dex is registered as a trusted issuer through OIDC parameters during the Kyma installation.

Kubeconfig generator

The Kubeconfig generator is a proprietary tool that generates a kubeconfig file which allows the user to access the Kyma cluster through the Command Line Interface (CLI), and to manage the connected cluster within the permission boundaries of the user.

The Kubeconfig generator rewrites the ID token issued for the user by Dex into the generated kubeconfig file. The time to live (TTL) of the ID token is 24 hours, which effectively means that the TTL of the generated kubeconfig file is 24 hours as well.

The generator is a publicly exposed service. You can access it directly under the https://configurations-generator.{YOUR_CLUSTER_DOMAIN} address. The service requires a valid ID token issued by Dex to return a code 200 result.

Get the kubeconfig file and configure the CLI

Follow these steps to get the kubeconfig file and configure the CLI to connect to the cluster:

  1. Access the Console UI of your Kyma cluster.
  2. Click Administration.
  3. Click the Download config button to download the kubeconfig file to a selected location on your machine.
  4. Open a terminal window.
  5. Export the KUBECONFIG environment variable to point to the downloaded kubeconfig. Run this command:

    export KUBECONFIG={path_to_downloaded_kubeconfig}
    

    NOTE: Drag and drop the kubeconfig file in the terminal to easily add the path of the file to the export KUBECONFIG command you run.

  6. Run kubectl cluster-info to check if the CLI is connected to the correct cluster.

NOTE: Exporting the KUBECONFIG environment variable works only in the context of the given terminal window. If you close the window in which you exported the variable, or if you switch to a new terminal window, you must export the environment variable again to connect the CLI to the desired cluster.

Alternatively, get the kubeconfig file by sending a GET request with a valid ID token issued for the user to the /kube-config endpoint of the https://configurations-generator.{YOUR_CLUSTER_DOMAIN} service. For example:

curl GET https://configurations-generator.{YOUR_CLUSTER_DOMAIN}/kube-config -H "Authorization: Bearer {VALID_ID_TOKEN}"

Add an Identity Provider to Dex

Add external, OpenID Connect compliant authentication providers to Kyma using Dex connectors. Follow the instructions below to add a GitHub connector and use it to authenticate users in Kyma.

NOTE: Groups in the Github are represented as teams. See this document to learn how to manage teams in Github.

Prerequisites

To add a GitHub connector to Dex, register a new OAuth application in GitHub. Set the authorization callback URL to https://dex.kyma.local/callback. After you complete the registration, request for an organization approval.

NOTE: To authenticate in Kyma using GitHub, the user must be a member of a GitHub organization that has at least one team.

Configure Dex

Register the GitHub Dex connector by editing the dex-config-map.yaml ConfigMap file located in the kyma/resources/dex/templates directory. Follow this template:

    connectors:
    - type: github
      id: github
      name: GitHub
      config:
        clientID: {GITHUB_CLIENT_ID}
        clientSecret: {GITHUB_CLIENT_SECRET}
        redirectURI: https://dex.kyma.local/callback
        orgs:
          - name: {GITHUB_ORGANIZATION}

This table explains the placeholders used in the template:

Placeholder Description
GITHUB_CLIENT_ID Specifies the application's client ID.
GITHUB_CLIENT_SECRET Specifies the application's client Secret.
GITHUB_ORGANIZATION Specifies the name of the GitHub organization.

Configure authorization rules

To bind Github groups to the default roles added to every Kyma Environment, add the bindings section to this file. Follow this template:

bindings:
  kymaAdmin:
    groups:
    - "{GITHUB_ORGANIZATION}:{GITHUB_TEAM_A}"
  kymaView:
    groups:
    - "{GITHUB_ORGANIZATION}:{GITHUB_TEAM_B}"

This table explains the placeholders used in the template:

Placeholder Description
GITHUB_ORGANIZATION Specifies the name of the GitHub organization.
GITHUB_TEAM_A Specifies the name of GitHub team to bind to the kyma-admin-role role.
GITHUB_TEAM_B Specifies the name of GitHub team to bind to the kyma-reader-role role.

Manage static users in Dex

To create a static user in Dex, create a Secret with the dex-user-config label set to true. Run:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name:  {SECRET_NAME}
  namespace: {SECRET_NAMESPACE}
  labels:
    "dex-user-config": "true"
data:
  email: {BASE64_USER_EMAIL}
  username: {BASE64_USERNAME}
  password: {BASE64_USER_PASSWORD}  
type: Opaque
EOF

The following table describes the fields that are mandatory to create a static user. If any of these fields is not included, the user is not created.

Field Description
data.email Base64-encoded email address used to sign-in to the console UI. Must be unique.
data.username Base64-encoded username displayed in the console UI.
data.password Base64-encoded user password. There are no specific requirements regarding password strength, but it is recommended to use a password that is at least 8-characters-long.

Create the Secrets in the cluster before Dex is installed. The Dex init-container with the tool that configures Dex generates user configuration data basing on properly labelled Secrets, and adds the data to the ConfigMap.

If you want to add a new static user after Dex is installed, restart the Dex Pod. This creates a new Pod with an updated ConfigMap.

Group

The groups.authentication.kyma-project.io Custom Resource Definition (CRD) is a detailed description of the kind of data and the format that represents user groups available in the ID provider in the Kyma cluster. To get the up-to-date CRD and show the output in the yaml format, run this command:

kubectl get crd groups.authentication.kyma-project.io -o yaml

Sample Custom Resource

This is a sample CR that represents an user group available in the ID provider in the Kyma cluster.

apiVersion: authentication.kyma-project.io/v1alpha1
kind: Group
metadata:
    name: "sample-group"
spec:    
    name: "admins"
    idpName: "github"
    description: "'admins' represents the group of users with administrative privileges in the organization."

This table analyses the elements of the sample CR and the information it contains:

Field Mandatory Description
metadata.name YES Specifies the name of the CR.
spec.name YES Specifies the name of the group.
spec.idpName YES Specifies the name of the ID provider in which the group exists.
spec.description NO Description of the group available in the ID provider.

Identity Provider Presets

The idppresets.authentication.kyma-project.io Custom Resource Definition (CRD) is a detailed description of the kind of data and the format that represents presets of the Identity Provider configuration used to secure API through the Console UI. Presets are a convenient way to configure the authentication section in the API Custom Resource.

To get the up-to-date CRD and show the output in the yaml format, run this command:

kubectl get crd idppresets.authentication.kyma-project.io -o yaml

Sample Custom Resource

This is a sample CR used to create an IDPPreset:

apiVersion: authentication.kyma-project.io/v1alpha1
kind: IDPPreset
metadata:
    name: "sample-idppreset"
spec:
    issuer: https://example.com
    jwksUri: https://example.com/keys

Custom resource parameters

This table lists all the possible parameters of a given resource together with their descriptions:

Parameter Mandatory Description
metadata.name YES Specifies the name of the CR.
spec.issuer YES Specifies the issuer of the JWT tokens used to access the services.
spec.jwksUri YES Specifies the URL of the OpenID Provider’s public key set to validate the signature of the JWT token.

Usage in the UI

issuer and jwksUri are some of the API CR specification fields. In most cases, these values are reused many times. IDPPresets usage is a solution to reuse them in a convenient way. It allows you to choose a proper preset from the dropdown menu instead of entering them manually every time you expose a secured API. Apart from consuming the IDPPresets, you can also manage them in the Console UI. To create and delete IDPPresets, go to the Administration tab and then to IDP Presets.

These components use this CR:

Name Description
IDP Preset Generates Go client which allows components and tests to create, delete, or get IDP Preset resources.
UI API Layer Enables the IDP Preset management with GraphQL API.

Update TLS certificate

The TLS certificate is a vital security element. This document describes how to update the TLS certificate in Kyma.

NOTE: This procedure can interrupt the communication between your cluster and the outside world for a limited period of time.

Prerequisites

  • New TLS certificates
  • Kyma administrator access

Steps

  1. Export the new TLS certificate and key as environment variables. Run:

     export KYMA_TLS_CERT=$(cat {NEW_CERT_PATH})
     export KYMA_TLS_KEY=$(cat {NEW_KEY_PATH})
    
  2. Update the Ingress Gateway certificate. Run:

     cat <<EOF | kubectl apply -f -
     apiVersion: v1
     kind: Secret
     type: kubernetes.io/tls
     metadata:
         name: istio-ingressgateway-certs
         namespace: istio-system
     data:
         tls.crt: $(echo "$KYMA_TLS_CERT" | base64)
         tls.key: $(echo "$KYMA_TLS_KEY" | base64)
     EOF
    
  3. Update the kyma-system Namespace certificate:

     cat <<EOF | kubectl apply -f -
     apiVersion: v1
     kind: Secret
     type: Opaque
     metadata:
         name: ingress-tls-cert
         namespace: kyma-system
     data:
         tls.crt: $(echo "$KYMA_TLS_CERT" | base64)
     EOF
    
  4. Update the kyma-integration Namespace certificate:

     cat <<EOF | kubectl apply -f -
     apiVersion: v1
     kind: Secret
     type: Opaque
     metadata:
         name: ingress-tls-cert
         namespace: kyma-integration
     data:
         tls.crt: $(echo "$KYMA_TLS_CERT" | base64)
     EOF
    
  5. Restart the Ingress Gateway Pod to apply the new certificate:

     kubectl delete pod -l app=istio-ingressgateway -n istio-system
    
  6. Restart the Pods in the kyma-system Namespace to apply the new certificate:

     kubectl delete pod -l tlsSecret=ingress-tls-cert -n kyma-system
    
  7. Restart the Pods in the kyma-integration Namespace to apply the new certificate:

     kubectl delete pod -l tlsSecret=ingress-tls-cert -n kyma-integration