• Explore the unified API Platform
        • BUILD APIs
        • Kong Insomnia
        • API Design
        • API Mocking
        • API Testing & Debugging
        • MCP Client
        • RUN APIs
        • API Gateway
        • Context Mesh
        • AI Gateway
        • Event Gateway
        • Kubernetes Operator
        • Service Mesh
        • Ingress Controller
        • Runtime Management
        • DISCOVER APIs
        • Developer Portal
        • Service Catalog
        • MCP Registry
        • GOVERN APIs
        • Metering & Billing
        • APIOps & Automation
        • API Observability
        • Why Kong?
      • CLOUD
      • Cloud API Gateways
      • Need a self-hosted or hybrid option?
      • COMPARE
      • Considering AI Gateway alternatives?
      • Kong vs. Postman
      • Kong vs. MuleSoft
      • Kong vs. Apigee
      • Kong vs. IBM
      • GET STARTED
      • Sign Up for Kong Konnect
      • Documentation
  • Agents
      • FOR PLATFORM TEAMS
      • Developer Platform
      • Kubernetes & Microservices
      • Observability
      • Service Mesh Connectivity
      • Kafka Event Streaming
      • FOR EXECUTIVES
      • AI Connectivity
      • Open Banking
      • Legacy Migration
      • Platform Cost Reduction
      • Kafka Cost Optimization
      • API Monetization
      • AI Monetization
      • AI FinOps
      • FOR AI TEAMS
      • AI Cost Control
      • AI Governance
      • AI Integration
      • AI Security
      • Agentic Infrastructure
      • MCP Production
      • MCP Traffic Gateway
      • FOR DEVELOPERS
      • Mobile App API Development
      • GenAI App Development
      • API Gateway for Istio
      • Decentralized Load Balancing
      • BY INDUSTRY
      • Financial Services
      • Healthcare
      • Higher Education
      • Insurance
      • Manufacturing
      • Retail
      • Software & Technology
      • Transportation
      • See all Solutions
      • DOCUMENTATION
      • Kong Konnect
      • Kong Gateway
      • Kong Mesh
      • Kong AI Gateway
      • Kong Insomnia
      • Plugin Hub
      • EXPLORE
      • Blog
      • Learning Center
      • eBooks
      • Reports
      • Demos
      • Customer Stories
      • Videos
      • EVENTS
      • AI + API Summit
      • Webinars
      • User Calls
      • Workshops
      • Meetups
      • See All Events
      • FOR DEVELOPERS
      • Get Started
      • Community
      • Certification
      • Training
      • COMPANY
      • About Us
      • Why Kong?
      • We're Hiring!
      • Press Room
      • Investors
      • Contact Us
      • PARTNER
      • Kong Partner Program
      • SECURITY
      • Trust and Compliance
      • SUPPORT
      • Enterprise Support Portal
      • Professional Services
      • Documentation
      • Press Releases

        Kong Names Bruce Felt as Chief Financial Officer

        Read More
  • Pricing
  • Login
  • Get a Demo
  • Start for Free
Blog
  • AI Gateway
  • AI Security
  • AIOps
  • API Security
  • API Gateway
|
    • API Management
    • API Development
    • API Design
    • Automation
    • Service Mesh
    • Insomnia
    • View All Blogs
  1. Home
  2. Blog
  3. Enterprise
  4. Simplifying PCI Compliance With Kong Gateway
Enterprise
June 9, 2021
5 min read

Simplifying PCI Compliance With Kong Gateway

Amit Mahbubani

Razorpay is a payments processor that's required to comply with PCI guidelines. This article will explain how we developed a custom Lua plugin to simplify PCI compliance with Kong Gateway.

PCI Compliance: A Quick Overview

The Payment Card Industry Data Security Standard (PCI-DSS) is a set of requirements to ensure that all companies that process, store or transmit card information maintain a secure environment. Every system component that processes, stores or transmits such information comes under the PCI system scope. Such companies are required to undergo annual audits where the system under scope is reviewed and certified.

Companies adhering to PCI-DSS requirements need to design secure and compliant systems that are easy to audit and develop on. A key consideration in these designs would be to limit the scope of the systems that come under PCI scope.

Leveraging Kong for the Ideal PCI Compliant Architecture

If your systems need to work with credit card information, an ideal architecture with PCI compliance in mind would be exposing a minimal number of system components to this information in its raw form. Here's an example of what that would look like with Kong:

Kong Gateway PCI handler plugin architecture


The diagram above shows that the components exposed to card data are limited to Kong itself and a tokenization service. Microservices upstream receive a tokenized version of the card data and are hence out of PCI scope. Other upstream services that need to access raw card information, such as those that communicate with third-party payment gateway APIs, can do so by exchanging the token on the tokenizer. By accessing card data, these services are also brought under PCI scope. Let's break this down.

The Tokenization Service

This service replaces sensitive card information with a unique, randomly generated identifier called a token. The system can then pass this token onto upstream services without exposing card data. The tokenization service itself is out of the scope of this article. It's enough to think of it as an abstraction that provides two operations: tokenize and detokenize. In production environments, this service needs to be highly secure and PCI compliant itself. At Razorpay, we use Hashicorp's Vault for this purpose.

The PCI Handler Plugin

The plugin is a new custom Kong plugin that you would need to enable on API routes that accept card data. Its key functions are:

1. Payload Introspection – A request payload may not always have card data. The plugin will first introspect incoming request payloads to determine whether card data is present and if further action is required. Payload attribute details are available as plugin configuration.

2. Validation – This is the basic input validation of the card attributes in the payload.

3. Handle Tokenization – The system makes an API request to the tokenization service with card attributes. Then, it captures the token response.

Payload Transformation – The plugin transforms the request payload to replace the sensitive card attributes with the token. The new attribute is a plugin configuration.

Configuring Kong

1. Installing Kong

Install a basic version of Kong by following the guide for your system. Alternatively, you can clone our template starter repo, which is what we're doing next.

Note: this works with Docker.

git clone --recurse-submodules -j8 https://github.com/razorpay/kong-template.git
cd kong-template
make init
make up

This makes Kong Admin APIs available on 127.0.0.1:8001, whereas the service APIs are accessible on 127.0.0.1:8000. Verify if everything's up and running: curl -i http://127.0.0.1:8001/status.

2. Create the PCI Handler Plugin

You can write Kong plugins in Lua, Go or JavaScript. It's easy to create custom plugins with Kong's plugin development kit (PDK). Let's create a lightweight version of the pci-handler plugin with Lua:

The below snippet shows the general layout of a plugin that works with the access phase.

-- Validates card attributes in the request body
local function validate_body_params(conf, card_fields_conf, body)
 ...
end

-- Extracts card attributes from the request body as per config
-- specified in card_fields_conf and saves it tp a new table: "card_data"
local function set_card_data(card_fields_conf, body)
  ...
end

-- Transforms the request body. Removes the card_fields attributes
-- and adds a new attribute with the generated token string
local function transform_body(card_fields_conf, body, token)
  ...
end

-- Makes a HTTP call to the tokenizer service for card tokenization
local function tokenize_card(conf, card_data)
  ...
end

function PciHandler:access(conf)
  PciHandler.super.access(self)

  local card_fields_conf = {
    ...
  }

  ...

  if is_json_body(kong.request.get_header(CONTENT_TYPE)) then
    -- Parse the JSON body, to a lua table
    req_body = parse_json(kong.request.get_raw_body())

    -- Validates body for card attributes
    if not validate_body_params(conf, card_fields_conf, req_body) then
      ...
    end

    has_card_data = true
  end

  if has_card_data then
    -- Extracts card data from the request body and sets it to the
    -- format defined in the the card_fields_conf table
    local card_data = set_card_data(card_fields_conf, req_body)

    -- Tokenize the card attributes
    local token = tokenize_card(conf, card_data)

    -- Transform the request body - replaces the card attributes with
    -- token received in the previous step
    new_req_body = transform_body(card_fields_conf, req_body, token)

    -- Reset the request body
    local new_req_body_json = cjson.encode(new_req_body)
    set_raw_body(new_req_body_json)
    set_header(CONTENT_LENGTH, #new_req_body_json)
  end
end

return PciHandler

You can find the whole source code for this plugin here. You should store plugin files in a new directory under path – <path-to-project>/kong-plugins/pci-handler/…

Note: this is for demonstration purposes only, not intended for production use.

2. Enable and Attach the Plugin on Kong

The plugin can be attached to Kong by editing the kong.conf config file.

1. Add the plugin path to the lua_package_path key

lua_package_path = ./?.lua;./?/init.lua;/usr/local/kong/kong-plugins/pci-handler/?.lua;/usr/local/kong/kong-plugins/kong-plugin/?.lua;/usr/local/kong/kong-plugins/kong-plugin/?/init.lua;;

2. Add the plugin name to the "plugins" list: plugins = bundled,pci-handler

3. Reload kong for changes to take effect. If you're using the kong-template starter kit, you can do this by running the following command: docker-compose exec kong kong reload

3. Set Up the Tokenization and Upstream Services

Given below are two snippets to set up sample tokenization and upstream services with NodeJs.

mkdir -p kong-services kong-services/upstream-example kong-services/tokenizer

# To setup the upstream-example service:
cd kong-services/upstream-example
npm init
npm install express
touch index.js
node index.js

# Similarly, to setup the tokenizer service:
cd kong-services/tokenizer
npm init
npm install express
touch index.js
node index.js

kong-services/tokenizer/index.js:

const express = require('express')
const crypto = require('crypto')

const server = express()
const port = 8885

server.use(express.json());

var algorithm = 'aes256';
var key = 'example_encryption_key_123456789';
var iv = "example_iv_12345"

// Serve a POST /tokenize API call 
server.post('/tokenize', (req, res) => {

  // req.body should be validated first here.

  data = JSON.stringify(req.body)

  // encrypt the card data attributes to create a token
  var cipher = crypto.createCipheriv(algorithm, key, iv);  
  var token = cipher.update(data, 'utf8', 'hex') + cipher.final('hex');

  json = {
  "token": token
  };

  res.status(200).send(JSON.stringify(json))
})

// Serve a POST /detokenize API call
server.post('/detokenize', (req, res) => {
  var token = req.body.token;

  // decrypt a token and return the original payload
  var decipher = crypto.createDecipheriv(algorithm, key, iv);
  var decrypted = decipher.update(token, 'hex', 'utf8') + decipher.final('utf8');

  res.status(200).send(decrypted)
})

server.listen(port, () => {
  console.log(`Server is listening on http://localhost:${port}`)
})

kong-services/upstream-example/index.js:

const express = require('express')
const server = express()
const port = 8881

server.use(express.json());

server.post('/payments', (req, res) => {
  console.log(req.body);
  res.status(200).send(req.body)
})
 
server.listen(port, () => {
  console.log(`Server is listening on http://localhost:${port}`)
})

With the above setup, we now have these microservices running:

1. "Tokenizer" service, on port 8885

2. "upstream-example" service, on port 8881

4. Define Service and Routes, and Enable the Plugin

Define the upstream-example service on Kong:

1. Create the service

curl --location 'http://127.0.0.1:8001/services' --header 'Content-Type: application/json' --data-raw '{
        "name": "upstream-example",
        "url": "http://host.docker.internal:8881"
}'

2. Define a route, attached to the service

curl --location 'http://127.0.0.1:8001/services/upstream-example/routes' --header 'Content-Type: application/json' --data-raw '{"paths":[""]}'

3. Attach the plugin

curl --location 'http://127.0.0.1:8001/services/upstream-example/plugins' --header 'Content-Type: application/json' --data-raw '{
        "name": "pci-handler",
        "config": {
                "card_expiry_year_field": "card_expiry_year",
                "card_cvv_field": "card_cvv",
                "card_number_field": "card_number",
                "card_expiry_month_field": "card_expiry_month",
                "tokenizer_url": "http://host.docker.internal:8885/tokenize",
                "card_token_output_field": "card_token"
        }
}'

5. Get This All Running

Let's hit the /payments endpoint on the upstream-example service via Kong:

curl --location 'http://127.0.0.1:8000/payments' --header 'Content-Type: application/json' --data-raw '{
        "card_expiry_month": "04",
        "card_expiry_year": "2022",
        "card_number": "1234",
        "card_cvv": "351",
        "payment_amount": 5000,
        "currency": "INR"
}'

You should see a response as follows.

{
"card_token": "15e797499d18b9912c69485bc8b89e72e10c58ed06e5d66b9ad1b5647143fb65a3109a95c2848cc87a0bae173e0cc700409941b95dff10ee31beeb37d1a1ebe5d07ebe4fc558afb0bc9e6281d634f566669c3f8293559e62d2d353709d2a1849",
"payment_amount": 5000,
"currency": "INR"
}

We see in the response above that the upstream-service simply responded with the request body that it had received. In this case, the card attributes were replaced with a card_token attribute, meaning our pci-handler plugin is working as expected!

You can find all the above code for Kong, the plugin and sample services packaged into one Github repo here.

Fast, Scalable and Secure With Kong

Designing systems that work well with PCI-DSS is not trivial but is important to get right. With the rapid adoption of microservices taking place, delegating such mission-critical components to the API gateway makes a lot of sense. Kong's plugin architecture allowed us to significantly reduce our PCI scope, thereby increasing security and agility.

If you'd like a more in-depth look at some of the things you can build, check out the Plugin Development Guide in Kong's documentation and these resources:

  • The Kong Plugin Development Kit documentation
  • An excellent introduction to Lua
  • Pongo, the Kong plugin test tool
  • A plugin-template to clone
  • The Kong open source plugins and their tests to use as examples

If you have questions or comments, tweet us @RazorpayEngg!

To stay in touch, join the Kong Community.

Once you've successfully set up a custom Lua plugin, you may find these other tutorials helpful:

  • Protecting Services With Kong Gateway Rate Limiting
  • Kong Configurations Using Terraform via GitOps Model
  • Getting Started With Kong Konnect in 10 Minutes

API GatewayKong Gateway

More on this topic

Videos

How to Use the Kong Gateway Key Authentication Plugin

Videos

How Delta Fiber Scaled Transformation with Kong Gateway

See Kong in action

Accelerate deployments, reduce vulnerabilities, and gain real-time visibility. 

Get a Demo
Topics
API GatewayKong Gateway
Amit Mahbubani

Recommended posts

Kong Gateway Enterprise 3.3.x.x EOL

EnterpriseMarch 29, 2024

As of May 2024, Kong Gateway Enterprise 3.3.x.x will enter its End Of Life (EOL) phase and will no longer be a part of the full support cycle. Following this, Kong Gateway Enterprise 3.3.x.x will enter a 12-month sunset support period, exclusively f

Veena Rajarathna

Leap Forward with Kong Gateway Enterprise 3.6

EnterpriseFebruary 15, 2024

We're thrilled to announce the general availability of Kong Gateway Enterprise 3.6. This version brings security, efficiency, and standards conformance to enterprise applications. Plus, Kong AI Gateway , which you can learn more about here . Let’s

Veena Rajarathna

Kong Gateway Enterprise 3.2.x.x EOL

EnterpriseJanuary 31, 2024

As of February 2024, Kong Gateway Enterprise 3.2.x.x will enter its End Of Life (EOL) phase and out of the full support cycle. Following this, Kong Gateway Enterprise 3.2.x.x will enter a 12-month sunset support period, exclusively focused on helpin

Veena Rajarathna

Kong Gateway Enterprise and Amazon EKS Anywhere Bare Metal

EnterpriseJune 30, 2022

Power up application modernization and migration using Kong Gateway Enterprise and Amazon EKS Anywhere Bare Metal One of the most critical requirements for an Application Modernization project is to support workloads running on multiple platforms. I

Claudio Acquaviva

Open Banking With BIAN and Kong Gateway

EnterpriseJanuary 10, 2022

In this episode of Kongcast , I spoke with Grant McKeen and Jonathan White from IntegrationWorks about how open banking and BIAN (Banking Industry Architecture Network) work with Kong Gateway to create simplicity from complexity in the ba

Kaitlyn Barnard

Protecting Australian Consumer Data Rights (CDR) with Kong Gateway

EnterpriseNovember 9, 2021

This post highlights how you could use Kong Gateway to implement a solution for the Australian Consumer Data Standards (CDS) , which is part of the Consumer Data Right legislation introduced by the Australian Government in November 2017. As det

Steve Young

UnitedHealth Group Insures API Management With Kong Gateway

EnterpriseFebruary 5, 2021

This article was written by Jeremy Justus and Ross Sbriscia, senior software engineers from UnitedHealth Group/Optum. As part of the UnitedHealth Group (UHG), Optum optimizes healthcare technology, and one of our important missions is to provide the

Kong

Ready to see Kong in action?

Get a personalized walkthrough of Kong's platform tailored to your architecture, use cases, and scale requirements.

Get a Demo
Powering the API world

Increase developer productivity, security, and performance at scale with the unified platform for API management, AI gateways, service mesh, and ingress controller.

Sign up for Kong newsletter

    • Platform
    • Kong Konnect
    • Kong Gateway
    • Kong AI Gateway
    • Kong Insomnia
    • Developer Portal
    • Gateway Manager
    • Cloud Gateway
    • Get a Demo
    • Explore More
    • Open Banking API Solutions
    • API Governance Solutions
    • Istio API Gateway Integration
    • Kubernetes API Management
    • API Gateway: Build vs Buy
    • Kong vs Postman
    • Kong vs MuleSoft
    • Kong vs Apigee
    • Documentation
    • Kong Konnect Docs
    • Kong Gateway Docs
    • Kong Mesh Docs
    • Kong AI Gateway
    • Kong Insomnia Docs
    • Kong Plugin Hub
    • Open Source
    • Kong Gateway
    • Kuma
    • Insomnia
    • Kong Community
    • Company
    • About Kong
    • Customers
    • Careers
    • Press
    • Events
    • Contact
    • Pricing
  • Terms
  • Privacy
  • Trust and Compliance
  • © Kong Inc. 2026