blog

Managing Kalix APIs with Apigee

Alan Klikić.
Senior Solution Architect, Lightbend.
  • 22 August 2022,
  • 7 minute read

Introduction.

Kalix is a developer PaaS that enables any developer to build large-scale and high performant backend APIs with no operations required. With a very simple API first and polyglot development model, Kalix allows developers to only focus on implementing the API business logic.

Externalizing these kinds of backend APIs to third-party consumers (one to many) for a system to system integration, in some use cases, requires some additional features on top of standard internal API consumption requirements.

These additional API features are commonly called API Gateway features. These features cover:

  • Security (token, JWT, mTLS,...)
  • Rate limits
  • Quota
  • Monetization
  • Security
  • Analytics and Monitoring

One of those use cases is "API as a Product". API as a Product is a type of SaaS (Software as a Service) where the API is not just the delivery mode but also the product itself. Some of the examples of API as a Product are payment gateway API, geolocation API, ...

Kalix focus is on implementing the backend API business logic and also supports securing the APIs with JWT and mTLS. But it does not support all other API Gateway features that could be required for externalizing the API. There are many software products that focus on providing dedicated API Gateway features for facading backend API.

This article will showcase how Google Apigee cloud service can be used to facade Kalix API with required API gateway features.

Google Apigee is a platform for full lifecycle management of APIs. By fronting services with a proxy layer, Apigee provides an abstraction or facade for backend service APIs and provides security, rate limiting, quotas, analytics and more.

Example use case: eCommerce shopping cart API

Shopping Cart, one of Kalix’s quickstart projects, is a simple example of an API for managing a shopping cart.

Architecture

Managing Kalix APIs with Apigee

Kalix is used to implement shopping cart business logic and expose it with secure access via mTLS.

Apigee is faceding Kalix API to provide rich API gateway features mentioned above.

Kalix - Shopping cart service

Shopping cart service exposes functionality via GRPC and HTTP/REST endpoints. Currently Apigee does not support GRPC so we will use HTTP/REST endpoints:

POST /cart/{cart_id}/add
POST /cart/{cart_id}/remove
GET /carts/{cart_id}

Follow the instructions here on how to build, deploy and run the Shopping cart service on Kalix.

When the Shopping service is deployed on Kalix it needs to be exposed to the Internet using routes.

These routes need to provide secure and limited access only to the consumers that are authorized to use it (in this case Apigee API Gateway). To be able to achieve that, routes can be secured using Kalix client certificate/mTLS support.

mTLS (Mutual TLS) requires consumers to authenticate using a client certificate. A server verifies a client certificate by validating the client certificate issuer (Certificate authority or CA). Kalix provides secret management for managing secrets in a secure manner. It is a requirement to store CA certificates using secret management.

For exposing service via mTLS secure route, a CA certificate secret needs to be provided.

For simplicity reasons all certificates and keys will be created manually using small step CLI (openssl can also be used).

Creating CA certificate and key:

step certificate create --profile root-ca "My Root" my-root-ca.crt my-root-ca.key --insecure --no-password

Create Kalix secret for CA certificate:

kalix secret create tls-ca my-root-ca --cert my-root-ca.crt

Before adding a route you need to specify a hostname. Kalix allows you to provision a generated or a custom hostname.

Provision generated hostname:

kalix project hostname add

HOSTNAME                               GENERATED   REGION         CNAME
hidden-voice-4974.us-east1.kalix.app   true        gcp-us-east1

Create Kalix mtls route:

kalix route create shopping-cart-mtl --hostname hidden-voice-4974.us-east1.kalix.app  --path /=shopping-cart --client-ca-secret my-root-ca

Note: Replace hostname with your own host.

Verify access WITHOUT providing client certificate:

curl -XGET https://hidden-voice-4974.us-east1.kalix.app/carts/1 -H "Content-Type: application/json"

curl: (56) LibreSSL SSL_read: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0

Create client certificate and key:

step certificate create  "Shopping Cart Client" shopping-cart-client.crt shopping-cart-client.key --ca my-root-ca.crt --ca-key my-root-ca.key --insecure --no-password --not-after=8760h

Verify access WITH providing client certificate:

curl -XGET https://hidden-voice-4974.us-east1.kalix.app/carts/1 -H "Content-Type: application/json" --cacert lightbend-gsa-root-ca.crt --key shopping-cart-client.key --cert shopping-cart-client.crt

{"items":[]}%

Now Shopping cart service is exposed to the Internet and accessible only to consumers that provide shopping-cart-client client certificates.

Apigee

Organization provisioning

To start with Apigee, the Apigee organization needs to be provisioned.

Note: prepare domain and TLS/SSL server certificate that will be used for frontend facing API.

API Proxy

When an Apigee organization is provisioned, an API proxy needs to be created in the Apigee console. API proxy is used to decouple frontend API and backend API. API proxy defines requirements for frontend API (like authorization, quota, ...) and defines configuration for accessing backend API (target).

The target is Kalix Shopping cart service mTLS endpoint.

mTLS

For configuring access to Kalix Shopping cart service, in API proxy, mTLS client certificate needs to be stored in the Apigee TLS Keystore (Admin -> Environments -> TLS Keystores):

  • +Keystore
  • Keystore name: shopping-cart-client
  • Add Keystore
  • When keystore is created select it do Add alias (+ icon)
  • Alias name: shopping-cart-api
  • Type: Certificate with Key
  • Choose Certificate File: shopping-cart-client.crt
  • Key Password: leave empty
  • Choose Key File: shopping-cart-client.key

After TLS Keystore is created, Apigee Reference needs to be created (Admin -> Environments -> References):

  • +Reference
  • Name: shopping-cart-client-mtls
  • Choose shopping-cart-client from the Reference list.

Open API specs

API proxy can be created using Open API specification. Kalix uses protobuf for endpoint description (shopping_cart_api.proto).

For now, Kalix does not support conversion from protobuf to Open API but this can be manually done using Google’s Gnostic tool.

Note: To generate Open API specification from shopping_cart_api proto file, the file needs to be stripped of Kalix annotations (kalix.field,kalix.codegen, kalix.service). Also go_package will need to be added for next step:

option go_package="shopping.cart.api"

Also google api protobuf definitions need to be cloned from here.

protoc shopping_cart_api.proto -I. -I<folder_for_cloned_googleapis>/googleapis --=.

Output OpenAPI specification will be stored in openapi.yaml.

API Proxy

  • Develop -> Proxies
  • CREATE NEW
  • Choose Use OpenAPI Spec (link in Reverse proxy option)
  • File tab
  • Choose openapi.yaml file
  • Note: if there is an error that Open API version is not supported just change the version to the max supported one in openapi.yaml
  • Proxy details:
    • Name: ShoppingCart-API
    • Base path: /shoppingcart-api
    • Target (Existing API): use the HTTPS URL with Kalix Shopping cart service hostname
  • Select common policies:
    • Security: Authorization - API Key
    • Quota - impose quotas per App

Configuring mTLS support for the API Proxy target

After API Proxy was created:

  • Edit API Proxy
  • DEVELOP tab
  • Select Target Endpoints - PostFix
  • add SSLInfo in HTTPTargetConnection:
<HTTPTargetConnection>
<URL>https://hidden-voice-4974.us-east1.kalix.app</URL>
<SSLInfo>
  <Enabled>true</Enabled>
  <ClientAuthEnabled>true</ClientAuthEnabled>
  <KeyStore>ref://shopping-cart-client-mtls</KeyStore>
  <KeyAlias>shopping-cart-api</KeyAlias>
  <IgnoreValidationErrors>false</IgnoreValidationErrors>
</SSLInfo>
</HTTPTargetConnection>

Note: Keystore is using the Apigee reference for TLS keystore. KeyAlias is Alias configured when adding the TLS Keystore.

Save changes

In the OVERVIEW tab in Deployments choose the last Revision number and deploy.

Publishing API as a Product

Using Apigee publishing, API Proxy can be exposed via multiple products. Each product defines frontend API configuration like exact quota and/or which API Proxy operations are permitted.

Product consumers can be configured as App or Portal.

API Product

Create an API Product (Publishing - API Products) by setting:

  • Name
  • Displayname
  • choose Environment
  • Access = Public
  • define Quota
    • example: 5 per minute
  • add operations
    • choose ShoppingCart-API API Proxy
    • Path = /
    • Methods: GET, POST

Developers

To be able to create an App or Portal consumer, a Developer (Publishing -> Developer) needs to be created. Developer is the consumer source owner.

Apps

Apps represents API product consumers and identifies itself with API key that is generated on its creation.

Verify

apiKey query parameters can be copied from Apps.

curl -XGET -H "Content-Type: application/json" 'https://apigee.lightbend.solutions/shoppingcart-api/carts/1?apikey=h4B2JbPqQHnV8mUqobnbzWuQEybaOUAw6yRZIgbjuTnpndCa'

{"items":[]}%

Conclusion

Kalix provides an API-first development model that simplifies implementation of business logic by increasing development productivity and decreases time to value. mTLS support provides secure and authorized access.

Apigee decouples frontend API usage and allows Kalix implementation to focus on business logic where frontend API can utilize all the benefits of Apigee API gateway.

Kalix and Apigee symbiosis provides a very nice serverless solution for use cases where API requires API gateway.

Author Section will go here