Our own, Mateusz Szostok has two sessions at KubeCon around K8s Service CatalogRead more

Mateusz Szostok, Piotr Kopczynski and Pawel Kosiec have several talks at San Diego Cloud Native MeetupRead more

API Gateway v2

Overview

CAUTION: This implementation replaces the API Gateway that is based on the Api custom resource. The services you exposed and secured using the deprecated implementation require no action, as the API Gateway Controller co-exists with the API Controller in the cluster. Expose and secure new services and functions secured with OAuth2 using the v2 implementation described in this documentation topic.

To make your service accessible outside the Kyma cluster, expose it using the Kyma API Gateway Controller, which listens for the custom resource (CR) objects that follow the apirules.gateway.kyma-project.io CustomResourceDefinition (CRD). Creating a valid CR triggers the API Gateway Controller to create an Istio Virtual Service. Optionally, you can specify the rules attribute of the CR to secure the exposed service with Oathkeeper Access Rules.

The API Gateway Controller allows you to secure the exposed services using JWT tokens issued by Kyma Dex, or OAuth2 tokens issued by the Kyma OAuth2 server. You can secure the entire service, or secure the selected endpoints. Alternatively, you can leave the service unsecured.

NOTE: Read this document to learn more about the Kyma OAuth2 server.

Architecture

This diagram illustrates the workflow that leads to exposing a service in Kyma:

service-exposure-flow

  • API Gateway Controller is a component responsible for exposing services. The API Gateway Controller is an application deployed in the kyma-system Namespace, implemented according to the Kubernetes Controller principles. The API Gateway Controller listens for newly created custom resources (CR) that follow the set apirule.gateway.kyma-project.io CustomResourceDefinition (CRD), which describes the details of exposing services in Kyma.

  • Istio Virtual Service specifies the services visible outside the cluster. The API Gateway Controller creates a Virtual Service for the hostname defined in the apirule.gateway.kyma-project.io CRD. The convention is to create a hostname using the name of the service as the subdomain, and the domain of the Kyma cluster. To learn more about the Istio Virtual Service concept, read this Istio documentation. To get the list of Virtual Services in Kyma, run:

    Click to copy
    kubectl get virtualservices.networking.istio.io --all-namespaces
  • Oathkeeper Access Rule allows operators to specify authentication requirements for a service. It is an optional resource, created only when the CR specifies the desired authentication method, the trusted token issuer, allowed methods and paths, and required scopes. To learn more about Oathkeeper Access Rules, read this document.

    To get the list of Oathkeeper Access Rules created in Kyma, run:

    Click to copy
    kubectl get rules.oathkeeper.ory.sh --all-namespaces

Details

Whitelisted domains in the API Gateway Controller

The API Gateway Controller uses a whitelist of domains for which it allows to expose services. Every time a user creates a new APIRule custom resource (CR) for a service, the API Gateway Controller checks the domain of the service specified in the CR against the whitelist. If the domain of the service matches a whitelisted entry, the API Gateway Controller creates a Virtual Service and Oathkeeper Access Rules for the service according to the details specified in the CR. If the domain is not whitelisted, the Controller creates neither a Virtual Service nor Oathkeeper Access Rules and, as a result, does not expose the service.

If the domain does not match the whitelist, the API Gateway Controller sets an appropriate validation status on the APIRule CR created for that service.

TIP: Read this document to learn more about the Api CR statuses.

By default, the only whitelisted domain is the domain of the Kyma cluster.

Blacklisted services in the API Gateway Controller

The API Gateway Controller uses a blacklist of services for which it does not create either a Virtual Service or Oathkeeper Access Rules. As a result, these services cannot be exposed. Every time a user creates a new APIRule custom resource (CR) for a service, the API Gateway Controller checks the name of the service specified in the CR against the blacklist. If the name of the service matches a blacklisted entry, the API Gateway Controller sets an appropriate validation status on the APIRule CR created for that service.

TIP: Read this document to learn more about the Api CR statuses.

The blacklist works as a security measure and prevents users from exposing vital internal services of Kubernetes, Istio, and API Server Proxy.

Custom Resource

APIRule

The apirule.gateway.kyma-project.io CustomResourceDefinition (CRD) is a detailed description of the kind of data and the format the API Gateway Controller listens for. To get the up-to-date CRD and show the output in the yaml format, run this command:

Click to copy
kubectl get crd apirule.gateway.kyma-project.io -o yaml

Sample custom resource

This is a sample custom resource (CR) that the API Gateway Controller listens for to expose a service. This example has the rules section specified which makes the API Gateway Controller create an Oathkeeper Access Rule for the service.

Click to copy
apiVersion: gateway.kyma-project.io/v1alpha1
kind: APIRule
metadata:
name: service_secured
spec:
gateway: kyma-gateway.kyma-system.svc.cluster.local
service:
name: foo-service
port: 8080
host: foo.bar
rules:
- path: /.*
methods: ["GET"]
mutators: []
accessStrategy:
- handler: oauth2_introspection
config:
required_scope: ["read"]

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

FieldMandatoryDescription
metadata.nameYESSpecifies the name of the exposed API.
spec.gatewayYESSpecifies the Istio Gateway.
spec.service.nameYESSpecifies the name of the exposed service.
spec.service.portYESSpecifies the communication port of the exposed service.
spec.service.hostYESSpecifies the service's communication address for inbound external traffic.
spec.rulesYESSpecifies the array of Oathkeeper access rules.
spec.rules.pathYESSpecifies the path of the exposed service.
spec.rules.methodsNOSpecifies the list of HTTP request methods available for spec.rules.path.
spec.rules.mutatorsNOSpecifies the array of Oathkeeper mutators.
spec.rules.accessStrategiesYESSpecifies the array of Oathkeeper authenticators.

Additional information

When you fetch an existing APIRule CR, the system adds the status section which describes the status of the Virtual Service and the Oathkeeper Access Rule created for this CR. This table lists the fields of the status section.

FieldDescription
status.apiRuleStatusStatus code describing the APIRule CR.
status.virtualServiceStatus.codeStatus code describing the Virtual Service.
status.virtualService.descCurrent state of the Virtual Service.
status.accessRuleStatus.codeStatus code describing the Oathkeeper Rule.
status.accessRuleStatus.descCurrent state of the Oathkeeper Rule.

Status codes

These are the status codes used to describe the Virtual Services and Oathkeeper Access Rules:

CodeDescription
OKResource created.
SKIPPEDSkipped creating a resource.
ERRORResource not created.

Tutorials

Expose and secure a service

This tutorial shows how to expose and secure services or lambda functions using the API Gateway Controller. The controller reacts to an instance of the APIRule custom resource (CR) and creates an Istio Virtual Service and Oathkeeper Access Rules according to the details specified in the CR. To interact with the secured services, the tutorial uses an OAuth2 client registered through the Hydra Maester controller.

The tutorial comes with a sample HttpBin service deployment and a sample lambda function.

Register an OAuth2 client and get tokens

  1. Export these values as environment variables:
  • The name of your client and the Secret which stores the client credentials:

    Click to copy
    export CLIENT_NAME={YOUR_CLIENT_NAME}
  • The Namespace in which you want to create the client and the Secret that stores its credentials:

    Click to copy
    export CLIENT_NAMESPACE={YOUR_CLIENT_NAMESPACE}
  • The domain of your cluster:

    Click to copy
    export DOMAIN={CLUSTER_DOMAIN}
  1. Create an OAuth2 client with read and write scopes. Run:

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: hydra.ory.sh/v1alpha1
    kind: OAuth2Client
    metadata:
    name: $CLIENT_NAME
    namespace: $CLIENT_NAMESPACE
    spec:
    grantTypes:
    - "client_credentials"
    scope: "read write"
    secretName: $CLIENT_NAME
    EOF
  2. Export the credentials of the created client as environment variables. Run:

    Click to copy
    export CLIENT_ID="$(kubectl get secret -n $CLIENT_NAMESPACE $CLIENT_NAME -o jsonpath='{.data.client_id}' | base64 --decode)"
    export CLIENT_SECRET="$(kubectl get secret -n $CLIENT_NAMESPACE $CLIENT_NAME -o jsonpath='{.data.client_secret}' | base64 --decode)"
  3. Encode your client credentials and export them as an environment variable:

    Click to copy
    export ENCODED_CREDENTIALS=$(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)
  4. Get tokens to interact with secured resources using client credentials flow:

  • Token with "read" scope
  • Token with "write" scope

Deploy, expose, and secure the sample resources

Follow the instructions in the tabs to deploy an instance of the HttpBin service or a sample lambda function, expose them, and secure them with Oauth2 scopes.

  • HttpBin - secure endpoints of a service
  • Secure a lambda function

Access the secured resources

Follow the instructions in the tabs to call the secured service or lambda functions using the tokens issued for the client you registered.

  • Call secured endpoints of a service
  • Call the secured lambda function