API management

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

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

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)

All files used in this tutorial are available at github:

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 * 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 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 *

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 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

Problems, which you may encounter:

  • Wrong certificate: Check ingress-gateway console-logs if it failed to load your certificate

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

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. and

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

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 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.

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):

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

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 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 (, 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 (, 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"


Test the API

Go to:

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.