Gravitee.io API management

Thomas Scherer
11 min readApr 4, 2021

This tutorial continues on my previous one to prepare a .NET 5.0 webapi for Kubernetes deployment:

It is part of a multi-series tutorial for full stack development using .NET 5.0 for API development, Gravitee for API management and React for frontend development:

Topic here, will be to release the previously build webapi on a Kubernetes cluster, and managing public access to the webapi using API management. I am a fan of gravitee.io.

I find its feature set just amazing and it is open source. Thanks to Gravitee, at the end of the tutorial series, we’ll have all pieces together, such as token based access control to the API, subscription management, documentation as well as OAuth2 and OIDC based user access for API frontend applications with API level granular access control. Only challenge is probably the documentation, but it’s obviously related to the fast paced feature augmentation. Nonetheless the quickstarts on above webpage are a useful start to get things going. Anyhow, this gives this tutorial reason to be written.

In this part of the series, we will:

  • Deploy the API manager on Kubernetes
  • Use the API of previous tutorial (or any other) released via the API management
  • Add token based access control to the API
  • Obtain Swagger based documentation to test the secured API

What you will need to run this tutorial

You will need:

  • An internet accessible Kubernetes cluster onto which you can run kubectl commands (e.g. from the usual public cloud providers)
  • A domain name to be used in this tutorial and possibility to add subdomains
  • A wildcard public-private kay pair or one for each subdomain to activate https for deployed services and APIs
  • We need helm to deploy the API manager over CLI on the same host as you use for kubectl commands

All files used in this tutorial are available at github:

https://github.com/TomSearcher/graviteeio_on_kubernetes

So, let’s get started :-).

Deploy Ingress gateway and preflight check of API to be published

Now we will install an ingress gateway. This Kubernetes functionality acts as reverse proxy towards our services, within the cluster. Also it will do ssl offloading, such that we can use https towards external world. Ingress gateway installations may differ relative to your Kubernetes environment. Here, I am using ingress-nginx, which should work for most cases. I am using it on Google Kubernetes Engine, where it works like a charm. Deploying it, will automatically associate a public IP to the gateway, towards which you then need to configure your domain name(s), which you define later on. Here I assume you use *.yourdomain.net including wildcard ssl certificate.

We will use https to expose our API and the webpages, which come with Gravitee. So, first we need to install the key material for our domain, which we will use, into our cluster. Here is an example file:

You need to alter tls.crt and tls.key to your certificate and key, respectively. Then you can deploy

kubectl apply -f api-custom-cert.yaml

This will install the certificate into the DEFAULT namespace in the cluster. Now we can use helm to deploy the ingress gateway:

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo updatehelm install ingress-nginx  ingress-nginx/ingress-nginx --set controller.extraArgs.default-ssl-certificate=default/api-custom-cert

One conceptional thing:

Here, we deploy the certificate as default ssl certificate. So, this certificate will be used for any https traffic arriving at the ingress gateway, if there’s no other certificate defined for a specific forwarding rule. So, this makes sense for a wildcard certificate as we use here. if you go for specific certificates for subdomains, then those will be installed together with the forwarding rule definition.

The certificate is deployed as a “Secret” into the DEFAULT namespace. Secrets are not accessible from foreign namespaces. So gateway and secret have to be in the same namespace. Forwarding rules may be in different namespaces as the ingress gateway (of course). If they should use specific certificates then you must install the respective secret in the same namespace as the forwarding rule (which is not necessarily the same as the gateway’s namespace).

By now, you should have a public IP to which the ingress gateway is associated. Configure DNS to point to this public IP (here *.mydomain.net).

Now it’s time to test if ingress, DNS and the API work. You may use the yaml files of previous tutorial here. Just change the DNS record in carlibraryapi-ingress.yaml to your case:

Alternatively you may test with your own API and/or alter the yaml files as needed. By default, those yaml files point to the docker image created in previous tutorial.

kubectl create namespace carlibraryapi
kubectl apply -n carlibraryapi -f postgres.yaml
kubectl apply -n carlibraryapi -f carlibraryapi.yaml
kubectl apply -n carlibraryapi -f carlibraryapi-ingress.yaml

Those yaml files will deploy a postgres database and the API of previous tutorial (including respective service) into namespace carlibraryapi. The 4th command creates an ingress rule to forward the http traffic to the API using URL https://clapi2.yourdomain.net. As you may recognize, I commented the secretName reference, because in my case I use a wildcard certificate, which I configured as default on the gateway (above). You may now check if you can reach swagger following https://clapi2.yourdomain.net/swagger.

Problems, which you may encounter:

  • Wrong certificate: Check ingress-gateway console-logs if it failed to load your certificate
  • Timeout: Check the webapi console log if it received the http request.

Otherwise we are good to proceed. You may now delete the ingress rule again because we will access the API via the API management in future steps.

kubectl delete -n carlibraryapi -f carlibraryapi-ingress.yaml

Install Gravitee API Management

Now it is time to deploy the API manager. The functionality of the API manager goes way beyond the scope of this tutorial. Information and documentation is available at https://gravitee.io

We will follow the installation using helm, but with separate deployments for the DB and elasticsearch dependencies of the gateway. Here are sample yaml files, which you may alter as desired. https://github.com/TomSearcher/graviteeio_on_kubernetes/blob/main/graviteeio/mongodb-deployment.yaml and https://github.com/TomSearcher/graviteeio_on_kubernetes/blob/main/graviteeio/elasticsearch-deployment.yaml.

Let’s create a namespace for the API manager and deploy those there:

kubectl create namespace apim
kubectl apply -n apim -f elasticsearch-deployment.yaml
kubectl apply -n apim -f mongodb-deployment.yaml

Next, we need to get the helm repository for Gravitee

helm repo add graviteeio https://helm.gravitee.io

Now, we need to fetch the configuration values to prepare the deployment to our environment

helm show values graviteeio/apim3 > apim.yaml

There are quite some configuration possibilities, but just a few mandatory ones. You may compare with https://github.com/TomSearcher/graviteeio_on_kubernetes/blob/main/graviteeio/apim.yaml. Line references refer to that file:

  • Change adminPasswordBcrypt (Line 16). Use bcrypt ($2a$ version) to generate a new one, e.g. using htpasswd:
htpasswd -bnBC 10 "" mysuperduperpassword| tr -d ':\n' | sed 's/$2y/$2a/'
  • Change jwtSecret (Line 21) to anything you like.
  • Change passwords (Line 215 and 386)
  • Change all “hosts” entries to your domain with a dedicated subdomain (e.g. api.yourdomain.com)
  • Disable secretName entries if you use the default certificate of the ingress gateway. Otherwise specify the ssl certificate there
  • Change DB parameters inline to your DB deployment above in section “mongo:” (Line 68). The settings on the github yaml files correspond
  • Disable DB deployment by setting key “enabled” of mongodb-replicaset (Line 186) to false
  • Set the elasticsearch url to previous elasticsearch deployment (Line 141) by altering the endpoints parameter in the “es” section
  • Disable Elasticsearch deployment by setting key “enabled” of eleasticsearch section (Line 143) to false
  • Change API key name to a name you like such as “X-MyDomain-Api-Key” (Line 443 and 613). This is the header key, which is later used to carry the token when contacting the API.
  • If you wish to keep the deployment small change all replica values (various names like maxreplicas, replicacount,…) to 1.

Save all changes and deploy Gravitee:

helm install apim --namespace apim -f apim.yaml graviteeio/apim3

It will take a moment until everything is deployed.

Complete global Gravitee configuration

After the deployment is complete, you may reach the configuration portal following (with “/” after console):

https://above-subdomain.yourdomain.net/console/.

Go to Settings>Settings and change “Company name” to something, which suits you. Scroll down to API Key Header and change it to your previous yaml configured header name.

Go to Settings > Sharding Tags. Change the URL in Default configuration to your case https://above-subdomain.yourdomain.net

This completes the basic configuration.

Configure an API

Now it’s time to setup access to the API. First we need to register it. Go to the API section and press the plus button.

Now you have two options. Either to create the registration manually or to import an Open API specification. The latter has the advantage that it will autogenerate path rules, which can later be used for swagger and path based access restrictions, if one desires doing so. With our webapi we received this for free via .NET 5.0 webapi in previous tutorial, and it’s already accessible by http within the Kubernetes cluster. So we will make use of this by pressing the “Import” button. You may refer to Gravitee.io quickstart if you prefer creating from scratch.

We may use “Import from link” and put the URL suitable to parameters set in the webapi deployment above (https://github.com/TomSearcher/graviteeio_on_kubernetes/blob/main/carlibraryapi/carlibraryapi.yaml), i.e. http://<service name>.<namespace>:<port>/swagger/v1/swagger.js

Click “Create policies on paths”, since in later tutorials we will grant users different access rights.

This will finish the registration of the API. Now go to Proxy>Entrypoints. Here you configure the external URL of the API. You MUST add the path rule of the helm configuration for the gateway if it was different from “/”. In above configuration it was /gateway. behind you append a path, which you deem reasonable in naming.

Go to Proxy>Endpoints. Here we configure the backend URL of the API in the Kubernetes cluster.

So, click the configure icon and set the URL as in the webapi service definition (https://github.com/TomSearcher/graviteeio_on_kubernetes/blob/main/carlibraryapi/carlibraryapi.yaml), i.e. http://<service name>.<namespace>:<port>.

Now we may “click deploy API”. Go to Portal>Details. You may start and publish the API there.

Next thing to create is a plan for using this API, i.e. we will define a way to obtain access to the API. Here, we will grant access via API keys. In next tutorial, we will add a plan for OAuth2 to gain access to the API upon user login. Click Portal > Plans:

Click the plus button and follow instructions.

Here we specify API Key usage:

Click the small blue cloud in the plan to publish it. Additionally Deploy the API.

Finally we need to create an application to consume the plan. Applications consolidate access to APIs and link them to external identity services (Client ID) if needed (not here, later yes). Follow the instructions on screen and screenshots below:

Click “Create the Application”. Now we can actually already start using the API using an API key. But before we will update documentation of the API to include swagger for testing the API — otherwise one may use simply postman. Go to Portal->Pages .

click “Swagger”. This will bring us to the swagger, which was imported before. We need to add the usage of API keys to this specification so that we can test the API right from the portal. First go to configuration. Scroll down to bottom and click “Remove External Source Configuration”, such that we can edit the openapi definition.

Tick checkboxes as in below screenshots and save:

Go to the “Page” tab. Now we need to add API key usage into the openapi specification.

Add a new main section: “security” as shown in below image:

"security" : [ {
"ApiKeyAuth" : [ ]
} ],

Add a subsection into the “components” section to specify the header key as in the helm configuration file.

"securitySchemes" : {
"ApiKeyAuth" : {
"type" : "apiKey",
"name" : "X-YourDomain-Api-Key",
"in" : "header"
}
}

WE ARE FINISHED.

Test the API

Go to: https://above-subdomain.yourdomain.net

Visit Applications > Subscriptions and select your subscription.

Click the green arrow symbol. It will get you to your API key. Copy it.

Then go to Catalog -> All APIs -> View API.

This will bring you to the previously defined Swagger. Click Authorize, paste the API key in there. Test the API usage via the API functions displayed underneath.

--

--