Custom Plugins
Last updated:
Introduction
Plugins can be used to customize and enhance the capabilities of your APIs through integration with external services and databases to perform operations such as data transformation, custom authentication, logging and monitoring etc.
When Tyk receives an API request, it works through a chain of processing middleware that is configured using the API definition. There are a large number of built-in middleware in the processing chain that are dedicated to performing client authentication, request transformation, caching and many other processes before proxying the request to the upstream.
Tyk’s custom plugin facility provides a powerful and flexible way to extend the middleware chain. It allows API developers to write custom middleware, in various programming languages, that can perform additional processing of requests and responses.
For example, a custom authentication scheme can be implemented and executed on API requests, custom plugins can be used to provide integration with external services and databases, or additional processing can be performed on the response returned from the upstream.
There are several different stages of the API request lifecycle where custom plugins can be attached (or hooked) into the middleware chain allowing significant customization to meet your specific requirements.
Custom plugins are usually referred to by the location where they can be hooked into the middleware processing chain as follows:
How Plugin Works
The diagram below illustrates a high level architectural overview for how Tyk Gateway interacts with plugins.
From the above illustration it can be seen that:
- The client sends a request to an API served by Tyk Gateway.
- Tyk processes the request and forwards it to one or more plugins implemented and configured for that API.
- A plugin performs operations (e.g., custom authentication, data transformation).
- The processed request is then returned to Tyk Gateway, which forwards it upstream.
- Finally, the upstream response is sent back to the client.
Types of Plugin
Tyk supports four types of plugins:
To know more about plugin types and it’s advanced configuration, refer the following docs.
Getting Started
This section takes you through the process of running and building a quickstart Go plugin, included within Tyk’s getting started repository. Go plugins are the recommended plugin type and suitable for most use cases.
Expected outcome
At the end of this process you should have a Tyk Gateway or Tyk Self-Managed environment running locally, with a simple Go plugin executing on each API request. For each reponse to an API request the example plugin will inject a Foo header, with a value of Bar.
Prerequisites
- Docker
- Docker-compose
- Tyk license (if using Self-Managed Tyk, which will make the process easier via UI)
- Make
- OSX (Intel) -> Not a prerequisite, though these steps are tested on OSX Intel/ARM
Before you begin
Please clone the getting started respository.
git clone https://github.com/TykTechnologies/custom-go-plugin
cd custom-go-plugin
Choose your environment
Dashboard Plugins
This quick start explains how to run the getting started Go plugin within Tyk Dashboard.
Estimated time: 10-15 minutes
In this tutorial you will learn how to:
- Add your Tyk license.
- Bootstrap the Tyk Dashboard environment.
- Login to Tyk Dashboard.
- View the pre-configured API.
- Test the plugin.
- View the analytics.
- Next steps.
Steps for Configuration:
-
Add your Tyk license
Create and edit the file
.env
with your Tyk Dashboard license key# Make a copy of the example .env file for the Tyk-Dashboard cp .env.example .env
-
Bootstrap the getting started example
run the
make
command:make
This will take a few minutes to run as it compiles the plugin for the first time and downloads all the necessary Docker images.
-
Log in to Tyk Dashboard
Log on to the Tyk Dashboard on
http://localhost:3000
using the following Bootstrapped credentials:and password:
topsecretpassword
Note: these are editable in
.env.example
-
View the pre-configured API
Once you’re logged on to the Tyk Dashboard, navigate to the APIs screen.
You’ll see a sample Httpbin API. Let’s click into it for more details.
Click on VIEW RAW DEFINITION. Note the custom_middleware block is filled out, injecting the compiled example Go plugin into the API.
-
Test the plugin
Let’s send an API request to the API Gateway so it can reverse proxy to our API.
curl localhost:8080/httpbin/get
Yields the response:
{ "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Foo": "Bar", "Host": "httpbin.org", "User-Agent": "curl/7.79.1", "X-Amzn-Trace-Id": "Root=1-63f78c47-51e22c5b57b8576b1225984a" }, "origin": "172.26.0.1, 99.242.70.243", "url": "http://httpbin.org/get" }
Note, we see a Foo:Bar HTTP Header was injected by our Go plugin and echoed back to us by the Httpbin mock server.
-
View the analytics
Navigate to the Dashboard’s various API Usage Data to view analytics on the API request!
Open-Source Plugins
This quick start guide will explain how to run the getting started Go plugin using the Tyk OSS Gateway.
Steps for Configuration:
-
Bootstrap the getting started example
Please run the following command from within your newly cloned directory to run the Tyk Stack and compile the sample plugin. This will take a few minutes as we have to download all the necessary dependencies and docker images.
make up-oss && make build
-
Test the plugin
Let’s test the plugin by sending an API request to the pre-configured API definition:
curl localhost:8080/httpbin/get
Response:
{ "args": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip", "Foo": "Bar", "Host": "httpbin.org", "User-Agent": "curl/7.79.1" }, "origin": "172.28.0.1, 99.242.70.243", "url": "http://httpbin.org/get" }
We’ve sent an API request to the Gateway. We can see that the sample custom plugin has injected an HTTP header with a value of Foo:Bar. This header was echoed back in the Response Body via the mock Httpbin server.
The
./tyk/scripts/bootstrap-oss.sh
script creates an API definition that includes the custom plugin. -
View the analytics
We can see that Tyk Pump is running in the background. Let’s check the logs after sending the API request:
docker logs custom-go-plugin_tyk-pump_1
Output:
time="Feb 23 16:29:27" level=info msg="Purged 1 records..." prefix=stdout-pump {"level":"info","msg":"","time":"0001-01-01T00:00:00Z","tyk-analytics-record":{"method":"GET","host":"httpbin.org","path":"/get","raw_path":"/get","content_length":0,"user_agent":"curl/7.79.1","day":23,"month":2,"year":2023,"hour":16,"response_code":200,"api_key":"00000000","timestamp":"2023-02-23T16:29:27.53328605Z","api_version":"Non Versioned","api_name":"httpbin","api_id":"845b8ed1ae964ea5a6eccab6abf3f3de","org_id":"","oauth_id":"","request_time":1128,"raw_request":"...","raw_response":"...","ip_address":"192.168.0.1","geo":{"country":{"iso_code":""},"city":{"geoname_id":0,"names":null},"location":{"latitude":0,"longitude":0,"time_zone":""}},"network":{"open_connections":0,"closed_connections":0,"bytes_in":0,"bytes_out":0},"latency":{"total":1128,"upstream":1111},"tags":["key-00000000","api-845b8ed1ae964ea5a6eccab6abf3f3de"],"alias":"","track_path":false,"expireAt":"2023-03-02T16:29:27.54271855Z","api_schema":""}}
As we can see, when we send API requests, the Tyk Pump will scrape them from Redis and then send them to a persistent store as configured in the Tyk Pump env file.
In this example, we’ve configured a simple
STDOUT
Pump where the records will be printed to the Standard OUT (docker logs!)
API Configuration
This page provides an overview on how to register one or more custom plugins to be executed at different stages or hooks in the API request/response lifecycle. If you wish to learn how to register custom plugins to be executed on the traffic logs generated by the Gateway please refer to the analytics plugins page.
If you need fine-grained control at the endpoint level then it is also possible to configure per-endpoint plugins. These are custom Golang plugins that are triggered at the end of the request processing chain before API-level Post plugins are executed.
Introduction
There are three locations where Tyk Gateway can find plugin functions:
- gRPC plugins: Plugin functions are implemented by a gRPC server with the associated configuration specified with the API definition. For further details on how to configure gRPC plugins, please refer to our gRPC documentation.
- Local plugins: Plugins are implemented by functions within source code files located on the Gateway’s file system. The API Definition allows the source code file path and function name to be configured for each plugin. For further details read on.
- Plugin bundles: The plugin source code and configuration are bundled into a zip file that is served by a remote web server. For further details see the plugin bundles page.
Plugin configuration
Each plugin for an API can be configured within the API Definition with the following details:
Property | Description |
---|---|
Enabled |
When true, the plugin is activated |
Name |
A name used to identify the plugin |
Path |
The path to the source code file on the Tyk Gateway file system |
Function name |
The name of the function that implements the plugin. The function should exist within the source code file referenced in path |
Raw body only |
When set to true, this flag indicates that only the raw request body should be processed |
Require session state |
When set to true, Tyk Gateway will serialize the request session state and pass it as an argument to the function that implements the plugin in the target language. This is applicable to Post, Response, and Authentication hooks only |
Language configuration
For local and bundle plugins a plugin driver is configured to specify the plugin implementation language. If using gRPC plugins a grpc
plugin driver should be used to instruct Tyk to request execution of plugins from within a gRPC server that is external to the Tyk process. This offers additional language support since Tyk can integrate with a gRPC server that is implemented using any supported gRPC language.
For a given API it is not possible to mix the implementation language for the plugin types: Pre, Authentication, Post, Post Authentication and Response plugins. For example, it is not possible to implement a pre request plugin in Go and also implement a post request plugin in Python for the same API.
Tyk OAS APIs
An API can be configured so that one or more of its associated plugins can execute at different phases of the request / response life cycle. Each plugin configuration serves to identify the plugin source file path and the name of the corresponding function, triggered at each request / response lifecycle stage.
This guide explains how to configure plugins for Tyk OAS APIs within the Tyk OAS API definition or via the API designer in Tyk Dashboard.
If you’re using the legacy Tyk Classic APIs, then check out the Tyk Classic page.
Using API Definition
The x-tyk-api-gateway.middleware.global
section is used to configure plugins in a Tyk OAS API. It contains a pluginConfig
section and a list of plugins for each phase of the API request / response lifecycle.
The pluginConfig
section contains the driver
parameter that is used to configure the plugin implementation language:
"pluginConfig": {
"driver": "goplugin"
}
Within the x-tyk-api-gateway.middleware.global
section, keyed lists of plugins can be configured for each phase of the API request / response lifecycle described in the table below:
Phase | Description | Config Key |
---|---|---|
Pre | Executed at the start of the request processing chain | prePlugins |
Post Auth | Executed after the requester has been authenticated | postAuthenticationPlugins |
Post | Executed at the end of the request processing chain | postPlugins |
Response | Occurs after the main request processing but before the response is sent. | responsePlugins |
Each plugin configuration can have the following fields configured:
enabled
: When true, enables the plugin.functionName
: The name of the function that implements the plugin within the source file.path
: The path to the plugin source file.rawBodyOnly
: When true, indicates that only the raw body should be processed.requireSession
: When true, indicates that session metadata will be available to the plugin. This is applicable only for post, post authentication and response plugins.
For example a Post Authentication plugin would be configured within a postAuthenticationPlugins
list as shown below:
"postAuthenticationPlugins": [
{
"enabled": true,
"functionName": "post_authentication_func",
"path": "/path/to/plugin1.so",
"rawBodyOnly": true,
"requireSession": true
}
]
An full example is given below to illustrate how to set up plugins for different phases of the request / response lifecycle:
|
|
In this example we can see that the plugin driver has been configured by setting the driver
field to goplugin
within the pluginConfig
object. This configuration instructs Tyk Gateway that our plugins are implemented using Golang.
We can also see that the following type of plugins are configured:
- Pre: A plugin is configured within the
prePlugins
list. The plugin is enabled and implemented by functionpre-plugin
within the source file located at path/path/to/plugin1.so
. - Post Authentication: A plugin is configured within the
postAuthenticationPlugins
list. The plugin is enabled and implemented by functionpost_authentication_func
within the source file located at path/path/to/plugin1.so
. The raw request body and session metadata is available to the plugin. - Post: A plugin is configured within the
responsePlugins
list. The plugin is enabled and implemented by functionpostplugin
within the source file located at path/path/to/plugin1.so
. The raw request body and session metadata is available to the plugin. - Response: A plugin is configured within the
postPlugins
list. The plugin is enabled and implemented by functionResponse
within the source file located at path/path/to/plugin1.so
. The raw request body and session metadata is available to the plugin.
The configuration above is a complete and valid Tyk OAS API Definition that you can use as a basis for trying out custom plugins. You will need to update the driver parameter to reflect the target language type of your plugins. You will also need to update the path
and functionName
parameters for each plugin to reflect the source code.
Using API Designer
Select your API from the list of Created APIs to reach the API designer and then follow these steps:
-
Configure plugin type and custom data
In the Plugins Configuration section, select the Plugin Driver, which tells Tyk which type of plugin to expect: Go, gRPC, JavaScript (OTTO), Lua or Python.
You can configure custom data that will be made available to your plugin function as a JSON formatted object in the Config Data option.
-
Configure the custom plugins
For each plugin that you wish to register with the API, click on the Add Plugin button to display a plugin configuration section:
Complete the following fields:
Function Name
: Enter the name of the function within your plugin code that Tyk should invoke.Path
: Enter the path to the source file that contains the function that implements your plugin.Raw Body Only
: Optionally, toggle the Raw Body Only switch to true when you do not wish to fill body in request or response object for your plugins.
-
Save the API
Select Save API to apply the changes to your API.
Tyk Classic APIs
An API can be configured so that one or more of its associated plugins can execute at different phases of the request / response lifecycle. Each plugin configuration serves to identify the plugin source file path and the name of the corresponding function, triggered at each request / response lifecycle stage.
This guide explains how to configure plugins for Tyk Classic APIs within the Tyk Classic API definition or via the API designer in Tyk Dashboard.
If you’re using the newer Tyk OAS APIs, then check out the Tyk OAS page.
Using API Definition
In Tyk Classic APIs, the custom_middleware section of the Tyk Classic API Definition is where you configure plugins that will run at different points during the lifecycle of an API request.
This table illustrates the different phases of the API request lifecycle where custom plugins can be executed:
Phase | Description | Config |
---|---|---|
Pre | Executed at the start of the request processing chain | pre |
Auth | Executed during the authentication step | auth_check |
Post Auth | Executed after the requester has been authenticated | post_key_auth |
Post | Executed at the end of the request processing chain | post |
Response | Executed on the response received from the upstream | response |
This example configuration illustrates how to set up plugins for different phases of the request lifecycle:
|
|
In this example we can see that there are Golang custom authentication (auth_check
), post authentication (post_key_auth
), post, pre and response plugins configured.
It can be seen that each plugin is configured with the specific function name and associated source file path of the file that contains the function. Furthermore, each lifecycle phase (except auth
) can have a list of plugins configured, allowing for complex processing workflows. For example, you might develop one plugin for logging and another for modifying the request in the pre request phase. When multiple plugins are configured for a phase they will be executed in the order that they appear in the API definition.
The driver
configuration parameter describes the plugin implementation language. Please refer to the supported languages section for list of supported plugin driver names.
Each plugin can have additional settings, such as:
disabled
: When true, disables the plugin.raw_body_only
: When true, indicates that only the raw body should be processed.require_session
: When true, indicates that session metadata will be available to the plugin. This is applicable only for post, post authentication and response plugins.
Using API Designer
This section explains how to configure plugins for a Tyk Classic API using Tyk Dashboard. It specifically covers the use case where the source files of your plugins are deployed on the Tyk Gateway file system.
Select your API from the list of Created APIs to reach the API designer and then follow these steps:
-
Display the Tyk Classic API Definition editor
Click on the View Raw Definition button to display an editor for updating the Tyk Classic API Definition.
-
Edit the Tyk Classic API Definition to configure plugins
Use the editor to edit the
custom_middleware
section of the Tyk Classic API Definition. -
Save changes
Select the Update button to apply your changes to the Tyk Classic API Definition.
Plugin Deployment Types
There are a variety of scenarios relating to the deployment of plugins for an API, concerning the location of the plugin source code and its associated configuration.
Local Plugins
The plugin source code and associated configuration are co-located with Tyk Gateway in the same file system. The configuration is located within the API Definition. For further details please consult API configuration.
Plugin Bundles (Remote)
The plugin source code and associated configuration are bundled into a zip file and uploaded to a remote webserver. Multiple plugins can be stored in a single plugin bundle. Tyk Gateway will download the plugin bundle from the remote webserver and then extract, cache and execute plugins for each of the configured phases of the API request / response lifecycle. For further details on plugin bundles and how to configure them, please refer to the plugin bundles page.
gRPC Plugins (Remote)
Custom plugins can be hosted on a remote server and executed from the Tyk Gateway middleware chain via gRPC. These plugins can be written in any language you prefer, as they are executed on the gRPC server. You’ll configure your API definition so that Tyk Gateway will send requests to your gRPC server at the appropriate points in the API request / response lifecycle. For further details please consult our gRPC documentation.
Plugin Bundles
For Tyk Gateway to execute local custom plugins during the processing of API requests and responses, the plugin source code must be loaded into the Gateway. The source is usually stored in files and the API definition is used to point the Gateway at the correct file for each plugin type. To simplify the management of plugins, you can group (or bundle) multiple plugin files together in a ZIP file that is referred to as a plugin bundle.
When To Use Plugin Bundles
Plugin bundles are intended to simplify the process of attaching and loading custom middleware. Multiple API definitions can refer to the same plugin bundle (containing the source code and configuration) if required. Having this common, shared resource avoids you from having to duplicate plugin configuration for each of your APIs definitions.
How Plugin Bundles Work
The source code and a manifest file are bundled into a zip file and uploaded to an external remote web server. The manifest file references the source code file path and the function name within the code that should be invoked for each plugin type. Within the API definition, custom plugins are configured simply using the name of the bundle (zip file). Tyk Gateway downloads, caches, extracts and executes plugins from the downloaded bundle according to the configuration in the manifest file.
Caching plugin bundles
Tyk downloads a plugin bundle on startup based on the configuration in the API definition, e.g. http://my-bundle-server.com/bundles/bundle-latest.zip
. The bundle contents will be cached so that, when a Tyk reload event occurs, the Gateway does not have to retrieve the bundle from the server again each time. If you want to use a different bundle then you must update your API to retrieve a different bundle filename and then trigger a reload. It is not sufficient simply to replace the bundle file on your server with an updated version with the same name - the caching ensures this will not be retrieved during a reload event.
As a suggestion, you may organize your plugin bundle files using a Git commit reference or version number, e.g. bundle-e5e6044.zip
, bundle-48714c8.zip
, bundle-1.0.0.zip
, bundle-1.0.1.zip
, etc.
Alternatively, you may delete the cached bundle from Tyk manually and then trigger a hot reload to tell Tyk to fetch a new one. By default, Tyk will store downloaded bundles in this path:
{ TYK_ROOT } / { CONFIG_MIDDLEWARE_PATH } / bundles
Gateway configuration
To configure Tyk Gateway to load plugin bundles the following parameters must be specified in your tyk.conf
:
"enable_bundle_downloader": true,
"bundle_base_url": "http://my-bundle-server.com/bundles/",
"public_key_path": "/path/to/my/pubkey",
enable_bundle_downloader
: Enables the bundle downloader.bundle_base_url
: A base URL that will be used to download the bundle. For example if we havebundle-latest.zip
specified in the API definition, Tyk will fetch the following file:http://my-bundle-server.com/bundles/bundle-latest.zip
(see the next section for details).public_key_path
: Sets a public key, used for verifying signed bundles. If unsigned bundles are used you may omit this.
Note
Remember to set "enable_coprocess": true
in your tyk.conf
when using rich plugins!
The manifest file
A plugin bundle must include a manifest file (called manifest.json
). The manifest file contains important information like the configuration block and the list of source code files that will be included as part of the bundle file. If a file isn’t specified in the list, it won’t be included in the resulting file, even if it’s present in the current directory.
A sample manifest file looks like this:
{
"file_list": [
"middleware.py",
"mylib.py"
],
"custom_middleware": {
"pre": [
{
"name": "PreMiddleware"
}
],
"post": [
{
"name": "PostMiddleware"
}
],
"driver": "python"
},
"checksum": "",
"signature": ""
}
You may leave the checksum
and signature
fields empty, the bundler tool will fill these during the build process.
The custom_middleware
block follows the standard syntax we use for Tyk plugins. In Tyk Community Edition, where file-based API configuration is used by default, a custom_middleware
block is located/added to the API configuration file.
Creating plugin bundles
Tyk provides the Bundle CLI tool as part of the tyk
binary. For further details please visit the Bundle CLI tool page.
Tyk OAS API Configuration
For API plugins that are deployed as plugin bundles, the API should be configured with the name of the plugin bundle file to download from your remote web server. Furthermore, the Gateway should be configured to enable downloading plugin bundles.
You can configure your API with the name of the plugin bundle file to download within the Tyk OAS API definition or API Designer.
If you’re using the legacy Tyk Classic APIs, then check out the Tyk Classic page.
Using API Definition
The configuration for a Tyk OAS API to fetch the download of a plugin bundle from a remote web server is encapsulated within the pluginConfig
section within the middleware.global
section of the x-tyk-api-gateway
part of a Tyk OAS API Definition.
The pluginConfig
section is structured as follows:
bundle
: A JSON entity that contains the following configuration parameters:enabled
: Whentrue
, enables the plugin.path
: The relative path of the zip file in relation to the base URL configured on the remote webserver that hosts plugin bundles.
driver
: Indicates the type of plugin, e.g.golang
,grpc
,lua
,otto
orpython
.
An illustrative example is listed below:
|
|
In this example we can see that bundle plugin has been configured within the middleware.global.pluginConfig.bundle
object. The plugin is enabled and bundled within file plugin.zip
. The plugin bundle is a Go plugin, i.e. middleware.global.pluginConfig.driver
has been configured with value goplugin
.
The configuration above is a complete and valid Tyk OAS API Definition that you can import into Tyk to try out custom plugin bundles, assuming that you have provided a valid bundle file named plugin.zip
.
Using API Designer
To configure plugin bundles for Tyk OAS APIs click on the APIs menu item in the API Management menu of Dashboard and select your API to display the editor screen. Subsequently, follow the steps below:
-
Access plugin options
Scroll down until the Enable Plugin section is displayed.
-
Enable plugin bundle for you API
Enable a plugin bundle for your API by activating the toggle switch.
-
Enter relative path to plugin bundle file
Enter the relative path of the plugin bundle file in the Plugin Bundle ID field that Tyk Gateway should download from the web server that hosts your plugin bundles.
-
Save the API
Select Save API to apply the changes to your API.
Tyk Classic API Configuration
For custom plugins that are deployed as plugin bundles, the API should be configured with the name of the plugin bundle file to download from your remote web server. Furthermore, the Gateway should be configured to enable downloading plugin bundles.
You can configure your API with the name of the plugin bundle file to download within the Tyk Classic API definition or API Designer.
If you’re using the newer Tyk OAS APIs, then check out the Tyk OAS page.
Using API Definition
The configuration for an API to fetch and download a plugin bundle from a remote server is encapsulated within the custom_middleware_bundle
field of the Tyk Classic API Definition. An illustrative example is listed below:
|
|
With the configuration given in the example above, calls to the API will invoke the custom plugins defined in the manifest.json
file contained within bundle-latest.zip
uploaded to your remote webserver, e.g. http://your-example-plugin-server.com/plugins
.
Tyk Gateway should be configured for downloading plugin bundles from a secured web server. Please consult the plugin bundles documentation for further details.
Using API Designer
To configure plugin bundles for Tyk Classic APIs click on the APIs menu item in the API Management menu of Dashboard and select your API to display the API editor screen. Subsequently, follow the steps below:
-
Access plugin options
Click on the Advanced Options tab and scroll down until the Plugin Options section is displayed.
-
Enter relative path to bundle file
Enter the relative path of the plugin bundle file in the Plugin Bundle ID field that Tyk Gateway should download from the web server hosting plugin bundles.
-
Save the API
Select the save or update button to apply the changes to your API.
Bundler CLI Tool
The bundler tool is a CLI service, provided by Tyk Gateway as part of its binary since v2.8. This lets you generate plugin bundles.
Generated plugin bundles must be served using your own web server.
Issue the following command to see more details on the bundle
command:
/opt/tyk-gateway/bin/tyk bundle -h
Prerequisites
To create plugin bundles you will need the following:
-
Manifest.json: The manifest.json file contains the paths to the plugin source files and the name of the function implementing each plugin. The manifest.json file is mandatory and must exist on the Tyk Gateway file system. By default the bundle CLI looks for a file named manifest.json in the current working directory where the bundle command is run from. The exact location can be specified using the
--manifest
command option. -
Plugin source code files: The plugin source code files should be contained relative to the directory in which the manifest.json file is located. The manifest.json should contain relative path references to source code files.
Note
Source code files are not required when creating a plugin bundle for gRPC plugins since the plugin source code is located at the gRPC server. -
Certificate key: Plugin bundles can optionally be signed with an RSA private key. The corresponding public key should be located in the file configured in environmental variable
TYK_GW_PUBLICKEYPATH
or thepublic_key_path
parameter intyk.conf
:
{
"enable_bundle_downloader": true,
"bundle_base_url": "http://my-bundle-server.com/bundles/",
"public_key_path": "/path/to/my/pubkey.pem"
}
Directory Structure
A suggested directory structure is shown below for Golang, Javascript and Python bundles in the tabs below.
Note
Sub-directories (folders) are not supported inside the bundle-directory
location.
/bundle-directory
├── manifest.json # Manifest file with plugin references
└── plugin.so # Compiled Golang plugin
/bundle-directory
├── manifest.json # Manifest file with plugin references
├── plugin1.js # First JavaScript plugin source file
└── plugin2.js # Second JavaScript plugin source file
/bundle-directory
├── manifest.json # Manifest file with plugin references
├── plugin1.py # First Python plugin source file
└── plugin2.py # Second Python plugin source file
The manifest.json
will reference the files located in the bundle-directory
, ensure plugin source files are organized relative to the manifest. The Tyk Gateway will load and execute these plugins based on the paths defined in the manifest.json
file.
Sample manifest.json
is shown below for Golang, Javascript and Python bundles in the tabs below.
{
"file_list": [
"plugin.so"
],
"custom_middleware": {
"pre": [
{
"name": "PreMiddleware",
"path": "./plugin.so"
}
],
"post": [
{
"name": "PostMiddleware",
"path": "./plugin.so"
}
],
"driver": "goplugin"
},
"checksum": "",
"signature": ""
}
{
"file_list": [
"plugin1.js",
"plugin2.js"
],
"custom_middleware": {
"pre": [
{
"name": "PreMiddleware",
"path": "./plugin1.js"
}
],
"post": [
{
"name": "PostMiddleware",
"path": "./plugin2.js"
}
],
"driver": "otto"
},
"checksum": "",
"signature": ""
}
{
"file_list": [
"plugin1.py",
"plugin2.py"
],
"custom_middleware": {
"pre": [
{
"name": "PreMiddleware",
"path": "./plugin1.py"
}
],
"post": [
{
"name": "PostMiddleware",
"path": "./plugin2.py"
}
],
"driver": "python"
},
"checksum": "",
"signature": ""
}
Creating a plugin bundle
Run the following command to create the bundle:
$ tyk bundle build
The resulting file will contain all your specified files and a modified manifest.json
with the checksum and signature
(if required) applied, in ZIP format.
By default, Tyk will attempt to sign plugin bundles for improved security. If no private key is specified, the program
will prompt for a confirmation. Use -y
to override this (see options below).
Command Options
Instructions on how to create plugin bundles is displayed by issuing the following command:
/opt/tyk-gateway/bin/tyk bundle build -h
The following options are supported:
--manifest
: Specifies the path to the manifest file. This defaults tomanifest.json
within the current working directory.--output
: Specifies the name of the bundle file e.g.--output bundle-latest.zip
. If this flag is not specified,bundle.zip
will be used.-y
: Force tool to create unsigned bundle without prompting e.g.$ tyk bundle build --output bundle-latest.zip -y
.--key
: Specifies the path to your private key which is used to generate signed bundle e.g.$ tyk bundle build --output bundle-latest.zip --key=mykey.pem
.
Docker Example
Since v5.5 Tyk Gateway uses distroless docker images.
For Gateway version < v5.5 it is possible to use Docker to create plugin bundles as shown in the example below.
docker run --rm -it \
--name bundler \
-v `pwd`:/plugin-source \
-v `pwd`/../../../confs/keys:/keys \
-w /plugin-source \
--entrypoint /bin/bash \
tykio/tyk-gateway:v5.4.0 \
-c 'export PATH="/opt/tyk-gateway:$$PATH"; tyk bundle build -o bundle.zip -k /keys/key.pem'
This Docker command runs a container using the tykio/tyk-gateway:v5.4.0
image to build a Tyk plugin bundle. It mounts
the current directory from the host as /plugin-source
and a directory containing keys as /keys
inside the container.
The working directory within the container is set to /plugin-source
, and the default entrypoint is overridden to use
/bin/bash
. The command executed in the container exports a modified PATH
to include the Tyk Gateway binaries, then
runs tyk bundle build
to generate a plugin bundle named bundle.zip
, using the specified key for authentication. The
container is automatically removed after the command completes, and the operation is conducted interactively.
Supported Languages
The following languages are supported for custom plugins:
- Golang: A plugin written in Golang is called a Native Plugin. Tyk recommends using Go plugins for performance, flexibility, and nativity reasons (all Tyk components are written in Go).
- JavaScript: A plugin written in Javascript uses JavaScript Virtual Machine (JSVM) interpreter.
- Rich Plugins includes Python, Lua, gRPC - With gRPC, you can write plugins in Java, .NET, C++ / C#, PHP, and all other gRPC supported languages. Rich plugins give ultimate flexibility in the language of implementation, however, there are some performance and management overheads when compared with native GoLang plugin.
Common To All Plugin Languages:
- Make Layer 4 (TCP) or Layer 7 (HTTP/REST/SOAP) calls
- Open Persistent Connections
- Modify the request in-flight
- Used to stop the request and return a custom response
- Be served using Bundles or by files on the file system, except gRPC of course which by definition is served by some webserver in the language of your choosing
Plugin Hook Types
Tyk provide 5 different phases, i.e. hooks to inject custom plugin throughout the API execution lifecycle.
Not all hooks are supported in every language. The following table shows you which plugin language support which phase/hook:
Auth | Pre | Post-Auth | Post | Response | |
---|---|---|---|---|---|
GoLang | ✅ | ✅ | ✅ | ✅ | ✅ |
JavaScript | ❌ | ✅ | ❌ | ✅ | ❌ |
gRPC | ✅ | ✅ | ✅ | ✅ | ✅ |
Python | ✅ | ✅ | ✅ | ✅ | ✅ |
Lua | ✅ | ✅ | ✅ | ✅ | ❌ |
More reading on the hook types in rich plugins and explanation with common use case for each hook type
Plugin Driver Names
We use the following Plugin driver names:
Plugin | Name |
---|---|
GoLang | goplugin |
JavaScript | otto |
gRPC | grpc |
Python | python |
Lua | lua |
Limitations
What are the limitations to using this programming Language?
GoLang | JavaScript | gRPC | Python | Lua | |
---|---|---|---|---|---|
Runs in Gateway process | ✅ Runs natively |
✅ Built-In JSVM Interpreter |
❌ Standalone server |
✅ Tyk talks with Python interpreter |
✅ |
Built-in SDK | ✅ All Gateway Functionality |
✅ Yes |
❌ | ✅ Yes |
❌ |
TCP Connections (DBs, Redis, etc) |
✅ | ❌ Very Limited |
✅ | ✅ | ✅ |
Custom Plugin Table
We have put together a GitHub repo with a table of custom plugins in various languages that you can experiment with. If you would like to submit one that you have developed, feel free to open an issue in the repo.
Differences between Rich Plugins and JSVM middleware
JavaScript
The JavaScript Virtual Machine provides pluggable middleware that can modify a request on the fly and are designed to augment a running Tyk process, are easy to implement and run inside the Tyk process in a sandboxed ECMAScript interpreter. This is good, but there are some drawbacks with the JSVM:
- Performance: JSVM is performant, but is not easy to optimize and is dependent on the otto interpreter - this is not ideal. The JSVM also requires a copy of the interpreter object for each request to be made, which can increase memory footprint.
- Extensibility: JSVM is a limited interpreter, although it can use some NPM modules, it isn’t NodeJS so writing interoperable code (especially with other DBs) is difficult.
- TCP Access: The JSVM has no socket access so working with DB drivers and directly with Redis is not possible.
Rich Plugins
Rich Plugins can provide replacements for existing middleware functions (as opposed to augmentation) and are designed to be full-blown, optimized, highly capable services. They enable a full customized architecture to be built that integrates with a user’s infrastructure.
Rich Plugins bring about the following improvements:
- Performance: Run on STDIN (unix pipes), which are extremely fast and run in their own memory space, and so can be optimized for performance way beyond what the JSVM could offer.
- Extensibility: By allowing any language to be used so long as GRPC is supported, the extensibility of a CPH is completely open.
- TCP Access: Because a plugin is a separate process, it can have it’s own low-level TCP connections opens to databases and services.
Plugin Caveats
- Tyk Gateway manages plugins for each API within the same process.
- For gRPC plugins, Tyk Gateway can only be configured to integrate with one gRPC server.
- Javascript plugins only allow Pre and Post Request hooks of the API Request Lifecycle.
Plugins Hub
Welcome to the Tyk Plugins Hub, dedicated to providing you with a curated list of resources that showcase how to develop Tyk Plugins.
Tyk Plugins are a powerful tool that allows you to develop custom middleware that can intercept requests at different stages of the request lifecycle, modifying/transforming headers and body content.
Tyk has extensive support for writing custom plugins using a wide range of languages, most notably: Go, Python, Javascript etc. In fact, plugins can be developed using most languages via gRPC.
Blogs
Selected blogs for plugin development are included below. Further examples are available at the Tyk website.
-
Decoupling micro-services using Message-based RPC
- Summary: Explains how to write a plugin that intercepts an API request and forwards it to a gRPC server. The gRPC server processes the request and dispatches work to an RabbitMQ message queue. The source code is available in the accompanying GitHub repository
-
How to configure a gRPC server using Tyk
- Summary: Explains how to configure a Python implementation of a gRPC server to add additional logic to API requests. During the request lifecycle, the Tyk-Gateway acts as a gRPC client that contacts the Python gRPC server, providing additional custom logic.
-
How to deploy Python plugins in Tyk running On Kubernetes
- Summary: Explains how to deploy a custom Python plugin into a Tyk installation running on a Kubernetes cluster.
GitHub Repositories
Here are some carefully selected GitHub repositories that will help you learn how to integrate and utilize Tyk Plugins in your development projects:
-
- Description: Index of plugins developed using a variety of languages.
- Key Features Demonstrated: A comprehensive index for a collection of plugins that can be used with the Tyk API Gateway in areas such as: rate limiting, authentication and request transformation. The examples are developed using a diverse array of languages, including but not limited to: Python, JavaScript and Go. This broad language support ensures that developers from different backgrounds and with various language preferences can seamlessly integrate these plugins with their Tyk API Gateway implementations.
-
- Description: Index of examples for a range of plugin hooks (Pre, Post, Post-Auth and Response) developed using a variety of languages.
- Key Features Demonstrated: Specific examples include invoking an AWS lambda, inserting a new claim into a JWT, inject a signed JWT into authorization header, request header modification. A range of examples are available including Python, Java, Ruby, Javascript, NodeJS and Go.
-
Environment For Plugin Development
- Description: Provides a docker-compose environment for developing your own custom Go plugins.
- Key Features Demonstrated: Showcases support for bundling plugins, uploading plugins to AWS S3 storage, test coverage etc.