<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Julia Salem</title>
    <description>The latest articles on Forem by Julia Salem (@jsal570).</description>
    <link>https://forem.com/jsal570</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F597029%2Fc1012de9-e00c-4002-a7a4-eb8984e38bbc.jpeg</url>
      <title>Forem: Julia Salem</title>
      <link>https://forem.com/jsal570</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jsal570"/>
    <language>en</language>
    <item>
      <title>Implementing Traffic Policies in Kubernetes</title>
      <dc:creator>Julia Salem</dc:creator>
      <pubDate>Wed, 30 Jun 2021 15:45:26 +0000</pubDate>
      <link>https://forem.com/jsal570/implementing-traffic-policies-in-kubernetes-ie3</link>
      <guid>https://forem.com/jsal570/implementing-traffic-policies-in-kubernetes-ie3</guid>
      <description>&lt;p&gt;When setting up Kubernetes for the first time, one of the networking challenges you might face is how to safely grant outside clients access to your cluster. By default, pods within a cluster can communicate with all other pods and services. You should restrict access to anything outside of that group. &lt;/p&gt;

&lt;p&gt;In this post, we’ll take a closer look at how to introduce a process for monitoring and observing Kubernetes traffic using &lt;a href="https://kuma.io/"&gt;Kuma&lt;/a&gt;, a modern distributed control plane with a bundled Envoy Proxy integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up a Kuma Service Mesh
&lt;/h2&gt;

&lt;p&gt;Application stacks that run as individual containers need to communicate with one another and outside clients. To coordinate between all the requirements necessary to support such platforms—including security, routing and load-balancing—the concept of a &lt;strong&gt;service mesh&lt;/strong&gt; emerged. The goal of a service mesh is to provide seamless management of any service on the network. Thus, while an ingress controller handles the behavior of incoming traffic, a service mesh is responsible for overseeing &lt;em&gt;all&lt;/em&gt; aspects of the network, such as monitoring and configuration of the network.&lt;/p&gt;

&lt;p&gt;Kuma is one example of a service mesh. It’s an open source project that works across various environments, including Kubernetes and virtual machines, and supports multi-zone deployments. Kuma is supported by the same team that built &lt;a href="https://github.com/Kong/kong"&gt;Kong&lt;/a&gt;, a popular API gateway that simplifies network communication. Kong has a vast plugin ecosystem that enables you to easily deploy and manage HTTP requests, responses and routes across your entire fleet. Kuma works hand-in-hand with Kong, but the two projects don’t rely on each other, as we’ll see below. &lt;/p&gt;

&lt;p&gt;In addition to providing fine-grained traffic control capabilities, Kuma also offers rapid metrics and observability analyses. Being able to secure your networking access is only part of the solution. Since Kuma integrates with &lt;a href="https://prometheus.io/"&gt;Prometheus&lt;/a&gt; for native data collection and &lt;a href="https://grafana.com/"&gt;Grafana&lt;/a&gt; for charting and viewing that data, you’ll be able to see precisely how your load balancing and client routing are behaving.&lt;/p&gt;

&lt;p&gt;Installing Kuma is a snap. First, you can download and run the installer like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -L https://kuma.io/installer.sh | sh -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, switch to the installation directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd kuma-1.1.2/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, you can run Kuma in multi-zone mode or standalone mode if Kuma is just in a single Kubernetes cluster. The command below will deploy Kuma in a single zone configuration, the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./kumactl install control-plane | kubectl apply -f -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For other environments, check out &lt;a href="https://kuma.io/docs/1.1.2/documentation/deployments/"&gt;the docs on deployment&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are several ways to interact with Kuma. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read-only through its &lt;a href="https://kuma.io/docs/1.1.4/documentation/gui/#getting-started"&gt;GUI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;For write/edit access –&lt;a href="https://kuma.io/docs/1.1.4/policies/introduction/"&gt;kubectl&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kuma.io/docs/1.1.4/documentation/http-api/#pagination"&gt;API&lt;/a&gt; (note that in a Kubernetes deployment, the API is also read-only, and interactions via kubectl are the correct process.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To access the GUI, you’ll first need to forward the API service port:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ kubectl port-forward svc/kuma-control-plane -n kuma-system 5681:5681
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, you can navigate to &lt;a href="http://127.0.0.1:5681/gui"&gt;http://127.0.0.1:5681/gui&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  CNI Compatibility
&lt;/h2&gt;

&lt;p&gt;Before continuing, it’s important to introduce a minor point about configuration, which has major implications. &lt;/p&gt;

&lt;p&gt;Kubernetes uses &lt;a href="https://github.com/containernetworking/cni"&gt;the Container Network Interface (CNI) standard&lt;/a&gt; to configure networking for containers. This means that no matter how you design a CNI-compatible tool, it ought to be able to rely on the same set of protocols. Kubernetes provides an API that an ingress controller can use to set and manage the network policies. Multiple CNI-based projects have sprung up in response to enterprise-grade security and ease of use requirements. For example, one such project is &lt;a href="https://www.projectcalico.org/"&gt;Calico&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Depending on your needs, opting for a more customizable service mesh, like Kuma, can help you achieve your specific goals. For example, although Calico adheres to the &lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/"&gt;Network Policies&lt;/a&gt; Kubernetes provides, &lt;a href="https://docs.projectcalico.org/security/service-accounts"&gt;its format for setting up traffic rules&lt;/a&gt; is more opaque than Kuma. Kuma provides a way of configuring &lt;a href="https://kuma.io/policies/"&gt;network&lt;/a&gt; policies that run parallel to the first-class API Kubernetes provides. It should come as no surprise that Kuma is also compatible with CNI. This means you can easily swap out any network policies defined by Calico—or any project that uses a CNI-based protocol for Kuma’s traffic rules. The main differentiator between such projects comes down to features. Kuma, for example, can act as a service mesh, an observability platform &lt;em&gt;and&lt;/em&gt; a network policy manager all in one. Other projects may have different priorities, and it is the developer’s responsibility to make sure they can all interact with one another properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecting Traffic Policies in Kubernetes with Kuma
&lt;/h2&gt;

&lt;p&gt;With Kuma set up and running on Kubernetes, let’s see how to establish traffic rules to manage incoming access.&lt;/p&gt;

&lt;p&gt;Imagine the following scenario: an eCommerce platform that relies on two microservices that communicate to meet the business’s needs—let’s call them services backend1 and backend2. A third microservice acts as a public API, and any incoming request to this service privately queries the other two. We’d like to expose the API to the public but keep the other two microservices isolated from external networks.&lt;/p&gt;

&lt;p&gt;The pure ingress way to do this is to set up a &lt;a href="https://kubernetes.io/docs/concepts/services-networking/network-policies/"&gt;Network Policy&lt;/a&gt;. However, Kuma drastically simplifies this process with an easy-to-understand YAML DSL. You can define &lt;a href="https://kuma.io/docs/1.1.4/policies/traffic-permissions/"&gt;Traffic Permission policies&lt;/a&gt; that explicitly identify which sources the services can communicate specific destination services.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | kumactl apply -f - 
type: TrafficPermission
name: api-to-backends
mesh: default
sources:
  - match:
      service: 'publicAPI'
destinations:
  - match:
      service: 'backend1'
  - match:
      service: 'backend2'
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this manifest, the Traffic Permission policy gives the frontend permission to send traffic to the backend. The policy will reject any other source.&lt;/p&gt;

&lt;p&gt;Traffic Permission is just one of the policies that Kuma provides. Among other features, you can also set up a &lt;a href="https://kuma.io/docs/1.1.4/policies/health-check/#usage"&gt;Health Check policy&lt;/a&gt; to keep track of the health of every data plane proxy. This, too, makes use of familiar source and destination matches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | kumactl apply -f -
apiVersion: kuma.io/v1alpha1
kind: HealthCheck
mesh: default
metadata:
  name: web-to-backend-check
spec:
  sources:
  - match:
      service: 'publicAPI'
  destinations:
  - match:
      service: 'backend1'
  - match:
      service: 'backend2'
  conf:
    interval: 10s
    timeout: 2s
    unhealthyThreshold: 3
    healthyThreshold: 1
    tcp:
      send: Zm9v
      receive:
      - YmFy
      - YmF6
EOF
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  One Control Plane for Security, Observability and Routing
&lt;/h2&gt;

&lt;p&gt;The goal of any service mesh is to provide a single location to configure how your network behaves across your entire cluster. A service mesh can simplify much of the communication across disparate services. It’s often better to opt for a more restrictive network security rather than one which is open to any connection. Implementing a &lt;a href="https://kuma.io/docs/1.1.6/policies/mutual-tls/"&gt;zero-trust security policy&lt;/a&gt; with Kuma is a first-class feature, not an afterthought.&lt;/p&gt;

&lt;p&gt;If you’d like to learn more about proper access configuration, you can check out &lt;a href="https://kubernetes.io/docs/concepts/security/controlling-access/"&gt;the Kubernetes documentation on controlling access&lt;/a&gt; or &lt;a href="https://kubernetes.io/docs/concepts/security/pod-security-standards/"&gt;their best practices on pod security&lt;/a&gt;. &lt;a href="https://kuma.io/docs/1.1.4/security/certificates/"&gt;Kuma’s secure access patterns&lt;/a&gt; also provide some guidelines on how to define commonly-required networking policies.&lt;/p&gt;

&lt;p&gt;I hope you found this information on traffic policies in Kubernetes helpful. Get in touch via the &lt;a href="https://kuma.io/community/"&gt;Kuma community&lt;/a&gt; or learn more about other ways you can leverage Kuma for your connectivity needs with these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/getting-started-kuma-service-mesh/"&gt;Getting Started With Kuma Service Mesh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/authorize-api-opa-kuma"&gt;Authorizing Microservice APIs With OPA and Kuma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/service-mesh-observability"&gt;Automate Service Mesh Observability With Kuma&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The post &lt;a href="https://konghq.com/blog/traffic-policies-kubernetes/"&gt;Implementing Traffic Policies in Kubernetes&lt;/a&gt; appeared first on &lt;a href="https://konghq.com"&gt;KongHQ&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>opensource</category>
      <category>servicemesh</category>
    </item>
    <item>
      <title>Protecting Services With API Gateway Rate Limiting</title>
      <dc:creator>Julia Salem</dc:creator>
      <pubDate>Tue, 18 May 2021 13:00:19 +0000</pubDate>
      <link>https://forem.com/kong/protecting-services-with-api-gateway-rate-limiting-413</link>
      <guid>https://forem.com/kong/protecting-services-with-api-gateway-rate-limiting-413</guid>
      <description>&lt;p&gt;The Kong Gateway Rate Limiting &lt;a href="https://docs.konghq.com/hub/kong-inc/rate-limiting/"&gt;plugin&lt;/a&gt; is one of our most popular traffic control add-ons. You can configure the plugin with a policy for what constitutes “similar requests” (requests coming from the same IP address, for example), and you can set your limits (limit to 10 requests per minute, for example). This tutorial will walk through how simple it is to enable rate limiting in your &lt;a href="https://konghq.com/kong/"&gt;Kong Gateway&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rate Limiting: Protecting Your Server 101
&lt;/h2&gt;

&lt;p&gt;Let’s take a step back and go over the concept of rate limiting for those who aren’t familiar.&lt;/p&gt;

&lt;p&gt;Rate limiting is remarkably effective and ridiculously simple. It’s also regularly forgotten. Rate limiting is a defensive measure you can use to prevent your server or application from being paralyzed. By restricting the number of similar requests that can hit your server within a window of time, you ensure your server won’t be overwhelmed and debilitated.&lt;/p&gt;

&lt;p&gt;You’re not only guarding against malicious requests. Yes, you want to shut down a bot that’s trying to discover login credentials with a brute force attack. You want to stop scrapers from slurping up your content. You want to safeguard your server from DDOS attacks.&lt;/p&gt;

&lt;p&gt;But it’s also vital to limit non-malicious requests. Sometimes, it’s somebody else’s buggy code that hits your API endpoint 10 times a second rather than one time every 10 minutes. Or, perhaps only your premium users get unlimited API requests, while your free-tier users only get a hundred requests an hour.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mini-Project for Kong Gateway Rate Limiting
&lt;/h2&gt;

&lt;p&gt;In our mini-project for this article, we’re going to walk through a basic use case: Kong Gateway with the Rate Limiting plugin protecting a simple API server. Here are our steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create Node.js Express API server with a single “hello world” endpoint.&lt;/li&gt;
&lt;li&gt;Install and set up Kong Gateway.&lt;/li&gt;
&lt;li&gt;Configure Kong Gateway to sit in front of our API server.&lt;/li&gt;
&lt;li&gt;Add and configure the Rate Limiting plugin.&lt;/li&gt;
&lt;li&gt;Test our rate limiting policies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After walking through these steps together, you’ll have what you need to tailor the Rate Limiting plugin for your unique business needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want to set up rate limiting for your API gateway with clicks instead of code? &lt;a href="https://konghq.com/kong-konnect/"&gt;Try Konnect for free &amp;gt;&amp;gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Node.js Express API Server
&lt;/h2&gt;

&lt;p&gt;To get started, we’ll create a simple API server with a single endpoint that listens for a &lt;code&gt;GET&lt;/code&gt; request and responds with “hello world.” At the command line, create a project folder and initialize a Node.js application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/$ mkdir project
~/$ cd project
~/project$ yarn init
// Accept all defaults
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we’ll add Express, which is the only package we’ll need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ yarn add express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, let’s create a simple server with our “hello world” endpoint. In your project folder, create an index.js file with these contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* PATH: ~/project/index.js
*/
const express = require('express')
const server = express()
const port = 3000
server.get('/', (req, res) =&amp;gt; {
 console.log(req.headers)
 res.status(200).send('Hello world!')
})
server.listen(port, () =&amp;gt; {
 console.log(`Server is listening on http://localhost:${port}`)
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, spin up your server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your browser, you can visit &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;. Here’s what you should see:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VqB4mL8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/local-host-hello-world.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VqB4mL8I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/local-host-hello-world.png" alt="local host hello world"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s also use &lt;a href="https://insomnia.rest/"&gt;Insomnia&lt;/a&gt;, a desktop client for API testing. In Insomnia, we send a &lt;code&gt;GET&lt;/code&gt; request to &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wvvUIsX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/local-host-hello-world-insomnia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wvvUIsX1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/local-host-hello-world-insomnia.png" alt="local host hello world in Insomnia"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Node.js API server with its single endpoint is up and running. We have our &lt;code&gt;200 OK&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;Keep that terminal window with the node running. We’ll do the rest of our work in a separate terminal window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and Set Up Kong Gateway
&lt;/h2&gt;

&lt;p&gt;Next, we’ll &lt;a href="https://konghq.com/install/"&gt;install Kong Gateway&lt;/a&gt; to sit in front of our API server. These steps will vary depending on your local environment.&lt;/p&gt;

&lt;p&gt;Simple usage of the Rate Limiting plugin supports configuring Kong in DB-less mode with a declarative configuration. That means, instead of sending configurations to Kong Gateway one step at a time, with those configurations stored in a database, we can use a single declarative &lt;code&gt;.yml&lt;/code&gt; file for specifying our entire Kong configuration.&lt;/p&gt;

&lt;p&gt;After installing Kong, we generate a starter .yml file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ kong config init
~/project$ tree -L 1
.
├── index.js
├── kong.yml
├── node_modules
├── package.json
└── yarn.lock
1 directory, 4 files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll come back to that kong.yml file in a moment.&lt;/p&gt;

&lt;p&gt;Now, let’s tell Kong where to look for that declarative configuration file upon startup. In /etc/kong, there is a &lt;br&gt;
&lt;code&gt;kong.conf.default&lt;/code&gt; file that we’ll need to copy as &lt;code&gt;kong.conf&lt;/code&gt; and then edit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ cd /etc/kong
/etc/kong$ sudo su
root:/etc/kong$ cp kong.conf.default kong.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we edit the &lt;code&gt;kong.conf&lt;/code&gt; file. You’ll likely need root privileges to do this. There are two edits that we need to make:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# PATH: /etc/kong/kong.conf

# line ~839: Uncomment this line and set to off
database = off

# line ~1023, Uncomment this line. Set to absolute path to kong.yml
declarative_config = /PATH/TO/YOUR/project/kong.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure Kong Gateway With Our Service and Routes
&lt;/h2&gt;

&lt;p&gt;Before we start up Kong, let’s edit the declarative configuration file generated in our project folder. It should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# PATH: ~/project/kong.yml

_format_version: "2.1"

services:
- name: my-api-server
  url: http://localhost:3000/
  routes:
  - name: api-routes
    paths:
    - /api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s walk through what this configuration does. After setting the syntax version (2.1), we configure a new upstream service for which Kong will serve as an API gateway. Our service, which we name my-api-server, listens for requests at the URL &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;We associate a route (arbitrarily named &lt;br&gt;
&lt;code&gt;api-routes&lt;/code&gt;) for our service with the path &lt;code&gt;/api&lt;/code&gt;. Kong Gateway will listen for requests to &lt;code&gt;/api&lt;/code&gt;, and then route those requests to our API server at &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With our declarative configuration file in place, we start Kong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ sudo kong start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in Insomnia, we send a &lt;code&gt;GET&lt;/code&gt; request through Kong Gateway, which listens at &lt;a href="http://localhost:8000"&gt;http://localhost:8000&lt;/a&gt;, to the &lt;code&gt;/api&lt;/code&gt; path:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ovx9Qnh---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-get-request.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ovx9Qnh---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-get-request.png" alt="Insomnia get request"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that, by sending our request to port &lt;code&gt;8000&lt;/code&gt;, we are going &lt;em&gt;through&lt;/em&gt; Kong Gateway to get to our API server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add the Kong Gateway Rate Limiting Plugin
&lt;/h2&gt;

&lt;p&gt;Now that we have Kong Gateway sitting in front of our API server, we’ll add in the Rate Limiting Plugin and test it out. We will need to add a few lines to our &lt;code&gt;kong.yml&lt;/code&gt; declarative configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# PATH: ~/project/kong.yml

_format_version: "2.1"

services:
- name: my-api-server
  url: http://localhost:3000/
  routes:
  - name: api-routes
    paths:
    - /api
  plugins:
  - name: rate-limiting
    config:
      minute: 5
      hour: 12
      policy: local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve added the entire plugins section underneath our my-api-server service. We specify the name of the plugin, &lt;code&gt;rate-limiting&lt;/code&gt;. This name is &lt;em&gt;not&lt;/em&gt; arbitrary but refers to the actual &lt;code&gt;rate-limiting&lt;/code&gt; plugin in the Kong package.&lt;/p&gt;

&lt;p&gt;In this first run, we’ve configured the plugin with &lt;code&gt;minute: 5&lt;/code&gt;, which allows for up to five requests per minute. We’ve also added hour &lt;code&gt;: 12&lt;/code&gt;, which limits the requests per hour to 12. We’re using the local policy, which has to do with how Kong will store and increment request counts. We’ll talk about this policy configuration more below.&lt;/p&gt;

&lt;p&gt;Let’s restart Kong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ sudo kong restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, back in Insomnia, we test out sending some requests to our API endpoint. If you send a request every few seconds, you’ll see that the first five requests received a &lt;code&gt;200 OK&lt;/code&gt; response. However, if you exceed five requests within a minute:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lSvpme0r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-test-kong-rate-limiting.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lSvpme0r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-test-kong-rate-limiting.png" alt="Insomnia test Kong's rate limiting plugin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Rate Limiting plugin detects that requests have exceeded the five-per-minute rule. It doesn’t let the subsequent request through to the API server. Instead, we get a &lt;code&gt;429 Too Many Requests&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;Our plugin works!&lt;/p&gt;

&lt;p&gt;If you wait a minute and then try your requests again, you’ll see that you can get another five successful requests until Kong blocks you again with another &lt;code&gt;429&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point, we’ve sent 10 requests over several minutes. But you’ll recall that we configured our plugin with &lt;code&gt;hour: 12&lt;/code&gt;. That means our 11th and 12th requests will be successful. However, the system will reject our 13th request  even though we haven’t exceeded the five-per-minute rule . That’s because we’ll have exceeded the 12-per-hour rule.&lt;/p&gt;

&lt;p&gt;The Rate Limiting plugin allows you to limit the number of requests per second, minute, hour, day, month and year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rate Limiting “Similar” Requests
&lt;/h3&gt;

&lt;p&gt;We’ve configured Kong to count (and limit) requests to our server in our simple use case so far. More likely, we’ll want to apply our rate limits to &lt;em&gt;similar&lt;/em&gt; requests. By “similar,” we might mean “coming from the same IP address” or “using the same API key.”&lt;/p&gt;

&lt;p&gt;For example, let’s say that all users of our API server need to send requests with a unique API key set in headers as x-api-key. We can configure Kong to apply its rate limits on a per-API-key basis as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# PATH: ~/project/kong.yml

_format_version: "2.1"

services:
- name: my-api-server
  url: http://localhost:3000/
  routes:
  - name: api-routes
    paths:
    - /api
  plugins:
  - name: rate-limiting
    config:
      minute: 5
      hour: 12
      policy: local
      limit_by: header
      header_name: x-api-key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Rate Limiting plugin will apply its limits by grouping requests according to a value found in the &lt;code&gt;x-api-key&lt;/code&gt; in the header. Requests with the same &lt;code&gt;x-api-key&lt;/code&gt; will be considered “similar” requests.&lt;/p&gt;

&lt;p&gt;Let’s restart Kong and see this in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/project$ sudo kong restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back in Insomnia, we’ll adjust our &lt;code&gt;GET&lt;/code&gt; request slightly by adding a new &lt;code&gt;x-api-key&lt;/code&gt; header value. Let’s first set the value to user1. We send the request multiple times. Our first five requests return a &lt;code&gt;200 OK&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zsBE2YAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/x-api-key-header-insomnia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zsBE2YAp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/x-api-key-header-insomnia.png" alt="x-api-key header in Insomnia to test rate limiting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we exceed the five-per-minute rule, however, this is what we see:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LoKOY5o5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/Insomnia-api-rate-limit-exceeded.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LoKOY5o5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/Insomnia-api-rate-limit-exceeded.png" alt="Insomnia API Rate Limit Exceeded"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we change the &lt;code&gt;x-api-key&lt;/code&gt; to a different value (for example, user2), we immediately get &lt;code&gt;200 OK&lt;/code&gt; responses:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oRUC78Cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-test-kong-rate-limiting-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oRUC78Cp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/uploads/2021/05/insomnia-test-kong-rate-limiting-2.png" alt="Insomnia test Kong rate limiting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Requests from &lt;code&gt;user2&lt;/code&gt; are counted separately from requests from &lt;code&gt;user1&lt;/code&gt;. Each unique &lt;code&gt;x-api-key&lt;/code&gt; value gets (according to our rate limiting rules) up to five requests per minute and up to 12 requests per hour.&lt;/p&gt;

&lt;p&gt;You can configure the plugin to &lt;code&gt;limit_by&lt;/code&gt; IP address, a header value, request path or even credentials (like &lt;a href="https://konghq.com/blog/kong-gateway-oauth2/"&gt;OAuth2&lt;/a&gt; or &lt;a href="https://konghq.com/blog/jwt-kong-gateway"&gt;JWT&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Counter Storage “Policy”
&lt;/h3&gt;

&lt;p&gt;In our example above, we set the &lt;code&gt;policy&lt;/code&gt; of the Rate Limiting plugin to &lt;code&gt;local&lt;/code&gt;. This policy configuration controls &lt;a href="https://docs.konghq.com/hub/kong-inc/rate-limiting/#implementation-considerations"&gt;how Kong will store request counters&lt;/a&gt; to apply its rate limits. The &lt;code&gt;local&lt;/code&gt; policy stores in-memory counters. It’s the simplest strategy to implement (there’s nothing else you need to do!). &lt;/p&gt;

&lt;p&gt;However, request counters with this strategy are only &lt;em&gt;mostly&lt;/em&gt; accurate. If you want basic protection for your server, and it’s acceptable if you miscount a request here and there, then the local policy is sufficient. &lt;/p&gt;

&lt;p&gt;The documentation for the Rate Limiting plugin instructs those with needs where “every transaction counts” to use the &lt;code&gt;cluster&lt;/code&gt; (writes to the database) or &lt;code&gt;redis&lt;/code&gt; (writes to Redis key-value store) policy instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Rate Limiting
&lt;/h2&gt;

&lt;p&gt;For many common business cases, the open source Rate Limiting plugin has enough configuration options to meet your needs. For those with more complex needs (multiple limits or time windows, integration with Redis Sentinel), Kong also offers their &lt;a href="https://docs.konghq.com/hub/kong-inc/rate-limiting-advanced/"&gt;Rate Limiting Advanced plugin&lt;/a&gt; for &lt;a href="https://konghq.com/kong-konnect/"&gt;Kong Konnect&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s briefly recap what we did in our mini-project. We spun up a simple API server. Then, we installed and configured Kong Gateway to sit in front of our API server. Next, we added the Rate Limiting plugin to count and limit requests to our server, showing how Kong blocks requests once we exceed certain limits within a window of time. &lt;/p&gt;

&lt;p&gt;Lastly, we demonstrated how to group (and count) requests as “similar” with the example of a header value. Doing so enabled our plugin to differentiate counts for requests coming from two different users so that you can apply that rate limit to each user separately.&lt;/p&gt;

&lt;p&gt;That’s all there is to it. Kong’s Rate Limiting plugin makes protecting your server ridiculously simple. As a basic traffic control defense measure, rate limiting can bring incredible power and peace of mind. You can find more details in the &lt;a href="https://docs.konghq.com/hub/kong-inc/rate-limiting/"&gt;rate limiting plugin doc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any additional questions, post them on &lt;a href="https://discuss.konghq.com/"&gt;Kong Nation&lt;/a&gt;. To stay in touch, join the &lt;a href="https://konghq.com/community/"&gt;Kong Community&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now that you’re successfully protecting services with the Kong Gateway Rate Limiting plugin, you may find these other tutorials helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/custom-lua-plugin-kong-gateway"&gt;Creating Your First Custom Lua Plugin for Kong Gateway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/openid-connect-api-gateway"&gt;Getting Started With Kong’s OpenID Connect Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/kong-gateway-oauth2/"&gt;4 Steps to Authorizing Services With the Kong Gateway OAuth2 Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://konghq.com/blog/jwt-kong-gateway"&gt;How to Use the Kong Gateway JWT Plugin for Service Authentication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://dev.to/kong-konnect"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lrm3tu22--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://konghq.com/wp-content/themes/konghq/assets/img/cta-shortcode/konnect.jpg" alt="Get Started with Kong Konnect - The only full stack connectivity platform for cloud native architectures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://konghq.com/blog/kong-gateway-rate-limiting/"&gt;Protecting Services With Kong Gateway Rate Limiting&lt;/a&gt; appeared first on &lt;a href="https://konghq.com"&gt;KongHQ&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>apigateway</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>ratelimiting</category>
    </item>
    <item>
      <title>Authentication with Kong's JWT Plugin</title>
      <dc:creator>Julia Salem</dc:creator>
      <pubDate>Mon, 15 Mar 2021 22:38:31 +0000</pubDate>
      <link>https://forem.com/kong/service-authentication-with-kong-s-jwt-plugin-1knm</link>
      <guid>https://forem.com/kong/service-authentication-with-kong-s-jwt-plugin-1knm</guid>
      <description>&lt;p&gt;As you build and maintain more applications, your authentication strategy becomes increasingly important. It may also be top of mind for your boss since technology leaders cited “improve application security” as one of their top priorities in this year’s &lt;a href="https://konghq.com/resources/digital-innovation-benchmark-2021/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;Digital Innovation Benchmark&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Kong Gateway &lt;a href="https://docs.konghq.com/hub/kong-inc/jwt/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;JWT plugin&lt;/a&gt; is one strategy for &lt;a href="https://konghq.com/learning-center/api-gateway/api-gateway-authentication/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;API gateway authentication&lt;/a&gt;. JWT simplifies authentication setup, allowing you to focus more on coding and less on security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication Is Tough
&lt;/h2&gt;

&lt;p&gt;You know you need a secure front door to your system. If requests don’t have the right credentials, the door should remain locked. If they do have the proper credentials, the entry should be smooth. &lt;/p&gt;

&lt;p&gt;But how do you verify that credentials are authentic? And how do you make sure there aren’t other ways for those without the right credentials to get into your system?&lt;/p&gt;

&lt;p&gt;Let’s walk through those scenarios as I demonstrate how to secure a service (in this case, an API server) with &lt;a href="https://konghq.com/kong/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;Kong Gateway&lt;/a&gt; and its JWT plugin. I’ll cover all the steps to set up, configure and test the service — giving you the foundational knowledge needed to implement these tools independently.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/OjF95vVldxY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Concepts
&lt;/h2&gt;

&lt;p&gt;First, let’s cover the core technologies. If you’re already familiar with these and just want to get started, feel free to skip ahead.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is Kong Gateway?
&lt;/h3&gt;

&lt;p&gt;As more companies move from monolithic systems to microservices, a decoupled front-line API gateway to those services — providing authentication, traffic control, request and response transformation — becomes increasingly crucial. Kong Gateway, which is open source, serves as that thin layer between your users and your upstream microservices.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Is JWT?
&lt;/h3&gt;

&lt;p&gt;The JSON Web Token (JWT) format lets two parties exchange secure claims. It’s a way of saying, “I am so-and-so, which should give me access to that resource. Here is my access token to prove it.” &lt;/p&gt;

&lt;p&gt;A JWT has a data payload signed by a trusted party to prevent spoofing. An authorizer verifies that the JWT token is authentic, allowing (or forbidding) access to that resource. Typically, a JWT payload is not encrypted; it’s open for the whole world to read. However, what’s critical is the authenticity of a token, which depends on a trusted party signing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Does Kong's JWT API Gateway Plugin Do?
&lt;/h3&gt;

&lt;p&gt;In this approach, the plugin serves as the JWT authorizer. It authenticates the JWT in the HTTP request by verifying that token’s claims and ensuring a trusted party signed it. Then, depending on whether these steps were successful, Kong Gateway routes the upstream service request.&lt;/p&gt;

&lt;p&gt;Keep in mind that authentication in this context means validating the user’s credentials. That’s the job of the JWT plugin. There’s no way to know how a user got a valid JWT. The system just knows that the user has one and is presenting it for authentication. If the JWT is authentic, you can be confident that the user is who they say.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basic Use Case
&lt;/h2&gt;

&lt;p&gt;In this basic use case, I have a login server that accepts login attempts with a user’s email and password. If the email/password checks out, the server generates and signs a JWT and hands it back to the user.&lt;/p&gt;

&lt;p&gt;With JWT in hand, the user tries to access our microservice: a simple API server with a single endpoint. Kong Gateway sits in front of your API server, using the JWT plugin for authentication. The user presents his JWT with his request.&lt;/p&gt;

&lt;p&gt;First, the plugin verifies the token’s authenticity. Next, it confirms the installation steps of the claims inside the payload. A common claim used is an expiration timestamp for the access token. It’s essentially saying, “This token is valid until this date and time.” So, the plugin will check the token’s expiration date.&lt;/p&gt;

&lt;p&gt;If the JWT passes all the necessary checks, Kong Gateway grants access to the requested server endpoint. Otherwise, it responds with &lt;code&gt;401 Unauthorized&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The approach is quite simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up a basic Node.js Express server with a single endpoint.&lt;/li&gt;
&lt;li&gt;Set up Kong Gateway as an API gateway to your server.&lt;/li&gt;
&lt;li&gt;Enable the JWT plugin to protect your server endpoint with JWT authentication.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Set Up a Node.js Express Server and Endpoint
&lt;/h3&gt;

&lt;p&gt;On your local machine, create a folder for your project. Then, initialize a new Node.js project. In the following examples, I’ll use yarn, but you could use npm too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt; &lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ yarn init  # Use all of the yarn defaults here&lt;/span&gt;&lt;span class="err"&gt;.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add Express to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ yarn add expres&lt;/span&gt;&lt;span class="err"&gt;s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your project folder, create the entry point file, &lt;code&gt;index.js&lt;/code&gt;, which will spin up an Express server with a single endpoint. Allow a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;/&lt;/code&gt;, which will respond with the string, “Hello world!”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* PATH: ~/project/index.js
*/&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Server is listening on http://localhost:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was simple enough! Your single endpoint should log the request headers and then send “Hello world!” back to the client with a &lt;code&gt;200&lt;/code&gt; status.&lt;/p&gt;

&lt;p&gt;Start your server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ node index.j&lt;/span&gt;&lt;span class="err"&gt;s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use your browser to test this new endpoint by visiting &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your API server endpoint should be working now!&lt;/p&gt;

&lt;p&gt;Next, use &lt;a href="https://insomnia.rest/"&gt;Insomnia&lt;/a&gt; to send the request and inspect the response. Because of its usability, you’re going to want to use Insomnia exclusively once you start sending requests with a JWT.&lt;/p&gt;

&lt;p&gt;In Insomnia, create a &lt;code&gt;GET&lt;/code&gt; request to &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Insomnia, you should get a &lt;code&gt;200 OK&lt;/code&gt; with “Hello world!” in the response body.&lt;/p&gt;

&lt;p&gt;It looks like the API server is up and running. Now, it’s time to put Kong Gateway in front of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Set Up Kong Gateway
&lt;/h3&gt;

&lt;p&gt;I won’t cover the details here, but the &lt;a href="https://konghq.com/blog/set-up-kong-gateway/?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;Kong Gateway installation steps&lt;/a&gt; may look different depending on your system. &lt;/p&gt;

&lt;p&gt;Once you’ve installed Kong, you’ll need to take a few additional steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DB-Less Declarative Configuration&lt;/strong&gt;&lt;br&gt;
There are &lt;a href="https://docs.konghq.com/gateway-oss/2.3.x/db-less-and-declarative-config/?_ga=2.246640775.229196122.1615774344-852472749.1605808164&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community"&gt;two primary ways to configure Kong&lt;/a&gt;. Imperative configuration issues step-by-step configuration commands to Kong through its admin API. Meanwhile, declarative configuration stores the entire configuration in a single &lt;code&gt;.yml&lt;/code&gt; file then loads it into Kong upon startup. Additionally, you can configure Kong to hook into your database, providing more control over the different nodes it manages.&lt;/p&gt;

&lt;p&gt;For the simple setup example, I’ll use database-less declarative configuration. When you start up Kong, you’ll tell it where to find a &lt;code&gt;.yml&lt;/code&gt; file with all of the configuration declared within.&lt;/p&gt;

&lt;p&gt;In your project folder, run the following command, which generates an initial &lt;code&gt;kong.yml&lt;/code&gt; declarative configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ kong config ini&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ tree -L &lt;/span&gt;&lt;span class="err"&gt;1
&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yml&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;node_modules&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;yarn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lock&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you’ll need to configure the system’s &lt;code&gt;kong.conf&lt;/code&gt; file before starting up Kong. If you’re working on Ubuntu, you’ll be working in &lt;code&gt;/etc/kong&lt;/code&gt;. Here is a template to copy over and then edit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ cd /&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong$&lt;/span&gt; &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;su&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong$&lt;/span&gt; &lt;span class="nx"&gt;tree&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logrotate&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;directories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong$&lt;/span&gt; &lt;span class="nx"&gt;cp&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are only two edits you need to make in your &lt;code&gt;kong.conf&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;PATH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Around&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;839&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uncomment&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;off&lt;/span&gt;
&lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;off&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Around&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;uncomment&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;absolute&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yml&lt;/span&gt;
&lt;span class="nx"&gt;declarative_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/PATH/&lt;/span&gt;&lt;span class="nx"&gt;TO&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;YOUR&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;kong&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Kong starts up, it will be in DB-less mode, meaning it will look to your project’s kong.yml file for a configuration.&lt;/p&gt;

&lt;p&gt;Finally, you’ll need to edit your &lt;code&gt;kong.yml&lt;/code&gt; file to set up a gateway in front of your API server “hello world” endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="mi"&gt;13&lt;/span&gt;
&lt;span class="cm"&gt;/* PATH: ~/project/kong.yml
*/&lt;/span&gt;

&lt;span class="nx"&gt;_format_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3000/&lt;/span&gt;
&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;requests&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sr"&gt;/ap&lt;/span&gt;&lt;span class="err"&gt;i
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go over this.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;_format_version&lt;/code&gt; metadata specifies the version number of your declarative configuration format.&lt;/p&gt;

&lt;p&gt;Next, you define your service, which Kong describes as “an entity representing an external upstream API or microservice.” You can name your service &lt;code&gt;my-api-service&lt;/code&gt; and specify its URL — you’ll recall that the Express server listens for requests at &lt;code&gt;http://localhost:3000&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, define routes, which “determine how (and if) requests are sent to their Services after they reach Kong Gateway.” The (local) URL for Kong is &lt;code&gt;http://localhost:8000&lt;/code&gt;. You should declare your route so that Kong listens for requests at &lt;code&gt;http://localhost:8000/api&lt;/code&gt;, then routes to your service.&lt;/p&gt;

&lt;p&gt;Let’s see this in action. Make sure your Express server is running in a separate terminal. Then, start Kong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ sudo kong star&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In your browser, go to &lt;code&gt;http://localhost:8000/api&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Kong Gateway is up. Finally, add authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Attach JWT Plugin to Kong Gateway
&lt;/h3&gt;

&lt;p&gt;To add the JWT plugin, add a “plugins” definition to your &lt;code&gt;kong.yml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* PATH: ~/project/kong.yml
*/&lt;/span&gt;

&lt;span class="nx"&gt;_format_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3000/&lt;/span&gt;
&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;requests&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sr"&gt;/ap&lt;/span&gt;&lt;span class="err"&gt;i
&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;key_claim_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;kid&lt;/span&gt;
    &lt;span class="nx"&gt;claims_to_verify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;exp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, you can add the plugin named &lt;code&gt;jwt&lt;/code&gt; and attach it to your service called &lt;code&gt;my-api-server&lt;/code&gt;. For its &lt;a href="https://docs.konghq.com/hub/kong-inc/jwt/?_ga=2.207847185.229196122.1615774344-852472749.1605808164&amp;amp;utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=community#parameters"&gt;configuration options&lt;/a&gt;, tell the plugin to check the &lt;code&gt;exp&lt;/code&gt; value to verify that the access token has not expired.&lt;/p&gt;

&lt;p&gt;At this point, restart Kong and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ sudo kong restar&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is &lt;code&gt;401 Unauthorized&lt;/code&gt;. Excellent! Kong now requires a valid JWT for any requests to your API server. Next, you need to tell Kong what constitutes a valid JWT.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;kong.yml&lt;/code&gt;, you need to add a consumer and a credential. Kong describes consumers as being “associated with individuals using your Service, and can be used for tracking, access management, and more.” In a more elaborate setting, every one of your API users could be a consumer. That’s a use case you can read more about towards the end of this article. In this situation, your login server is your consumer. Your login server will be the entity generating JWTs and handing them out. Users who make a request to Kong will be holding a “login server” JWT.&lt;/p&gt;

&lt;p&gt;Edit your &lt;code&gt;kong.yml&lt;/code&gt; file by adding the “consumers” and “jwt_secrets” definitions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;span class="mi"&gt;8&lt;/span&gt;
&lt;span class="mi"&gt;9&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt;
&lt;span class="mi"&gt;13&lt;/span&gt;
&lt;span class="mi"&gt;14&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="mi"&gt;17&lt;/span&gt;
&lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="mi"&gt;19&lt;/span&gt;
&lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="mi"&gt;21&lt;/span&gt;
&lt;span class="mi"&gt;22&lt;/span&gt;
&lt;span class="mi"&gt;23&lt;/span&gt;
&lt;span class="mi"&gt;24&lt;/span&gt;
&lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="cm"&gt;/* PATH: ~/project/kong.yml
*/&lt;/span&gt;

&lt;span class="nx"&gt;_format_version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//localhost:3000/&lt;/span&gt;
&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;requests&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sr"&gt;/ap&lt;/span&gt;&lt;span class="err"&gt;i
&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;key_claim_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;kid&lt;/span&gt;
    &lt;span class="nx"&gt;claims_to_verify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;exp&lt;/span&gt;
&lt;span class="nx"&gt;consumers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;login_server_issuer&lt;/span&gt;
&lt;span class="nx"&gt;jwt_secrets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;login_server_issuer&lt;/span&gt;
    &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secret-hash-brown-bear-market-rate-limit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ve added a new consumer, named &lt;code&gt;login_server_issuer&lt;/code&gt;. Then, you added a JWT API gateway credential for that consumer, which contains the secret used to sign JWTs for this consumer. Authentication requires two parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;kid&lt;/code&gt; (key identifier) value in the JWT header, which is a unique identifier that lets the plugin determine which consumer allegedly issued this JWT&lt;/li&gt;
&lt;li&gt;Verification of the consumer’s secret – Was this the secret used to sign this JWT API gateway? If so, then this JWT is authentic.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before continuing, remember to restart Kong:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;/project$ sudo kong restar&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to generate a JWT for testing, you need the secret (which you have) and the key to use for the kid value. Kong gives us access to that value through its admin API at &lt;code&gt;http://localhost:8001&lt;/code&gt;. You send a &lt;code&gt;GET&lt;/code&gt; request to the admin API’s endpoint &lt;code&gt;/consumers/CONSUMER-USERNAME/jwt&lt;/code&gt;. This gives us information about this consumer’s JWT credential.&lt;/p&gt;

&lt;p&gt;As you inspect this credential’s information, you should see the JWT &lt;code&gt;secret&lt;/code&gt; and signing &lt;code&gt;algorithm&lt;/code&gt;. What you’re looking for, though, is the key. In the above example, that’s &lt;code&gt;1nzcMG9Xg7n1lLgmltHnkAmkt7yp4fjZ&lt;/code&gt;. This is what you use as the &lt;code&gt;kid&lt;/code&gt; value in the JWT header. The Kong plugin will see this &lt;code&gt;kid&lt;/code&gt; value, track down the associated consumer and secret, then make sure the JWT was signed with that secret.&lt;/p&gt;

&lt;p&gt;To test this, let’s start with the happy path. You need a JWT with a header that includes the correct kid value, signed with the right secret. For simplicity, let’s do this at jwt.io. Here, you can craft your payload, set the signing secret and then copy/paste the resulting JWT.&lt;/p&gt;

&lt;p&gt;In the payload, the &lt;code&gt;kid&lt;/code&gt; must match the &lt;code&gt;key&lt;/code&gt; value from above. Also, because you configured the plugin to check JWT token expiration, you should set the &lt;code&gt;exp&lt;/code&gt; (Unix timestamp) far into the future. The &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; are inconsequential; they just demonstrate that you can put other helpful data in the JWT payload.&lt;/p&gt;

&lt;p&gt;Lastly, include your JWT secret at the bottom for proper signing. The result is an encoded JWT.&lt;/p&gt;

&lt;p&gt;Back in Insomnia, you have your original request that resulted in &lt;code&gt;401&lt;/code&gt;. You need to add “Authorization” to that request. Choose “Auth – Bearer Token,” then paste in your encoded JWT from above.&lt;/p&gt;

&lt;p&gt;Now, with a valid JWT attached, resend the request.&lt;/p&gt;

&lt;p&gt;Your JWT should have been validated, and Kong routed us to the API server!&lt;/p&gt;

&lt;p&gt;If you look back at the terminal running the Express server, you’ll recall that you’re logging the request headers to the console. When the JWT plugin authenticates an access token, it writes some additional values to the upstream headers, namely the consumer id, username and credential identifier (the &lt;code&gt;key&lt;/code&gt; value).&lt;/p&gt;

&lt;p&gt;But what happens if your JWT is not valid? Let’s test and see.&lt;/p&gt;

&lt;p&gt;First, sign the JWT with a different secret. Back at jwt.io, keep the payload, but change the signing secret. Copy the resulting JWT to Insomnia, and send your request again. You’ll get a &lt;code&gt;401&lt;/code&gt; with “Invalid Signature.”&lt;/p&gt;

&lt;p&gt;If your secret is correct, but the &lt;code&gt;kid&lt;/code&gt; is incorrect, Kong won’t find an associated credential. Without that credential, there’s no way to find the secret for authenticating the JWT.&lt;/p&gt;

&lt;p&gt;Lastly, if the &lt;code&gt;exp&lt;/code&gt; value is in the past, then your JWT has expired. Just as you expected, you get the following response.&lt;/p&gt;

&lt;p&gt;And that’s it! You should be up and running with Kong Gateway and the JWT Plugin acting as an authentication layer in front of an API server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set It and Forget It
&lt;/h2&gt;

&lt;p&gt;Implementing authentication —and getting it right —is hard work. As microservices become the norm, delegating authentication makes more and more sense. “Rolling your own” implementation for JWT authentication can muddy a code base and still leave you wondering if you got it right. By using well-tested and community-adopted services that handle concerns like routing, logging or authentication, developers can shift their focus back to their projects’ unique needs.&lt;/p&gt;

&lt;p&gt;With that, you now have a solid foundation for getting started with Kong Gateway and the JWT plugin. It’s time to get to work.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for walking through this tutorial with us. It was originally published on our blog: &lt;a href="https://bit.ly/3eJGhCS"&gt;https://bit.ly/3eJGhCS&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>apigateway</category>
      <category>authorization</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
