Application Connector

Overview

The Application Connector (AC) is a proprietary Kyma implementation that allows you to connect with external solutions. No matter if you want to integrate an on-premise or a cloud system, the integration process does not change, which allows to avoid any configuration or network-related problems.

The external solution you connect to Kyma using the AC is represented as an Application. There is always a one-to-one relationship between a connected solution and an Application, which helps to ensure the highest level of security and separation. This means that you must create five separate Applications in your cluster to connect five different external solutions and use their APIs and event catalogs in Kyma.

The Application Connector:

  • Manages lifecycles of Applications.
  • Establishes a secure connection and generates the client certificate used by the connected external solution.
  • Registers APIs and event catalogs of the connected external solution.
  • Delivers events from the connected external solution to the Kyma Event Bus.
  • Proxies calls sent from Kyma to external APIs registered by the connected external solution.
  • Allows to map an Application to a Kyma Namespace and use its registered APIs and event catalogs in the context of that Namespace.
  • Integrates the registered APIs and event catalogs with the Kyma Service Catalog.

All of the AC components scale independently, which allows to adjust it to fit the needs of the implementation built using Kyma.

Supported APIs

The Application Connector allows you to register secured REST APIs exposed by the connected external solution. The Application Connector supports a variety of authentication methods to ensure smooth integration with a wide range of APIs.

You can register an API secured with one of the following authentication methods:

  • Basic Authentication
  • OAuth
  • Client Certificates

NOTE: You can register non-secured APIs for testing purposes, however, it is not recommended in the production environment.

In addition to authentication methods, the Application Connector supports Cross-Site Request Forgery Tokens.

You can register any API that adheres to the REST principles and is available over the HTTP protocol. The Application Connector also allows you to register APIs implemented with the OData technology.

You can provide specifications that document your APIs. The Application Connector supports AsyncAPI, OpenAPI, and OData specification formats.

TIP: Follow this link to read about the CMS AsyncAPI Service used in Kyma to process AsyncAPI specifications.

Architecture

Application Connector components

Architecture Diagram

Istio Ingress Gateway

The Istio Ingress Gateway exposes the Application Connector and other Kyma components. The DNS name of the Ingress is cluster-dependent and follows the gateway.{cluster-dns} format. For example, gateway.servicemanager.cluster.kyma.cx. Istio Ingress Gateway secures the endpoints with certificate validation. Each call must include a valid client certificate. You can access every exposed Application using the assigned path. For example, to reach the Gateway for the user-custom Application, use gateway.servicemanager.cluster.kyma.cx/user-custom.

Application Connectivity Validator

The Application Connectivity Validator verifies the subject of the client certificate. It is deployed per Application and it proxies requests to the Application Registry and the Event Service.

Connector Service

The Connector Service:

  • Handles the exchange of client certificates for a given Application.
  • Provides the Application Registry and Event Service endpoints.
  • Signs client certificates using the server-side certificate stored in a Kubernetes Secret.

Application Registry

The Application Registry saves and reads the APIs and Event Catalog metadata of the connected external solution in the Application custom resource. The system creates a new Kubernetes service for each registered API.

NOTE: Using the Application Registry, you can register an API along with its OAuth or Basic Authentication credentials. The credentials are stored in a Kubernetes Secret.

Event Service

The Event Service sends events to the Kyma Event Bus and enriches events with metadata that indicates the source of the event. This allows routing events to lambda functions and services based on their source Application.

Application

An Application represents an external solution connected to Kyma. It handles the integration with other components, such as the Service Catalog or the Event Bus. Using the components of the Application Connector, the Application creates a coherent identity for a connected external solution and ensures its separation. All Applications are instances of the Application custom resource, which also stores all of the relevant metadata. You can bind an Application to many Kyma Namespaces and use the APIs and the Event Catalogs of the connected external solution within their context.

Application Broker

The Application Broker (AB) watches all Application custom resources. These custom resources contain definitions of the external solutions’ APIs and events. The AB exposes those APIs and events definitions as ServiceClasses to the Service Catalog. When the list of remote ServiceClasses is available in the Service Catalog, you can create an ApplicationMapping, provision those ServiceClasses, and enable them for Kyma services. This allows you to extend the functionality of existing systems.

The AB implements the Open Service Broker API. For more details about Service Brokers, see this documentation.

Application Operator

The operator listens for creating or deleting the Application custom resources and acts accordingly, either provisioning or de-provisioning an instance of the Application Gateway and the Event Service for every custom resource.

NOTE: Every Application custom resource corresponds to a single Application to which you can connect an external solution.

Application Gateway

The Application Gateway is an intermediary component between a lambda function or a service and an external API registered with the Application Registry. It can call services secured with:

Additionally, the Application Gateway supports cross-site request forgery (CSRF) tokens as an optional layer of API protection.

Access Service

The Access Service exposes the Application Gateway and manages the access from the Lambda functions and services deployed in Kyma to the external APIs over the Application Gateway.

Asset Store

The Asset Store stores the documentation of the connected external solution's registered APIs and event catalogs.

Kubernetes Secret

The Kubernetes Secret is a Kubernetes object which stores sensitive data, such as the OAuth credentials.

Connector Service

The Connector Service generates client certificates which are used to secure the communication between Kyma and the connected external solutions.

Generating a new client certificate is the first step in the process of configuring an Application. Kyma stores the root certificate and serves as the Certificate Authority when you configure a new Application. When you generate a new client certificate, the Connector Service returns it along with the root certificate to allow validation.

This diagram illustrates the client certificate generation flow in details: Client certificate generation operation flow

  1. The administrator requests a token using the CLI or the UI and receives a link with the token, which is valid for a limited period of time.
  2. The administrator passes the token to the external system, which requests information regarding the Kyma installation. In the response, it receives the following information:
    • the URL to which a third-party solution sends its Certificate Signing Request (CSR)
    • the URL of the metadata endpoint
    • information required to generate a CSR
  3. The external system generates a CSR based on the information provided by Kyma and sends the CSR to the designated URL. In the response, the external system receives a signed certificate. It can use the certificate to authenticate and safely communicate with Kyma.
  4. The external system calls the metadata endpoint that contains the following information:
    • the URL of the Application Registry API
    • the URL of the Event Service API
    • the certificate renewal URL used to rotate certificates
    • the certificate revocation URL used to revoke compromised certificates
    • information uniquely identifying a certificate, such as the Application name
    • information required to generate a CSR

NOTE: The external Application should not hardcode any URLs. The information returned from the metadata endpoint should be stored by the external Application along with the certificate. This approach implicates less coupling and offers a great deal of flexibility.

NOTE: The external Application can call the metadata endpoint to fetch information required to generate a CSR prior to certificate renewal. This approach makes certificate rotation process convenient and flexible, since the external Application does not need to store information required to generate a CSR in its data model.

NOTE: Follow this tutorial to learn how to get a client certificate for your implementation.

Application Gateway

The Application Gateway sends the requests from lambda functions and services in Kyma to external APIs registered with the Application Registry. The Application Gateway works in conjunction with the Access Service, which exposes the Application Gateway.

NOTE: The system creates an Access Service for every external API registered by the Application Registry.

The following diagram illustrates how the Application Gateway interacts with other components and external APIs which are either unsecured or secured with various security mechanisms and protected against cross-site request forgery (CSRF) attacks.

Application Gateway Diagram

  1. A lambda function calls the Access Service. The name of every Access Service follows this format: {application-name}-{service-id}
  2. The Access Service exposes the Application Gateway.
  3. The Application Gateway extracts the Application name and the service ID from the name of the Access Service name. Using the extracted Application name, the Application Gateway finds the respective Application custom resource and obtains the information about the registered external API, such as the API URL and security credentials.
  4. The Application Gateway gets a token from the OAuth server.
  5. The Application Gateway gets a CSRF token from the endpoint exposed by the upstream service. This step is optional and is valid only for the API which was registered with a CSRF token turned on.
  6. The Application Gateway calls the target API.

Caching

To ensure optimal performance, the Application Gateway caches the OAuth tokens and CSRF tokens it obtains. If the service doesn't find valid tokens for the call it makes, it gets new tokens from the OAuth server and the CSRF token endpoint. Additionally, the service caches ReverseProxy objects used to proxy the requests to the underlying URL.

Handling of headers

The Application Gateway removes the following headers while making calls to the registered Applications:

  • X-Forwarded-Proto
  • X-Forwarded-For
  • X-Forwarded-Host
  • X-Forwarded-Client-Cert

In addition, the User-Agent header is set to an empty value not specified in the call, which prevents setting the default value.

Application Broker

The Application Broker (AB) workflow consists of the following steps:

  1. The Application Broker watches for Applications in the cluster and ApplicationMappings (AMs) in all Namespaces.
  2. The user creates an ApplicationMapping custom resource in a given Namespace. The AM activates services offered by an Application. The AM must have the same name as the Application.
  3. The Application Broker creates an application-broker Service Broker (SB) inside the Namespace in which the AM is created. This Service Broker contains data of all services provided by the activated Applications. There is always only one application-broker Service Broker per Namespace, even if there are more AMs.
  4. The Service Catalog fetches services that the application-broker Service Broker exposes.
  5. The Service Catalog creates a ServiceClass for each service received from the Service Broker.

AB architecture

When this process is complete, you can provision and bind your services.

Provisioning and binding for an API ServiceClass

This ServiceClass has a bindable parameter set to true, which means that you have to provision a ServiceInstance and bind it to the service or lambda to connect to the given API. The provisioning and binding workflow for an API ServiceClass consists of the following steps:

  1. Select an API ServiceClass from the Service Catalog.
  2. Provision this ServiceClass by creating its ServiceInstance in a Namespace.
  3. Bind your ServiceInstance to the service or lambda. During the binding process, ServiceBinding and ServiceBindingUsage resources are created.
  • ServiceBinding contains a Secret with a GatewayURL required to connect to the given API.
  • ServiceBindingUsage injects the Secret, together with the label given during the registration process, to the lambda or service.
  1. The service or lambda calls the API through the Application Connector. The Application Connector verifies the label to check if you have the authorization to access this API.
  2. After verifying the label, the Application Connector allows you to access the Application API.

API Service Class

Provisioning and binding for an event ServiceClass

This ServiceClass has a bindable parameter set to false which means that after provisioning a ServiceClass in the Namespace, given events are ready to use for all services. The provisioning workflow for an event ServiceClass consists of the following steps:

  1. Select a given event ServiceClass from the Service Catalog.
  2. Provision this ServiceClass by creating a ServiceInstance in the given Namespace.
  3. During the provisioning process, the EventActivation resource is created together with the ServiceInstance. EventActivation allows you to create an Event Bus Subscription.
  4. A Subscription is a custom resource by which an Event Bus triggers the lambda for a particular type of event in this step.
  5. The Application sends an event to the Application Connector.
  6. The Application Connector sends an event to the lambda through the Event Bus.

Event Service Class

Provisioning and binding for both the API and event ServiceClass

This ServiceClass has a bindable parameter set to true. The provisioning and binding workflow for both the API and event ServiceClass is a combination of the steps described for an API ServiceClass and an event ServiceClass.

Details

Security

Client certificates

To provide maximum security, the Application Connector uses TLS protocol with Client Authentication enabled. As a result, whoever wants to connect to the Application Connector must present a valid client certificate, which is dedicated to a specific Application. In this way, the traffic is fully encrypted and the client has a valid identity.

Disable SSL certificate verification

You can disable the SSL certificate verification in the communication between Kyma and an application to allow Kyma to send requests and data to an unsecured application. Disabling the certificate verification can be useful in certain testing scenarios.

NOTE: By default, the SSL certificate verification is enabled when sending data and requests to every application.

Follow these steps to disable SSL certificate verification for communication between Kyma and an external application:

  1. Edit the {APPLICATION_CR_NAME}-application-gateway Deployment in the kyma-integration Namespace. Run:
    Click to copy
    kubectl -n kyma-integration edit deployment {APPLICATION_CR_NAME}-application-gateway
  2. Edit the Deployment in Vim. Select i to start editing.
  3. Find the skipVerify parameter and change its value to true.
  4. Select esc, type :wq, and select enter to save the changes and quit.

Override the API security type

The Application Registry allows you to register APIs:

  • Secured with Basic Authentication
  • Secured with OAuth flow
  • Secured with client certificates
  • Not secured
  • Protected against cross-site request forgery (CSRF) attacks

The Application Gateway calls the registered APIs accordingly, basing on the security type specified in the API registration process.

The Application Gateway overrides the registered API's security type if it gets a request which contains the Access-Token header. In such a case, the Application Gateway rewrites the token from the Access-Token header into an OAuth-compliant Authorization header and forwards it to the target API.

This mechanism is suited for implementations in which an external application handles user authentication.

Access the Application Connector on a local Kyma deployment

To access the Application Connector on a local deployment of Kyma, you must add the Kyma server certificate to the trusted certificate storage of your programming environment. This is necessary to connect the external solution to your local Kyma deployment, allow client certificate exchange, and API registration.

For example, to access the Application Connector from a Java environment, run this command to add the Kyma server certificate to the Java Keystore:

Click to copy
sudo {JAVA_HOME}/bin/keytool -import -alias “Kyma” -keystore {JAVA_HOME}/jre/lib/security/cacerts -file {KYMA_HOME}/installation/certs/workspace/raw/server.crt

Consume applications through the Service Catalog

To consume an external solution connected to Kyma, you must register it as an Application. As a result of registering the external solution, ClusterServiceClasses are created in the Service Catalog.

External solution's services in the Service Catalog

The Example API is registered in Kyma with the targetUrl pointing to https://www.orders.com/v1/orders. The ID assigned to the API in the registration process is 01a702b8-e302-4e62-b678-8d361b627e49.

The Application Broker, which provides ServiceClasses to the Service Catalog, follows this naming convention for its objects:

Click to copy
{application-name}-{service-id}

The {service-id} is the service identifier assigned in the process of registration. The {application} is the name of the Application created in Kyma. It represents an instance of the connected external solution that owns the registered service. Such identifier used by the Application Broker is referred to as the name of a ClusterServiceClass in the Service Catalog.

This is an example of a full ClusterServiceClass name:

Click to copy
re-ec-default-01a702b8-e302-4e62-b678-8d361b627e49

Service consumption

After you provision the Example API in the Namespace of your choice using the Service Catalog, you can bind it to your Application and consume it by calling the URL you get as a result of a successful binding.

This is a sample URL for the Example API:

Click to copy
re-ec-default-01a702b8-e302-4e62-b678-8d361b627e49.kyma-integration/orders

When you call this URL, the Application Gateway passes all requests to the https://www.orders.com/v1/orders address, which is the targetUrl registered for the Example API. You do not have to get an OAuth token and manually include it in the call as the Application Gateway does it for you automatically.

Application Registry

The Application Registry allows you to register the APIs and event catalogs of the services exposed by the connected external solution.

The Application Registry stores the data of all registered services in:

  • Application custom resource (CR), which stores the metadata of the service.
  • DocsTopic custom resource (CR), which stores the links to API specification, event catalog, and documentation.
  • Upload Service, which stores the files containing API specification, event catalog, and documentation in an Asset Store bucket.
  • Kubernetes Secrets, which store sensitive data, such as OAuth credentials.

Kubernetes APIs interaction

The Application Registry interacts with Kubernetes APIs to perform these tasks:

  • Modify the Application CR instance.
  • Create Secrets which contain client ID and client secret used to access OAuth-secured APIs.
  • Create the Access Service.

Pass an access token in a request header

The Application Connector supports passing the access token directly in the request.

Passing the access token

If the user is already authenticated to the target API, the access token can be passed in a custom Access-token header. The value of the header is of the Bearer {token} or Basic {token} form. If the Application Connector detects that the custom header is present, instead of performing authentication steps, it removes the Access-token header and passes the received value in the Authorization header.

API registration in the Application Registry

The Application Registry supports the following formats of the API specification:

  • OpenAPI 2.0
  • OData XML 2.0, 3.0 and 4.0

You can pass the API specification in two ways:

  • JSON format
  • SpecificationUrl

NOTE: Specification passed directly as a JSON has a higher priority than SpecificationUrl. If you use these two methods at once, SpecificationUrl is ignored.

For the OpenAPI format, both methods are supported. You can register OData APIs only with SpecificationUrl.

Application Connector Certificates

The Application Connector is secured with a client certificate verified by the Istio Ingress Gateway.

The Certificates are generated and stored as Kubernetes Secrets by the Application Connector Certs Setup job.

By default, the server key and certificate are automatically generated. You can provide a custom server certificate and key during the installation by setting them as the following overrides:

Click to copy
global.applicationConnectorCaKey: "{BASE64_ENCODED_PRIVATE_KEY}"
global.applicationConnectorCa: "{BASE64_ENCODED_CERTIFICATE}"

NOTE: To use a custom certificate and key, you must provide both values through overrides. If either the certificate or key is incorrect or isn't provided, a new certificate and key pair is generated.

This is a sample ConfigMap that contains overrides with a custom certificate and key:

Click to copy
apiVersion: v1
kind: ConfigMap
metadata:
name: application-connector-certificate-overrides
namespace: kyma-installer
labels:
installer: overrides
kyma-project.io/installation: ""
data:
global.applicationConnectorCa: "{BASE64_ENCODED_CERTIFICATE}"
global.applicationConnectorCaKey: "{BASE64_ENCODED_PRIVATE_KEY}"

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configuration

Application Operator sub-chart

To configure the Application Operator sub-chart, override the default values of its values.yaml file. This document describes parameters that you can configure.

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configurable parameters

This table lists the configurable parameters, their descriptions, and default values:

ParameterDescriptionDefault value
controller.args.installationTimeoutSpecifies a period of time provided for the Application Gateway, Application Connectivity Validator and Event Service installation. The Application requires these services to be operational. The value is provided in seconds.240
controller.args.tillerTLSSkipVerifyDisables TLS verification in Tiller.true

Application Registry sub-chart

To configure the Application Registry sub-chart, override the default values of its values.yaml file. This document describes parameters that you can configure.

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configurable parameters

This table lists the configurable parameters, their descriptions, and default values:

ParameterDescriptionDefault value
deployment.args.requestTimeoutSpecifies an overall time-out after which requests to the Application Registry fail to be sent. It is provided in seconds.10
deployment.args.requestLoggingEnables logging incoming requests. By default, logging is disabled.false
deployment.args.specRequestTimeoutSpecifies a time-out after which a request fetching specifications provided by the user fails to be sent. It is provided in seconds.5
deployment.args.assetstoreRequestTimeoutSpecifies a time-out after which a request fetching specifications from the Asset Store fails to be sent. It is provided in seconds.5
deployment.args.insecureAssetDownloadDisables verifying certificates when downloading data from the Asset Store.true
deployment.args.insecureSpecDownloadDisables verifying certificates when fetching API specification from specification URL.true
deployment.args.detailedErrorResponseEnables showing full messages for internal error responses.false

Connectivity Certs Controller sub-chart

To configure the Connectivity Certs Controller sub-chart, override the default values of its values.yaml file. This document describes parameters that you can configure.

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configurable parameters

This table lists the configurable parameters, their descriptions, and default values:

ParameterDescriptionDefault value
deployment.args.minimalConnectionSyncPeriodSpecifies a minimum period of time between particular attempts to synchronize with the Central Connector Service. It is provided in seconds.300

Connector Service sub-chart

To configure the Connector Service sub-chart, override the default values of its values.yaml file. This document describes parameters that you can configure.

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configurable parameters

This table lists the configurable parameters, their descriptions, and default values:

ParameterDescriptionDefault value
deployment.args.tokenLengthSpecifies the number of characters in a registration token.64
deployment.args.appTokenExpirationMinutesSpecifies the period of time after which a token for an Application expires. It is provided in minutes.5
deployment.args.runtimeTokenExpirationMinutesSpecifies the period of time after which a token for a Runtime expires. It is provided in minutes.10
deployment.args.appValidityTimeSpecifies the period of time during which certificates that the service issues for an Application are valid. It is provided in days.92d
deployment.args.runtimeValidityTimeSpecifies the period of time during which certificates that the service issues for a Runtime are valid. It is provided in days.92d
deployment.args.centralDetermines whether the Connector Service works in the central mode.false
deployment.args.requestLoggingEnables logging of incoming requests.false
deployment.envvars.countrySpecifies a country expected in a Certificate Signing Request. It is provided as a two-letter country code.DE
deployment.envvars.organizationSpecifies an organization expected in a Certificate Signing Request.Organization
deployment.envvars.organizationalunitSpecifies an organizational unit expected in a Certificate Signing Request.OrgUnit
deployment.envvars.localitySpecifies a locality expected in a Certificate Signing Request.Waldorf
deployment.envvars.provinceSpecifies a province expected in a Certificate Signing Request.Waldorf

Application Connectivity Certs Setup Job

To configure the Application Connectivity Certs Setup Job, override the default values of its values.yaml file. This document describes parameters that you can configure.

TIP: To learn more about how to use overrides in Kyma, see the following documents:

Configurable parameters

This table lists the configurable parameters, their descriptions, and default values:

ParameterDescriptionDefault value
global.applicationConnectorCaKeySpecifies the base64-encoded private key for the Application Connector. If you don't provide it, the private key is generated automatically.autogenerated
global.applicationConnectorCaSpecifies the base64-encoded certificate for the Application Connector. If you don't provide it, the certificate is generated automatically.autogenerated
application_connectivity_certs_setup_job.certificate.validityTimeSpecifies how long the generated certificate is valid.92d

Custom Resource

Application

The applications.applicationconnector.kyma-project.io CustomResourceDefinition (CRD) is a detailed description of the kind of data and the format used to register an Application in Kyma. The Application custom resource (CR) defines the APIs that the Application offers. After creating a new custom resource for a given Application, the Application is mapped to appropriate ServiceClasses in the Service Catalog. To get the up-to-date CRD and show the output in the yaml format, run this command:

Click to copy
kubectl get crd applications.applicationconnector.kyma-project.io -o yaml

Sample custom resource

This is a sample resource that registers the system-prod Application which offers one service.

NOTE: The name of the Application must consist of lower case alphanumeric characters, - or ., and start and end with an alphanumeric character.

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: Application
metadata:
name: system-prod
spec:
description: This is the system-production Application.
labels:
region: us
kind: production

Custom resource parameters

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

ParameterRequiredDescription
metadata.nameYesSpecifies the name of the CR.
spec.descriptionNoDescribes the connected Application.
spec.accessLabelNoLabels the Application when an ApplicationMapping is created.
spec.labelsNoDefines the labels of the Application.
spec.servicesNoContains all services that the Application provides.
spec.services.idYesIdentifies the service that the Application provides.
spec.services.identifierNoProvides an additional identifier of the ServiceClass.
spec.services.nameNoRepresents a unique name of the service used by the Service Catalog.
spec.services.displayNameYesSpecifies a human-readable name of the Application service. Parameter provided by the Application Registry, do not edit.
spec.services.descriptionNoProvides a short, human-readable description of the service offered by the Application. Parameter provided by the Application Registry, do not edit.
spec.services.longDescriptionNoProvides a longer, human-readable description of the service offered by the Application. Parameter provided by the Application Registry, do not edit.
spec.services.providerDisplayNameYesSpecifies a human-readable name of the Application service provider. Parameter provided by the Application Registry, do not edit.
spec.services.tagsNoSpecifies additional tags used for better documentation of the available APIs. Parameter provided by the Application Registry, do not edit.
spec.services.labelsNoSpecifies additional labels for the service offered by the Application. Parameter provided by the Application Registry, do not edit.
spec.services.entriesYesContains the information about the APIs and events that the service offered by the Application provides. Parameter provided by the Application Registry, do not edit.
spec.services.entries.typeYesSpecifies the entry type: API or event. Parameter provided by the Application Registry, do not edit.
spec.services.entries.gatewayUrlNoSpecifies the URL of the Application Connector. This field is required for the API entry type. Parameter provided by the Application Registry, do not edit.
spec.services.entries.accessLabelNoSpecifies the label used in Istio rules in the Application Connector. This field is required for the API entry type.
spec.services.entries.targetUrlNoSpecifies the URL of a given API. This field is required for the API entry type. Parameter provided by the Application Registry, do not edit.
spec.services.entries.oauthUrlNoSpecifies the URL used to authorize with a given API. This field is required for the API entry type. Parameter provided by the Application Registry, do not edit.
spec.services.entries.credentialsSecretNameNoSpecifies the name of the Secret which allows you to call a given API. This field is required if spec.services.entries.oauthUrl is specified. Parameter provided by the Application Registry, do not edit.

These components use this CR:

ComponentDescription
Application RegistryReads and saves the APIs and Event Catalog metadata of the connected external solution in this CR.
Application BrokerExposes the APIs and event definitions stored in this CR as ServiceClasses to the Service Catalog.
Application OperatorProvisions and de-provisions an instance of Application Gateway and Event Service for every created or deleted Application CR.

Additional information

The Application Operator adds the status section which describes the status of the Application installation to the created CR periodically. This table lists the fields of the status section.

FieldDescription
status.installationStatusDescribes the status of the Application installation.
status.installationStatus.descriptionProvides a longer description of the installation status.
status.installationStatus.statusProvides a short, human-readable description of the installation status.

ApplicationMapping

The applicationmappings.application.kyma-project.io CustomResourceDefinition (CRD) is a detailed description of the kind of data and the format used to enable APIs and events from an Application as a ServiceClass in a given Namespace. To get the up-to-date CRD and show the output in the yaml format, run this command:

Click to copy
kubectl get crd applicationmappings.applicationconnector.kyma-project.io -o yaml

Sample custom resource

This is a sample ApplicationMapping resource which enables the test Application in the production Namespace. In this example, all services provided by the Application are enabled:

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: ApplicationMapping
metadata:
name: test
namespace: production

Using ApplicationMapping, you can also enable only the selected services in a given Namespace. See the example:

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: ApplicationMapping
metadata:
name: test
namespace: production
spec:
services:
- id: ac031e8c-9aa4-4cb7-8999-0d358726ffaa
- id: bef3143c-d1a5-674c-8dc9-ab4788896fba

The services list contains IDs of enabled services.

Custom resource parameters

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

ParameterRequiredDescription
metadata.nameYesSpecifies the name of the CR and the Application.
metadata.namespaceYesSpecifies the Namespace to which the Application is bound.
spec.services[]NoLists enabled services. If the list is specified, only the selected services are enabled. If the list is empty, all services of the Application are enabled.
spec.services[].idNoSpecifies the ID of the enabled service.

These components use this CR:

ComponentDescription
Application BrokerUses this CR to enable the provisioning of ServiceClasses in a given Namespace.
Console Backend ServiceUses this CR to filter the enabled Applications. It also allows you to create or delete ApplicationMappings.

EventActivation

The eventactivations.applicationconnector.kyma-project.io CustomResourceDefinition (CRD) is a detailed description of the kind of data and the format used to create an Event Bus Subscription and to get an event schema. To get the up-to-date CRD and show the output in the yaml format, run this command:

Click to copy
kubectl get crd eventactivations.applicationconnector.kyma-project.io -o yaml

Sample custom resource

This is a sample resource that allows you to consume events sent from the service with the ac031e8c-9aa4-4cb7-8999-0d358726ffaa ID in a production Namespace.

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: EventActivation
metadata:
name: "ac031e8c-9aa4-4cb7-8999-0d358726ffaa"
namespace: production
spec:
displayName: "Orders"
sourceId: "prod"

Custom resource parameters

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

ParameterRequiredDescription
metadata.nameYesSpecifies the name of the CR and the ID of the Application service. This field is also used to fetch event schemas from the MinIO storage.
metadata.namespaceYesSpecifies the Namespace in which the CR is created.
spec.displayNameYesSpecifies a human-readable name of the Application service.
spec.sourceIdYesUsed to construct a Publish-Subscribe (Pub/Sub) topic name where events are sent and from where they are consumed.

These are the resources related to this CR:

Custom resourceDescription
ApplicationDescribes a service from which the user receives events.
SubscriptionContains information on how to create an infrastructure for consuming events. Works only if the EventActivation is enabled.

These components use this CR:

ComponentDescription
Application BrokerUses this CR to enable the user to receive events from a given service.
Event BusUses this CR to control the consumption of an event.
ServerlessLambda UI sends a GraphQL query to Console Backend Service to list EventActivations.
Console Backend ServiceExposes the given CR to the Console UI.

TokenRequest

The tokenrequests.applicationconnector.kyma-project.io CustomResourceDefinition (CRD) is a detailed description of the kind of data and the format used to request a token for an Application configuration URL from the Connector Service. To get the up-to-date CRD and show the output in the yaml format, run this command:

Click to copy
kubectl get crd tokenrequests.applicationconnector.kyma-project.io -o yaml

Sample custom resource

This is a sample custom resource (CR) which allows to get the configuration required to connect an external solution to the test Application.

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: TokenRequest
metadata:
name: test-app
context:
tenant: test-tenant
group: test-group

Custom resource parameters

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

ParameterRequiredDescription
metadata.nameYesSpecifies the name of the CR and the Application for which to request a token.
context.tenantNoSpecifies the name of the Tenant.
context.groupNoSpecifies the name of the Group.

Additional information

When you fetch an existing TokenRequest CR, the system adds the status section which describes the status of the request and lists the configuration details. This table lists the fields of the status section.

FieldDescription
status.expireAfterDate and time after which the token expires and the controller deletes the CR.
status.applicationThe name of the Application for which the token was issued.
status.stateStatus of the token request. This field can have one of the two values: OK or ERR.
status.tokenThe token generated by the Connector Service.
status.urlThe URL to the Connector Service info endpoint with the token.

Tutorials

Create a new Application

The Application Operator listens for the creation of Application custom resources. It provisions and de-provisions the necessary deployments for every created Application.

NOTE: An Application represents a single connected external solution.

To create a new Application, run this command:

Click to copy
cat <<EOF | kubectl apply -f -
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: Application
metadata:
name: {APP_NAME}
spec:
description: {APP_DESCRIPTION}
labels:
region: us
kind: production
EOF

Check the Application status

To check the status of the created Application and show the output in the yaml format, run this command:

Click to copy
kubectl get app {APP_NAME} -o yaml

A successful response returns the Application custom resource with the specified name. The custom resource has the status section added. This is an example response:

Click to copy
apiVersion: applicationconnector.kyma-project.io/v1alpha1
kind: Application
metadata:
clusterName: ""
creationTimestamp: 2018-11-22T13:53:20Z
generation: 1
name: test1
namespace: ""
resourceVersion: "30728"
selfLink: /apis/applicationconnector.kyma-project.io/v1alpha1/applications/test1
uid: f8ca5595-ee5d-11e8-acb2-000d3a443243
spec:
accessLabel: {APP_NAME}
description: {APP_DESCRIPTION}
labels: {}
services: []
status:
installationStatus:
description: Installation complete
status: DEPLOYED

Get the client certificate

After you create an Application, connect it to an external solution to consume the solution's APIs and event catalogs in Kyma. To accomplish this, get the client certificate for the external solution and register its services.

This guide shows you how to get the client certificate.

NOTE: The client certificate is valid for 92 days. See this tutorial to learn how to renew the client certificate. You can also revoke the client certificate, which prevents it from being renewed. See this tutorial to learn how to do this.

Prerequisites

  • OpenSSL toolkit to create a Certificate Signing Request (CSR), keys, and certificates which meet high security standards

Get the configuration URL with a token

To get the configuration URL which allows you to fetch the required configuration details, create a TokenRequest custom resource (CR). The controller which handles this CR kind adds the status section to the created CR. The status section contains the required configuration details.

  • Create a TokenRequest CR. The CR name must match the name of the Application for which you want to get the configuration details. Run:

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: applicationconnector.kyma-project.io/v1alpha1
    kind: TokenRequest
    metadata:
    name: {APP_NAME}
    EOF
  • Fetch the TokenRequest CR you created to get the configuration details from the status section. Run:

    Click to copy
    kubectl get tokenrequest.applicationconnector.kyma-project.io {APP_NAME} -o yaml

    NOTE: If the response doesn't contain the status section, wait for a few moments and fetch the CR again.

    A successful call returns the following response:

    Click to copy
    apiVersion: applicationconnector.kyma-project.io/v1alpha1
    kind: TokenRequest
    metadata:
    name: {APP_NAME}
    status:
    expireAfter: 2018-11-22T18:38:44Z
    application: {APP_NAME}
    state: OK
    token: h31IwJiLNjnbqIwTPnzLuNmFYsCZeUtVbUvYL2hVNh6kOqFlW9zkHnzxYFCpCExBZ_voGzUo6IVS_ExlZd4muQ==
    url: https://connector-service.kyma.local/v1/applications/signingRequests/info?token=h31IwJiLNjnbqIwTPnzLuNmFYsCZeUtVbUvYL2hVNh6kOqFlW9zkHnzxYFCpCExBZ_voGzUo6IVS_ExlZd4muQ==

Get the CSR information and configuration details from Kyma

Use the link you got in the previous step to fetch the CSR information and configuration details required to connect your external solution. Run:

Click to copy
curl {CONFIGURATION_URL_WITH_TOKEN}

NOTE: The URL you call in this step contains a token that is valid for 5 minutes or for a single call. You get a code 403 error if you call the same configuration URL more than once, or if you call a URL with an expired token.

A successful call returns the following response:

Click to copy
{
"csrUrl": "{CSR_SIGNING_URL_WITH_TOKEN}",
"api":{
"metadataUrl": "https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/services",
"eventsUrl": "https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/events",
"infoUrl": "https://gateway.{CLUSTER_DOMAIN}/v1/applications/management/info",
"certificatesUrl": "https://connector-service.{CLUSTER_DOMAIN}/v1/applications/certificates",
},
"certificate":{
"subject":"OU=Test,O=TestOrg,L=Waldorf,ST=Waldorf,C=DE,CN={APP_NAME}",
"extensions": "",
"key-algorithm": "rsa2048",
}
}

NOTE: The response contains URLs to the Application Registry API and the Events Service API, however, it is not recommended to use them. You should call the metadata endpoint URL, which is provided in api.infoUrl property, to fetch correct URLs to the Application Registry API and to the Events Service API, and other configuration details.

Generate a CSR and send it to Kyma

Generate a CSR using the certificate subject data obtained in the previous step:

Click to copy
openssl genrsa -out generated.key 2048
openssl req -new -sha256 -out generated.csr -key generated.key -subj "/OU=Test/O=TestOrg/L=Waldorf/ST=Waldorf/C=DE/CN={APP_NAME}"
openssl base64 -in generated.csr

Send the encoded CSR to Kyma. Run:

Click to copy
curl -H "Content-Type: application/json" -d '{"csr":"BASE64_ENCODED_CSR_HERE"}' {CSR_SIGNING_URL_WITH_TOKEN}

The response contains a valid client certificate signed by the Kyma Certificate Authority (CA).

Click to copy
{
"crt":"BASE64_ENCODED_CRT_CHAIN",
"clientCrt":"BASE64_ENCODED_CLIENT_CRT",
"caCrt":"BASE64_ENCODED_CA_CRT"
}

After you receive the certificate, decode it and use it in your Application.

Call the metadata endpoint

Call the metadata endpoint with the generated certificate to get URLs to the following:

  • the Application Registry API
  • the Event Service API
  • the certificate renewal endpoint
  • the certificate revocation endpoint

The URL to the metadata endpoint is returned in the response body from the configuration URL. Use the value of the api.infoUrl property to get the URL. Run:

Click to copy
curl https://gateway.{CLUSTER_DOMAIN}/v1/applications/management/info --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

A successful call returns the following response:

Click to copy
{
"clientIdentity": {
"application": "{APP_NAME}"
},
"urls": {
"metadataUrl": "https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/services",
"eventsUrl": "https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/events",
"renewCertUrl": "https://gateway.{CLUSTER_DOMAIN}/v1/applications/certificates/renewals",
"revokeCertUrl": "https://gateway.{CLUSTER_DOMAIN}/v1/applications/certificates/revocations"
},
"certificate": {
"subject": "OU=Test,O=Test,L=Blacksburg,ST=Virginia,C=US,CN={APP_NAME}",
"extensions": "string",
"key-algorithm": "rsa2048"
}
}

Use urls.metadataUrl and urls.eventsUrl to get the URLs to the Application Registry API and to the Event Service API.

Call the Application Registry and Event Service on local deployment

Since Kyma installation on Minikube uses the self-signed certificate by default, skip TLS verification.

Call the Application Registry with this command:

Click to copy
curl https://gateway.kyma.local/{APP_NAME}/v1/metadata/services --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

Use this command to call the Event Service:

Click to copy
curl https://gateway.kyma.local/{APP_NAME}/v1/events --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

Register a service

This guide shows you how to register a service of your external solution in Kyma.

Prerequisites

  • A valid certificate signed by the Kyma Certificate Authority

Register a service

  1. To register a service with a Basic Authentication-secured API, follow this template to prepare the request body:

    NOTE: Follow this tutorial to learn how to register APIs secured with different security schemes or protected against cross-site request forgery (CSRF) attacks.

    Click to copy
    {
    "provider": "example-provider",
    "name": "example-name",
    "description": "This is the long description of your service",
    "shortDescription": "Short description",
    "labels": {
    "example": "true"
    },
    "api": {
    "targetUrl": "https://httpbin.org/",
    "spec": {},
    "requestParameters": {
    "queryParameters": {
    "param": ["bar"]
    },
    "headers": {
    "custom-header": ["foo"]
    }
    },
    "credentials": {
    "basic": {
    "username": "{USERNAME}",
    "password": "{PASSWORD}"
    }
    }
    },
    "events": {
    "spec": {
    "asyncapi": "1.0.0",
    "info": {
    "title": "PetStore Events",
    "version": "1.0.0",
    "description": "Description of all the events"
    },
    "baseTopic": "stage.com.some.company.system",
    "topics": {
    "petCreated.v1": {
    "subscribe": {
    "summary": "Event containing information about new pet added to the Pet Store.",
    "payload": {
    "type": "object",
    "properties": {
    "pet": {
    "type": "object",
    "required": [
    "id",
    "name"
    ],
    "example": {
    "id": "4caad296-e0c5-491e-98ac-0ed118f9474e",
    "category": "mammal",
    "name": "doggie"
    },
    "properties": {
    "id": {
    "title": "Id",
    "description": "Resource identifier",
    "type": "string"
    },
    "name": {
    "title": "Name",
    "description": "Pet name",
    "type": "string"
    },
    "category": {
    "title": "Category",
    "description": "Animal category",
    "type": "string"
    }
    }
    }
    }
    }
    }
    }
    }
    }
    },
    "documentation": {
    "displayName": "Documentation",
    "description": "Description",
    "type": "some type",
    "tags": ["tag1", "tag2"],
    "docs": [
    {
    "title": "Documentation title...",
    "type": "type",
    "source": "source"
    }
    ]
    }
    }
  2. Include the request body you prepared in the following call to register a service:

    Click to copy
    curl -X POST -d '{YOUR_REQUEST_BODY}' https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/services --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

    A successful response returns the ID of the registered service:

    Click to copy
    {"id":"{YOUR_SERVICE_ID}"}

Check the details of a registered service

Click to copy
curl https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/services/{YOUR_SERVICE_ID} --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

Register an API with a specification URL

The Application Registry allows you to pass API specifications in a form of specification URLs.

To register an API with a specification URL, replace api.spec with api.specificationUrl.

NOTE: If both api.spec and api.specificationUrl are provided, api.spec will be used due to its higher priority.

See the example of the API part of the request body with a specification URL:

Click to copy
"api": {
"targetUrl": "https://services.odata.org/OData/OData.svc",
"specificationUrl": "https://services.odata.org/OData/OData.svc/$metadata",
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
}
}
}

NOTE: Fetching a specification from a URL is supported only for APIs. Fetching specifications for events or documentation is not supported.

Register an API with a secured specification URL

The Application Registry allows you to register an API with a secured specification URL. The supported authentication methods are Basic Authentication and OAuth. You can specify only one type of authentication for an API.

Register an API with a Basic Authentication-secured specification URL

To register an API with a specification URL secured with Basic Authentication, add a specificationCredentials.basic object to the api section of the service registration request body. You must include these fields:

FieldDescription
usernameBasic Authorization username
passwordBasic Authorization password

This is an example of the api section of the request body for an API with a specification URL secured with Basic Authentication:

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"specificationUrl": "https://sampleapi.spec/v1",
"specificationCredentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
},
}
}

Register an API with an OAuth-secured specification URL

To register an API with a specification URL secured with OAuth, add a specificationCredentials.oauth object to the api section of the service registration request body. You must include these fields:

FieldDescription
urlOAuth token exchange endpoint of the service
clientIdOAuth client ID
clientSecretOAuth client Secret

This is an example of the api section of the request body for an API with a specification URL secured with OAuth:

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"specificationUrl": "https://sampleapi.spec/v1",
"specificationCredentials": {
"oauth": {
"url": "https://sampleapi.targeturl/authorizationserver/oauth/token",
"clientId": "{CLIENT_ID}",
"clientSecret": "{CLIENT_SECRET}"
},
}
}

Use custom headers and query parameters for fetching API specification from URL

You can specify additional headers and query parameters to inject to requests made to the specification URL.

NOTE: These headers and query parameters are used only for requests for fetching an API specification and are not stored in the system.

To register an API with a specification URL that requires specific custom headers and query parameters, add the specificationRequestParameters.headers and specificationRequestParameters.queryParameters objects to the api section of the service registration request body.

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"specificationUrl": "https://sampleapi.spec/v1",
"specificationRequestParameters": {
"headers": {
"custom-header": ["foo"]
},
"queryParameters": {
"param": ["bar"]
},
}
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
},
}
}

Register an OData API

If the api.spec or api.specificationUrl parameters are not specified and the api.type parameter is set to OData, the Application Registry will try to fetch the specification from the target URL with the $metadata path.

For example, for the service with the following API, the Application Registry will try to fetch the API specification from https://services.odata.org/OData/OData.svc/$metadata.

Click to copy
"api": {
"targetUrl": "https://services.odata.org/OData/OData.svc",
"apiType": "OData"
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
}
}
}

Register a secured API

The Application Registry allows you to register a secured API for every service. The supported authentication methods are Basic Authentication, OAuth, and client certificates.

You can specify only one authentication method for every secured API you register. If you try to register and specify more than one authentication method, the Application Registry returns the 400 code response.

Additionally, you can secure the API against cross-site request forgery (CSRF) attacks. CSRF tokens are an additional layer of protection and can accompany any authentication method.

NOTE: Registering a secured API is a part of registering services of an external solution connected to Kyma. To learn more about this process, follow this tutorial.

Register a Basic Authentication-secured API

To register an API secured with Basic Authentication, add a credentials.basic object to the api section of the service registration request body. You must include these fields:

FieldDescription
usernameBasic Authorization username
passwordBasic Authorization password

This is an example of the api section of the request body for an API secured with Basic Authentication:

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
},
}
}

Register an OAuth-secured API

To register an API secured with OAuth, add a credentials.oauth object to the api section of the service registration request body. You must include these fields:

FieldDescription
urlOAuth token exchange endpoint of the service
clientIdOAuth client ID
clientSecretOAuth client Secret

This is an example of the api section of the request body for an API secured with OAuth:

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"credentials": {
"oauth": {
"url": "https://sampleapi.targeturl/authorizationserver/oauth/token",
"clientId": "{CLIENT_ID}",
"clientSecret": "{CLIENT_SECRET}"
},
}
}

Register a client certificate-secured API

To register an API and secure it with client certificates, you must add the credentials.certificateGen object to the api section of the service registration request body. The Application Registry generates a ready to use certificate and key pair for every API registered this way. You can use the generated pair or replace it with your own certificate and key.

Include this field in the service registration request body:

FieldDescription
commonNameName of the generated certificate. Set as the CN field of the certificate Subject.

This is an example of the api section of the request body for an API secured with generated client certificates:

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"credentials": {
"certificateGen": {
"commonName": "{CERT_NAME}"
},
}
}

NOTE: If you update the registered API and change the certificateGen.commonName, the Application Registry generates a new certificate-key pair for that API. When you delete an API secured with generated client certificates, the Application Registry deletes the corresponding certificate and key.

Details

When you register an API with the credentials.certificateGen object, the Application Registry generates a SHA256withRSA-encrypted certificate and a matching key. To enable communication between Kyma and an API secured with this authentication method, set the certificate as a valid authentication medium for all calls coming from Kyma in your external solution.

You can retrieve the client certificate by sending the following request:

Click to copy
curl https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/services/{YOUR_SERVICE_ID} --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -k

A successful call will return a response body with the details of a registered service and a base64-encoded client certificate.

The certificate and key pair is stored in a Secret in the kyma-integration Namespace. List all Secrets and find the one created for your API:

Click to copy
kubectl -n kyma-integration get secrets

To fetch the certificate and key encoded with base64, run this command:

Click to copy
kubectl -n kyma-integration get secrets app-{APP_NAME}-{SERVICE_ID} -o yaml

NOTE: Replace the APP_NAME placeholder with the name of the Application used to connect the external solution that is the origin of the API. Replace the SERVICE_ID placeholder with the ID of the registered service to which the API belongs. You get this ID after you register an external solution's service in Kyma.

If the API you registered provides a certificate-key pair or the generated certificate doesn't meet your security standards or specific needs, you can use a custom certificate-key pair for authentication. To replace the Kyma-generated pair with your certificate and key, run this command:

Click to copy
kubectl -n kyma-integration patch secrets app-{APP_NAME}-{SERVICE_ID} --patch 'data:
crt: {BASE64_ENCODED_CRT}
key: {BASE64_ENCODED_KEY}'

Register a CSRF-protected API

The Application Registry supports CSRF tokens as an additional layer of API protection. To register a CSRF-protected API, add the credentials.{AUTHENTICATION_METHOD}.csrfInfo object to the api section of the service registration request body.

Include this field in the service registration request body:

FieldDescription
tokenEndpointURLThe URL to the upstream service endpoint that exposes CSRF tokens.

This is an example of the api section of the request body for an API secured with both Basic Authentication and a CSRF token.

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}",
"csrfInfo": {
"tokenEndpointURL": "{TOKEN_ENDPOINT_URL}"
}
},
}
}

Use headers and query parameters for custom authentication

You can specify additional headers and query parameters to inject to requests made to the target API. The Kubernetes Secret stores headers and query parameters which you can use for custom authentication methods.

This is an example of the api section of the request body for an API secured with Basic Authentication. It is enriched with the custom-header header with the foo value, and the param query parameter with the bar value.

Click to copy
"api": {
"targetUrl": "https://sampleapi.targeturl/v1",
"requestParameters": {
"headers": {
"custom-header": ["foo"]
},
"queryParameters": {
"param": ["bar"]
},
}
"credentials": {
"basic": {
"username": "{USERNAME}",
"password": "{PASSWORD}"
},
}
}

Trigger a lambda with events

To create a simple lambda function and trigger it with an event, you must first register a service using the Application Registry that is a part of the Application Connector. This service then sends the event that triggers the lambda. You must create a Service Instance which enables this event in the Namespace. Follow this guide to learn how to do it.

Prerequisites

  • An Application bound to a Namespace
  • Client certificates generated for the connected Application

NOTE: See the respective tutorials to learn how to create an Application, get the client certificate, and bind an Application to a Namespace.

Steps

  1. Export the name of the Namespace to which you bound your Application, and the name of your Application.

    Click to copy
    export NAMESPACE={YOUR_NAMESPACE}
    export APP_NAME={YOUR_APPLICATION_NAME}
  2. Register a service with events in the desired Application. Use the example AsyncAPI specification.

    NOTE: See this tutorial to learn how to register a service.

    Click to copy
    {
    "name": "my-events-service",
    "provider": "myCompany",
    "Identifier": "identifier",
    "description": "This is some service",
    "events": {
    "spec": {
    "asyncapi": "2.0.0",
    "info": {
    "title": "Example Events",
    "version": "2.0.0",
    "description": "Description of all the example events"
    },
    "channels": {
    "example/events/com/exampleEvent/v1": {
    "subscribe": {
    "message": {
    "summary": "Example event",
    "payload": {
    "type": "object",
    "properties": {
    "myObject": {
    "type": "object",
    "required": [
    "id"
    ],
    "example": {
    "id": "4caad296-e0c5-491e-98ac-0ed118f9474e"
    },
    "properties": {
    "id": {
    "title": "Id",
    "description": "Resource identifier",
    "type": "string"
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
    }
  3. Expose the externalName of the Service Class of the registered service.

    Click to copy
    export EXTERNAL_NAME=$(kubectl -n $NAMESPACE get serviceclass {SERVICE_ID} -o jsonpath='{.spec.externalName}')
  4. Create a Service Instance for the registered service.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: servicecatalog.k8s.io/v1beta1
    kind: ServiceInstance
    metadata:
    name: my-events-service-instance-name
    namespace: $NAMESPACE
    spec:
    serviceClassExternalName: $EXTERNAL_NAME
    EOF
  5. Create and register a lambda function in your Namespace.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: kubeless.io/v1beta1
    kind: Function
    metadata:
    name: my-events-lambda
    namespace: $NAMESPACE
    labels:
    app: my-events-lambda
    spec:
    deployment:
    spec:
    template:
    spec:
    containers:
    - name: ""
    resources: {}
    deps: |-
    {
    "name": "example-1",
    "version": "0.0.1",
    "dependencies": {
    "request": "^2.85.0"
    }
    }
    function: |-
    const request = require('request');
    module.exports = { main: function (event, context) {
    return new Promise((resolve, reject) => {
    const url = \`http://httpbin.org/uuid\`;
    const options = {
    url: url,
    };
    sendReq(url, resolve, reject)
    })
    } }
    function sendReq(url, resolve, reject) {
    request.get(url, { json: true }, (error, response, body) => {
    if(error){
    resolve(error);
    }
    console.log("Response acquired successfully! Uuid: " + response.body.uuid);
    resolve(response);
    })
    }
    function-content-type: text
    handler: handler.main
    horizontalPodAutoscaler:
    spec:
    maxReplicas: 0
    runtime: nodejs8
    service:
    ports:
    - name: http-function-port
    port: 8080
    protocol: TCP
    targetPort: 8080
    selector:
    created-by: kubeless
    function: my-events-lambda
    timeout: ""
    topic: exampleEvent
    EOF
  6. Create a Subscription to allow events to trigger the lambda function.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: eventing.kyma-project.io/v1alpha1
    kind: Subscription
    metadata:
    labels:
    Function: my-events-lambda
    name: lambda-my-events-lambda-exampleevent-v1
    namespace: $NAMESPACE
    spec:
    endpoint: http://my-events-lambda.$NAMESPACE:8080/
    event_type: exampleevent
    event_type_version: v1
    include_subscription_name_header: true
    source_id: $APP_NAME
    EOF
  7. Send an event to trigger the created lambda.

    Click to copy
    curl -X POST https://gateway.{CLUSTER_DOMAIN}/$APP_NAME/v1/events -k --cert {CERT_FILE_NAME}.crt --key {KEY_FILE_NAME}.key -d \
    '{
    "event-type": "exampleevent",
    "event-type-version": "v1",
    "event-id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
    "event-time": "2018-10-16T15:00:00Z",
    "data": "some data"
    }'
  8. Check the logs of the lambda function to see if it was triggered. Every time an event successfully triggers the function, this message appears in the logs: Response acquired successfully! Uuid: {RECEIVED_UUID}.

    Click to copy
    kubectl -n $NAMESPACE logs "$(kubectl -n $NAMESPACE get po -l function=my-events-lambda -o jsonpath='{.items[0].metadata.name}')" -c my-events-lambda | grep -E "Response acquired successfully! Uuid: [a-f0-9-]+"

Call a registered external service from Kyma

This guide shows how to call a registered external service from Kyma using a simple lambda function.

Prerequisites

  • An Application bound to the production Namespace
  • Client certificates generated for the connected App.
  • Map my-lambda-production.kyma.local to your Minikube IP to call the lambda function on a local Kyma deployment.

Steps

  1. Register a service with the following specification to the desired Application.

    NOTE: See this tutorial to learn how to register a service.

    Click to copy
    {
    "name": "my-service",
    "provider": "myCompany",
    "Identifier": "identifier",
    "description": "This is some service",
    "api": {
    "targetUrl": "http://httpbin.org/",
    "spec": {
    "swagger":"2.0"
    }
    }
    }
  2. Get the externalName of the Service Class of the registered service.

    Click to copy
    kubectl -n production get serviceclass {SERVICE_ID} -o jsonpath='{.spec.externalName}'
  3. Create a Service Instance for the registered service.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: servicecatalog.k8s.io/v1beta1
    kind: ServiceInstance
    metadata:
    name: my-service-instance-name
    namespace: production
    spec:
    serviceClassExternalName: {EXTERNAL_NAME}
    EOF
  4. Create a lambda function that sends a request to the registered service with an additional path of /uuid. A successful response returns a UUID generated by httpbin.org. To create and register the lambda function in the production Namespace, run:

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: kubeless.io/v1beta1
    kind: Function
    metadata:
    name: my-lambda
    namespace: production
    labels:
    app: my-lambda
    spec:
    deployment:
    spec:
    template:
    metadata:
    labels:
    {APP_NAME}-{SERVICE_ID}: "true"
    spec:
    containers:
    - env:
    - name: GATEWAY_URL
    value: {APP_NAME}-{SERVICE_ID}.kyma-integration
    deps: |-
    {
    "name": "example-1",
    "version": "0.0.1",
    "dependencies": {
    "request": "^2.85.0"
    }
    }
    function: |-
    const request = require('request');
    module.exports = { main: function (event, context) {
    return new Promise((resolve, reject) => {
    const url = \`http://\${process.env.GATEWAY_URL}/uuid\`;
    const options = {
    url: url,
    };
    sendReq(url, resolve, reject)
    })
    } }
    function sendReq(url, resolve, reject) {
    request.get(url, { json: true }, (error, response, body) => {
    if(error){
    resolve(error);
    }
    resolve(response.body);
    })
    }
    function-content-type: text
    handler: handler.main
    horizontalPodAutoscaler:
    spec:
    maxReplicas: 0
    runtime: nodejs8
    service:
    ports:
    - name: http-function-port
    port: 8080
    protocol: TCP
    targetPort: 8080
    selector:
    created-by: kubeless
    function: my-lambda
    timeout: ""
    topic: http
    EOF
  5. Create a ServiceBinding and a ServiceBindingUsage to bind the Service Instance to the lambda function.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: servicecatalog.k8s.io/v1beta1
    kind: ServiceBinding
    metadata:
    labels:
    Function: my-lambda
    name: my-service-binding
    namespace: production
    spec:
    instanceRef:
    name: my-service-instance-name
    EOF
    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: servicecatalog.kyma-project.io/v1alpha1
    kind: ServiceBindingUsage
    metadata:
    labels:
    Function: my-lambda
    ServiceBinding: my-service-binding
    name: my-service-binding
    namespace: production
    spec:
    serviceBindingRef:
    name: my-service-binding
    usedBy:
    kind: function
    name: my-lambda
    EOF
  6. To expose the lambda function outside the cluster create an Api custom resource.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: gateway.kyma-project.io/v1alpha2
    kind: Api
    metadata:
    labels:
    function: my-lambda
    name: my-lambda
    namespace: production
    spec:
    authentication: []
    hostname: my-lambda-production.{CLUSTER_DOMAIN}
    service:
    name: my-lambda
    port: 8080
    EOF
  7. To verify that everything was setup correctly you can now call the lambda through https:

  • On a cluster

    Click to copy
    curl https://my-lambda-production.{CLUSTER_DOMAIN}/ -k
  • On a local deployment:

    Click to copy
    curl https://my-lambda-production.kyma.local/ -k

    A successful response returns a UUID generated by httpbin.org:

    Click to copy
    {
    "uuid": "d44cc373-b26e-4a36-9890-6418d131a285"
    }

Bind an Application to a Namespace

This guide shows you how to bind an Application to a Namespace in Kyma. To execute the binding, create an ApplicationMapping custom resource in the cluster. Follow the instructions to bind your Application to the production Namespace.

Prerequisites

  • An Application created in your cluster

Steps

  1. List all Applications bound to the production Namespace.

    Click to copy
    kubectl get em -n production
  2. Bind an Application to a Namespace. Create an ApplicationMapping custom resource and apply it to the cluster.

    Click to copy
    cat <<EOF | kubectl apply -f -
    apiVersion: applicationconnector.kyma-project.io/v1alpha1
    kind: ApplicationMapping
    metadata:
    name: {NAME_OF_APP_TO_BIND}
    namespace: production
    EOF
  3. Check if the operation succeeded. List all Namespaces to which your Application is bound.

    Click to copy
    kubectl get em --all-namespaces -o jsonpath='{range .items[?(@.metadata.name=="{NAME_OF_YOUR_APP}")]}{@.metadata.namespace}{""}{end}'

Renew a client certificate

By default, a client certificate you generate when you connect an external solution to Kyma is valid for 92 days. Follow this tutorial to renew a client certificate.

NOTE: You can only renew client certificates that are still valid. If your client certificate is expired or revoked, you must generate a new one.

  1. To renew a client certificate, use the certificate subject that matches the subject of your current certificate. To check the certificate subject, run:

    Click to copy
    openssl x509 -noout -subject -in {PATH_TO_OLD_CRT}
  2. Generate a new Certificate Signing Request (CSR) using the certificate subject you got in the previous step.

    Click to copy
    openssl req -new -sha256 -out renewal.csr -key {PATH_TO_KEY} -subj "{SUBJECT}"
  3. Send a request to the Connector Service to renew the certificate.

    Click to copy
    curl -X POST https://gateway.{DOMAIN}/v1/applications/certificates/renewals -d '{"csr":"BASE64_ENCODED_CSR"}' -k --cert {PATH_TO_OLD_CRT} --key {PATH_TO_KEY}

    A successful call returns a renewed client certificate:

    Click to copy
    {
    "crt":"BASE64_ENCODED_CRT_CHAIN",
    "clientCrt":"BASE64_ENCODED_CLIENT_CRT",
    "caCrt":"BASE64_ENCODED_CA_CRT"
    }

Revoke a client certificate

You can revoke a client certificate generated for your Application. Revocation prevents a certificate from being renewed. A revoked certificate, however, continues to be valid until it expires.

To revoke a client certificate, send a request to the certificates/revocations endpoint. Pass the certificate you want to revoke and a key that matches this certificate in the call. Run:

Click to copy
curl -X POST https://gateway.{CLUSTER_DOMAIN}/v1/applications/certificates/revocations --cert {CERT_TO_REVOKE} --key {CERT_TO_REVOKE_KEY} -k

Revoke a certificate using the SHA256 fingerprint

If you have admin access to the Kyma cluster, you can revoke client certificates by sending the SHA256 fingerprint of a certificate to the internal certificates/revocations endpoint. Follow these steps:

  1. Convert the certificate from the pem format to the der format.

    Click to copy
    openssl x509 -in {CLIENT_CERT_FILE}.crt -outform der -out {CLIENT_CERT_DER_FILE}.der
  2. Get the SHA256 fingerprint of the certificate.

    Click to copy
    shasum -a 256 {CLIENT_CERT_DER_FILE}.der
  3. Revoke the certificate using the SHA256 fingerprint.

    Click to copy
    curl -X POST http://connector-service-internal-api:8080/v1/applications/certificates/revocations -d '{hash: {SHA256_FINGERPRINT_OF_CERT_TO_REVOKE_}}'

Rotate the Root certificate and the key issued by the Certificate Authority

The Central Connector Service uses the Root certificate issued by the Certificate Authority (CA) to issue new certificates for Runtimes and by the Istio Ingress Gateway to validate their identity.

Two different components use the Root CA certificate. As a result, the certificate is stored in two separate Secrets:

  • The connector-service-app-ca Connector Service CA Secret responsible for signing certificate requests
  • The application-connector-certs Istio Secret responsible for security in the Connector Service API

Keeping both Secrets up-to-date is vital for the security of your implementation as it guarantees that the Connector Service issues proper certificates and no unregistered Applications can access its API.

The Root CA certificate has a set expiration date and must be renewed periodically to prevent its expiration. You must also renew the Root CA certificate and key every time they are compromised.

This tutorial describes the procedure you must follow for these scenarios:

  • Rotating a soon-to-expire Root CA certificate
  • Rotating a compromised Root CA certificate
  • Rotating a compromised Root CA key

Rotating a soon-to-expire CA certificate

To successfully rotate a soon-to-expire CA certificate, replace it with a new certificate in both the Connector Service CA Secret and the Istio Secret. Follow these steps to replace the old certificate in both Secrets:

  1. Get the existing Root CA key. Fetch it from the connector-service-app-ca Secret and save it to the ca.key file.

    Click to copy
    kubectl -n kyma-integration get secret connector-service-app-ca -o=jsonpath='{.data.ca\.key}' | base64 --decode > ca.key
  2. Generate a new certificate for the key you obtained and save it to the new-ca.crt file.

    Click to copy
    openssl req -new -key ca.key -x509 -sha256 -days {TTL_DAYS} -nodes -out new-ca.crt

    NOTE: Use the -days flag to set the TTL (Time to live) of the newly generated certificate.

  3. Encode the newly created certificate with base64.

    Click to copy
    cat new-ca.crt | base64
  4. Replace the old certificate in the Connector Service CA Secret. Edit the Secret and replace the ca.crt value with the new base64-encoded certificate.

    Click to copy
    kubectl -n kyma-integration edit secret connector-service-app-ca
  5. Get the existing Istio CA certificate. Fetch it from the application-connector-certs Secret and save it to the old-ca.crt file.

    Click to copy
    kubectl -n istio-system get secret application-connector-certs -o=jsonpath='{.data.ca\.crt}' | base64 --decode > old-ca.crt
  6. Merge the old Nginx certificate and the newly generated certificate into a single nginx-ca.crt file.

    Click to copy
    cat old-ca.crt new-ca.crt > merged-ca.crt
  7. Encode the newly created merged-ca.crt certificate file with base64.

    Click to copy
    cat merged-ca.crt | base64
  8. Replace the old certificate in the Istio Secret. Edit the Secret and replace the ca.crt value with the merged-ca.crt base64-encoded certificate.

    Click to copy
    kubectl -n istio-system edit secret application-connector-certs
  9. Renew the certificates in a Runtime. To do that, create a CertificateRequest custom resource (CR) in the Runtime in which you want to renew the certificates. Alternatively, wait for the certificates to expire in a given Runtime. The system renews the certificates automatically using the information stored in the Secrets you updated.

  10. After the certificates are renewed in a Runtime, remove the application-connector-certs Secret entry which contains the old certificate. First, encode the new-ca.crt file with base64.

    Click to copy
    cat new-ca.crt | base64
  11. Edit the Secret and replace the ca.crt value with the new-ca.crt base64-encoded certificate.

    Click to copy
    kubectl -n istio-system edit secret application-connector-certs

Rotating a compromised Root CA certificate

  1. Get the existing Root CA key. Fetch it from the connector-service-app-ca Secret and save it to a ca.key file.

    Click to copy
    kubectl -n kyma-integration get secret connector-service-app-ca -o=jsonpath='{.data.ca\.key}' | base64 --decode > ca.key
  2. Generate a new certificate for the key you obtained and save it to the new-ca.crt file.

    Click to copy
    openssl req -new -key ca.key -x509 -sha256 -days {TTL_DAYS} -nodes -out new-ca.crt

    NOTE: Use the -days flag to set the TTL (Time to live) of the newly generated certificate.

  3. Encode the newly created certificate with base64.

    Click to copy
    cat new-ca.crt | base64
  4. Replace the old certificate in the Connector Service CA Secret. Edit the Secret and replace the ca.crt value with the new base64-encoded certificate.

    Click to copy
    kubectl -n kyma-integration edit secret connector-service-app-ca
  5. Replace the old certificate in the Istio Secret. Edit the Secret and replace the ca.crt value with the new base64-encoded certificate.

    Click to copy
    kubectl -n istio-system edit secret application-connector-certs
  6. Generate new certificates in a Runtime. To do that, create a CertificateRequest custom resource (CR) in the Runtime in which you want to generate the certificates.

Rotating a compromised Root CA key

  1. Generate a new RSA-encoded root CA key and save it to the new-ca.key file.

    Click to copy
    openssl genrsa -out new-ca.key 4096
  2. Generate a new certificate using the key you generated and save it to the new-ca.crt file.

    Click to copy
    openssl req -new -key new-ca.key -x509 -sha256 -days {EXPIRATION_DAYS} -nodes -out new-ca.crt

    NOTE: Use the -days flag to set the TTL (Time to Live) of the newly generated certificate.

  3. Encode the newly created certificate and key with base64:

    Click to copy
    cat new-ca.crt | base64
    Click to copy
    cat new-ca.key | base64
  4. Replace the old certificate and key in the Connector Service CA Secret. Edit the Secret and replace the ca.crt and ca.key values with the new base64-encoded certificate and key respectively.

    Click to copy
    kubectl -n kyma-integration edit secret connector-service-app-ca
  5. Replace the old certificate in the Istio Secret. Edit the Secret and replace the ca.crt value with the new base64-encoded certificate.

    Click to copy
    kubectl -n istio-system edit secret application-connector-certs
  6. Generate new certificates in a Runtime. To do that, create a CertificateRequest custom resource (CR) in the Runtime in which you want to generate the certificates.

API

Connector Service

The Connector Service exposes two separate APIs:

  • An internal API available in the Kyma cluster used to initiate certificate generation.
  • An external API exposed through Ingress used to finalize certificate generation.

Find the specification of both of these APIs here.

Alternatively, get the API specification directly from the Connector Service:

Click to copy
https://connector-service.{CLUSTER_DOMAIN}/v1/api.yaml

Run this command to access the API specification on a local Kyma deployment:

Click to copy
curl https://connector-service.kyma.local/v1/api.yaml

Application Registry

You can get the API specification of the Application Registry for a given version of the service using this command:

Click to copy
curl https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/metadata/api.yaml

TIP: For details on the Application Registry API specification, see this file.

Event Service

The Event Service provides an endpoint for fetching subscribed events for the Application. To fetch all of them, make a call:

Click to copy
curl https://gateway.{CLUSTER_DOMAIN}/{APP_NAME}/v1/events/subscribed -k --cert {APP_CERT} --key {APP_CERTS_KEY}

The successful call returns a list of all active events for the Application.

TIP: For details on the Event Service API specification, see this file.

Troubleshooting

Overview

The troubleshooting section aims to identify the most common recurring problems with the Application Connector, as well as the most suitable solutions to these problems.

If you cannot find a solution to your problem, do not hesitate to create a GitHub issue or reach out to the #application-connector Slack channel to get direct support from the community.

Error when calling a registered service

If you call a registered service and receive an error, follow these steps to detect the source of the problem:

  1. Check the logs.

    Check the logs from the Application Gateway Pod to verify that the call reached the Application Gateway. To fetch these logs, run this command:

    Click to copy
    kubectl -n kyma-integration logs -l app={APP_NAME}-application-gateway -c {APP_NAME}-application-gateway

    The request that reached the Pod is logged by the Application Gateway.

  2. Check for the Access Service.

    If the call you tried to make is not in the logs, check if the Access Service for the service you are trying to call exists.

    Click to copy
    kubectl -n kyma-integration get svc {APP_NAME}-{SERVICE_ID}
  3. Re-register the service.

    If the Access Service does not exist, deregister the service you tried to call.

    • With a trusted certificate
    • Without a trusted certificate

    Then, register the service and try calling again. Registering the service again recreates the Access Service. To register a service, see this tutorial.

  1. Check the API URL.

    If your call reaches the Application Gateway and the Access Service exists, but you still receive an error, check if the API URL in the service definition matches the API URL of the actual service you are trying to call. To check the target URL of the API, fetch the Service definition from the Application Registry:

    • With a trusted certificate
    • Without a trusted certificate

    A successful call returns a json response with the service definition that contains the target URL. Call the target URL directly to verify that the value of api.targetUrl is correct.

If you try to access the Application Registry without a client certificate, you get this error:

Click to copy
error:1401E410:SSL routines:CONNECT_CR_FINISHED:sslv3 alert handshake failure

To access the Application Registry, you need to pass a client certificate with the HTTP request.
To generate a client certificate, see this tutorial.

If you try to access the Application Registry using an expired client certificate, you get this error:

Click to copy
error:1401E415:SSL routines:CONNECT_CR_FINISHED:sslv3 alert certificate expired

To access the Application Registry, you need to pass a valid client certificate with the request.
To generate a new client certificate, see this tutorial.

If you try to access Application Registry with the wrong certificate, you get this error:

Click to copy
{"code":403,"error":"No valid subject found"}

Make sure that your certificate is generated for the Application that you are trying to access.
To get the certificate subject, run:

Click to copy
openssl req -noout -subject -in {PATH_TO_CSR_FILE}

You get the certificate subject as a response:

Click to copy
subject=/OU=OrgUnit/O=Organization/L=Waldorf/ST=Waldorf/C=DE/CN={APPLICATION_NAME}

Check that the common name CN matches the name of your Application.
If it does not, generate a new certificate for your Application.

To generate a new client certificate, see this tutorial.

Errors when generating or renewing a certificate

Invalid Certificate Signing Request (CSR)

If you try to generate a client certificate, you may get this error:

Click to copy
{
"code":403,
"error":"CSR: Invalid common name provided."
}

This error is caused by applying wrong subject information to your Certificate Signing Request.
To ensure CSR was generated properly, check the values returned by the Connector Service with the call that fetched the CSR information:

Click to copy
{
...
"certificate":{
"subject":"O=Organization,OU=OrgUnit,L=Waldorf,ST=Waldorf,C=DE,CN=CNAME",
"extensions":"",
"key-algorithm":"rsa2048"
}
}

Subject values present in the CSR should match the subject in the response that you got.

To check the subject of the generated CSR, run this command:

Click to copy
openssl req -noout -subject -in {PATH_TO_CSR_FILE}