Create Python Plugin

Hi,

I would like to use my own Auth service on every request. I found that by creating plugin is the best way to do it. I am just curious, How can I return an error directly after pre function ?

For example:

  1. access api

  2. Plugin check the token that sent along with the api request

  3. if it is false, then return error directly to user as Error HTTP 401 without processing into the proxy url.

Thanks

1 Like

Hi, you may use the following sample as a starting point:

https://github.com/TykTechnologies/tyk-plugin-demo-python/blob/master/mymiddleware.py

Take a look at MyAuthMiddleware, it performs a basic header check, if no token is set and an empty session object is returned, the authentication fails. You may explore the session object fields here.

You will also need these things:

  • Enable the coprocess feature in tyk.conf:
  "coprocess_options": {
    "enable_coprocess": true
  },
  "enable_bundle_downloader": true,
  "bundle_base_url": "http://localhost/"
  • A web server to serve the plugin bundles (this is the one specified in bundle_base_url).

  • Enable coprocess-based authentication in your API configuration file, and a bundle name:

    "custom_middleware_bundle": "test-bundle"
    "enable_coprocess_auth": true

Check these docs as well.

Hi,

Thank you for your reply. I have tried your additional code on GitHub and follow instruction on how to configure your API with custom bundle. But I got an error like this:

Here is some step that I did:

mymiddleware.py

from tyk.decorators import *
from gateway import TykGateway as tyk

import requests

@Hook
def MyPreMiddleware(request, session, spec):
    return request, session

@Hook
def MyAuthMiddleware(request, session, metadata, spec):
    auth_header = request.get_header('Authorization')
    headers = {'Authorization': auth_header}
    r = requests.post("http://13.76.101.247:9001/api/v1/users/session", headers=headers)
        if r.status_code == 200:
            session.rate = 1000.0
            session.per = 1.0
            metadata["token"] = "47a0c79c427728b3df4af62b9228c8ae"
    return request, session, metadata

tyk.conf

"coprocess_options": {
"enable_coprocess": true,
"coprocess_grpc_server": ""
  },
"pid_file_location": "./tyk-gateway.pid",
"allow_insecure_configs": true,
"public_key_path": "",
"close_idle_connections": false,
"allow_remote_config": false,
"enable_bundle_downloader": true,
"bundle_base_url": "http://13.76.187.81/tykbundle/",

And here is what I did on my dashboard:

Enable Cors, Allow Header : Authorization

Authentication mode: Use Custom Auth (plugin)

Plugin Option / Plugin ID : bundle

The bundle file name is bundle.zip

Thank You

Best Regards,

Adityo Setyonugroho

Can you share your API configuration?

Hi,

Here are my testing bundles : http://13.76.187.81/tykbundle/
Here is my API configuration (old bundle : bundle.zip, new bundle : bundle002.zip):

{
    "id": "589426519f1c9793538fd067",
    "name": "Home with Bundle",
    "slug": "home-with-bundle",
    "api_id": "8d0a5bdbf9d04f594958f9aef51d6c36",
    "org_id": "587f29df9f1c9793538fd053",
    "use_keyless": false,
    "use_oauth2": false,
    "use_openid": false,
    "openid_options": {
        "providers": [],
        "segregate_by_client": false
    },
    "oauth_meta": {
        "allowed_access_types": [],
        "allowed_authorize_types": [],
        "auth_login_redirect": ""
    },
    "auth": {
        "use_param": false,
        "param_name": "",
        "use_cookie": false,
        "cookie_name": "",
        "auth_header_name": ""
    },
    "use_basic_auth": false,
    "enable_jwt": false,
    "use_standard_auth": false,
    "enable_coprocess_auth": true,
    "jwt_signing_method": "",
    "jwt_source": "",
    "jwt_identity_base_field": "",
    "jwt_client_base_field": "",
    "jwt_policy_field_name": "",
    "notifications": {
        "shared_secret": "",
        "oauth_on_keychange_url": ""
    },
    "enable_signature_checking": false,
    "hmac_allowed_clock_skew": -1,
    "base_identity_provided_by": "",
    "definition": {
        "location": "header",
        "key": "x-api-version"
    },
    "version_data": {
        "not_versioned": true,
        "versions": {
            "Default": {
                "name": "Default",
                "expires": "",
                "paths": {
                    "ignored": [],
                    "white_list": [],
                    "black_list": []
                },
                "use_extended_paths": true,
                "extended_paths": {},
                "global_headers": {},
                "global_headers_remove": [],
                "global_size_limit": 0,
                "override_target": ""
            }
        }
    },
    "uptime_tests": {
        "check_list": [],
        "config": {
            "expire_utime_after": 0,
            "service_discovery": {
                "use_discovery_service": false,
                "query_endpoint": "",
                "use_nested_query": false,
                "parent_data_path": "",
                "data_path": "",
                "port_data_path": "",
                "target_path": "",
                "use_target_list": false,
                "cache_timeout": 60,
                "endpoint_returns_list": false
            },
            "recheck_wait": 0
        }
    },
    "proxy": {
        "preserve_host_header": false,
        "listen_path": "/home-with-bundle/",
        "target_url": "http://13.76.101.247:9001/",
        "strip_listen_path": true,
        "enable_load_balancing": false,
        "target_list": [],
        "check_host_against_uptime_tests": false,
        "service_discovery": {
            "use_discovery_service": false,
            "query_endpoint": "",
            "use_nested_query": false,
            "parent_data_path": "",
            "data_path": "hostname",
            "port_data_path": "port",
            "target_path": "/api-slug",
            "use_target_list": false,
            "cache_timeout": 60,
            "endpoint_returns_list": false
        }
    },
    "disable_rate_limit": false,
    "disable_quota": false,
    "custom_middleware": {
        "pre": [],
        "post": [],
        "post_key_auth": [],
        "auth_check": {
            "name": "",
            "path": "",
            "require_session": false
        },
        "response": [],
        "driver": "",
        "id_extractor": {
            "extract_from": "",
            "extract_with": "",
            "extractor_config": {}
        }
    },
    "custom_middleware_bundle": "bundle002",
    "cache_options": {
        "cache_timeout": 60,
        "enable_cache": true,
        "cache_all_safe_requests": false,
        "cache_response_codes": [],
        "enable_upstream_cache_control": false
    },
    "session_lifetime": 0,
    "active": true,
    "auth_provider": {
        "name": "",
        "storage_engine": "",
        "meta": {}
    },
    "session_provider": {
        "name": "",
        "storage_engine": "",
        "meta": null
    },
    "event_handlers": {
        "events": {}
    },
    "enable_batch_request_support": false,
    "enable_ip_whitelisting": false,
    "allowed_ips": [],
    "dont_set_quota_on_create": false,
    "expire_analytics_after": 0,
    "response_processors": [],
    "CORS": {
        "enable": true,
        "allowed_origins": [],
        "allowed_methods": [
            "GET"
        ],
        "allowed_headers": [
            "Authorization"
        ],
        "exposed_headers": [],
        "allow_credentials": false,
        "max_age": 24,
        "options_passthrough": true,
        "debug": false
    },
    "domain": "",
    "do_not_track": false,
    "tags": [],
    "enable_context_vars": false
}

Hi,

is there any update regarding to this problem ?

Thank You

Hi, I’m not able to reproduce it. Still researching it.

Hi,

I am afraid that I have configured it wrong, but I can’t find it. I have followed all details of installing tyk and creating plugin. would you like to try to access my installed tyk gateway ?

(it’s still an experiment one) if you like to try it, I can send you an email to access it.

Thanks

Yes, I will write you a private message here.

Hi,
I’m new to Tyk and am trying to add a Python custom authentication plugin based on the tutorial for Docker at //tyk.io/docs/plugins/supported-languages/rich-plugins/python/custom-auth-python-tutorial/. I followed the steps mentioned there but could not get the plugin to work.

I’m having trouble getting the example plugin to work. My test api was working prior to changing its config to use custom authentication from token authentication. When I updated the API to use custom auth, I’m not getting any response when invoking the same API. I got "Could not get any response. There was an error connecting to .

Questions:

  • This tutorial suggests restart the tyk-gateway service after making the API config changes. However, I remember seeing another post on tyk.io (can’t remember exactly where) where it suggests I should start the tyk-gateway-python process and stop the tyk-gateway process if I’m using Python plugin. Which is correct? I did try to stop tyk-gateway and start tyk-gateway-python, but the later process failed to start. I didn’t see any error in tyk log files.

  • Is there a more detailed document on how to set up the Python based custom authentication plugin? If so, can you point me to the page?

Thanks,
-Jeffrey

Hi @jeffrngu, thanks for the report, the following is required to use the Python build:

service tyk-gateway stop
service tyk-gateway-python start

From this point you should always use tyk-gateway-python, e.g. service tyk-gateway-python restart.

This Tyk build is linked against a specific version of Python, so if it’s failing and you don’t get any log lines, try to run the binary in a manual way, the output of these two commands will be useful for us:

cd /opt/tyk-gateway
./tyk-python

And also:

cd /opt/tyk-gateway
ldd ./tyk-python

Thanks!

Hi @matiasb,
Thanks for the quick reply. I’m running Tyk docker containers using Kitematic. When I stopped the tyk-gateway process, the container is also stopped. That prevents me from stopping tyk-gateway to start tyk-gateway-python. So what I did was I copied tyk-gateway-python to tyk-gateway. I also copied /etc/init.d/tyk-gateway-python to /etc/init.d/tyk-gateway. Then I restarted my tyk_gateway container. This seemed to force the tyk-gateway-python process to start (I can tell from looking at the container logs on Kiematic.

So with that, my test-api still not working as expected. I’m still getting “Could not get any response”. Please find below some additional info.

During tyk-gateway startup process, I see the following error from Kitematic container log. It looks like the directory includes the bundle.zip. I confirmed there’s no /opt/tyk-gateway/middleware/bundles/ directory.

time=“Oct 6 17:29:26” level=error msg=“Couldn’t create bundle directory: mkdir middleware/bundles/242e25605eee42db66c7bbb81b7c46b4-bundle.zip: no such file or directory” api_id=242e25605eee42db66c7bbb81b7c46b4 org_id=59cd4afc50827d0001291c5c path=- server_name=“http://www.google.com/” user_id=- user_ip=-

I’ve confirmed that the bundle.zip is serving fine from the url I configure in tyk.conf. Please see below.

root@792fbbd658e6:/opt/tyk-gateway# grep bundle_base_url tyk.conf
“bundle_base_url”: “http://localhost:8000/”,
root@792fbbd658e6:/opt/tyk-gateway# curl http://localhost:8000
127.0.0.1 - - [06/Oct/2017 17:36:32] “GET / HTTP/1.1” 200 -

Directory listing for /

Directory listing for /



root@792fbbd658e6:/opt/tyk-gateway#

*** tyk-gateway start-up log from Kitematic container log:
time=“Oct 6 17:27:39” level=info msg=“Processed and listening on: /portal-assets/{rest:.}"
time=“Oct 6 17:27:39” level=info msg="Processed and listening on: /portal-api/{rest:.
}”
time=“Oct 6 17:27:39” level=info msg=“Processed and listening on: /test-api/{rest:.}"
time=“Oct 6 17:27:39” level=info msg="Processed and listening on: /portal/{rest:.
}”
time=“Oct 6 17:27:39” level=info msg=“Loading uptime tests…”
time=“Oct 6 17:27:39” level=info msg=“Initialised API Definitions”
time=“Oct 6 17:27:39” level=info msg=“Loading policies”
time=“Oct 6 17:27:39” level=info msg=“Using Policies from Dashboard Service”
time=“Oct 6 17:27:39” level=info msg=“Mutex lock acquired… calling”
time=“Oct 6 17:27:39” level=info msg=“Calling dashboard service for policy list”
time=“Oct 6 17:27:39” level=info msg=“Processing policy list”
time=“Oct 6 17:27:39” level=info msg=“Gateway started (v2.3.9)”
time=“Oct 6 17:27:39” level=info msg=“–> Listening on address: (open interface)”
time=“Oct 6 17:27:39” level=info msg=“–> Listening on port: 8080”
time=“Oct 6 17:27:39” level=info msg=“–> PID: 8”
time=“Oct 6 17:27:40” level=warning msg=“Insecure configuration detected (allowing)!”
time=“Oct 6 17:27:41” level=info msg=“Using /opt/tyk-gateway/tyk.conf for configuration”
time=“Oct 6 17:29:26” level=info msg=“Reloading endpoints”
time=“Oct 6 17:29:26” level=info msg=“Reload queued”
time=“Oct 6 17:29:26” level=info msg=“Initiating reload”
time=“Oct 6 17:29:26” level=info msg=“Loading policies”
time=“Oct 6 17:29:26” level=info msg=“Using Policies from Dashboard Service”
time=“Oct 6 17:29:26” level=info msg=“Mutex lock acquired… calling”
time=“Oct 6 17:29:26” level=info msg=“Calling dashboard service for policy list”
time=“Oct 6 17:29:26” level=info msg=“Processing policy list”
time=“Oct 6 17:29:26” level=info msg=“Detected 4 APIs”
time=“Oct 6 17:29:26” level=info msg=“Preparing new router”
time=“Oct 6 17:29:26” level=info msg=“Initialising Tyk REST API Endpoints”
time=“Oct 6 17:29:26” level=info msg=“Loading API configurations.”
time=“Oct 6 17:29:26” level=info msg=“Tracking hostname” api_name=“Portal Assets” domain=www.tyk-portal-test.com
time=“Oct 6 17:29:26” level=info msg=“Tracking hostname” api_name=“Portal API” domain=www.tyk-portal-test.com
time=“Oct 6 17:29:26” level=info msg=“Tracking hostname” api_name=“Test API” domain=“(no host)”
time=“Oct 6 17:29:26” level=info msg=“Tracking hostname” api_name=Portal domain=www.tyk-portal-test.com
time=“Oct 6 17:29:26” level=info msg=“Loading API” api_name=“Portal Assets”
time=“Oct 6 17:29:26” level=info msg=“Checking security policy: Open” api_name=“Portal Assets”
time=“Oct 6 17:29:26” level=info msg=“Loading API” api_name=“Portal API”
time=“Oct 6 17:29:26” level=info msg=“Checking security policy: Open” api_name=“Portal API”
time=“Oct 6 17:29:26” level=info msg=“Loading API” api_name=“Test API”
time=“Oct 6 17:29:26” level=info msg=“----> Fetching Bundle: bundle.zip”
time=“Oct 6 17:29:26” level=info msg=“Loading API” api_name=Portal
time=“Oct 6 17:29:26” level=info msg=“Checking security policy: Open” api_name=Portal
time=“Oct 6 17:29:26” level=error msg=“Couldn’t create bundle directory: mkdir middleware/bundles/242e25605eee42db66c7bbb81b7c46b4-bundle.zip: no such file or directory” api_id=242e25605eee42db66c7bbb81b7c46b4 org_id=59cd4afc50827d0001291c5c path=- server_name=“http://www.google.com/” user_id=- user_ip=-
time=“Oct 6 17:29:26” level=info msg=“----> Checking security policy: JS Plugin”
time=“Oct 6 17:29:27” level=info msg=“Processed and listening on: /portal-assets/{rest:.}"
time=“Oct 6 17:29:27” level=info msg="Processed and listening on: /portal-api/{rest:.
}”
time=“Oct 6 17:29:27” level=info msg=“Processed and listening on: /test-api/{rest:.}"
time=“Oct 6 17:29:27” level=info msg="Processed and listening on: /portal/{rest:.
}”
time=“Oct 6 17:29:27” level=info msg=“Loading uptime tests…”
time=“Oct 6 17:29:27” level=info msg=“Initialised API Definitions”
time=“Oct 6 17:29:27” level=info msg=“API reload complete”
time=“Oct 6 17:29:27” level=info msg=“Initiating coprocess reload”
time=“Oct 6 17:29:27” level=info msg=“Reloading middlewares”
time=“Oct 6 17:29:27” level=info msg=“Reloading event handlers and middlewares.”

*** When I invoked the test-api, I see the following log:
2017/10/06 17:32:21 http: panic serving 172.18.0.1:48390: runtime error: invalid memory address or nil pointer dereference
goroutine 8147 [running]:
net/http.(*conn).serve.func1(0xc4204f2c80)
/usr/local/go/src/net/http/server.go:1721 +0xd0
panic(0xd10d00, 0x1523cf0)
/usr/local/go/src/runtime/panic.go:489 +0x2cf
main.(*DynamicMiddleware).ProcessRequest(0xc42027db80, 0x15559c0, 0xc42025e540, 0xc4205a4000, 0x0, 0x0, 0x0, 0x0, 0x0)
/src/github.com/TykTechnologies/tyk/plugins.go:166 +0xd61
main.CreateMiddleware.func1.1(0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/middleware.go:76 +0x65b
net/http.HandlerFunc.ServeHTTP(0xc4202ffa80, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc4202ffac0, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc4202ffc00, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc4202ffc40, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/usr/local/go/src/net/http/server.go:1942 +0x44
github.com/TykTechnologies/tyk/vendor/github.com/gorilla/context.ClearHandler.func1(0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/vendor/github.com/gorilla/context/context.go:141 +0x8b
net/http.HandlerFunc.ServeHTTP(0xc42027dc80, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/usr/local/go/src/net/http/server.go:1942 +0x44
github.com/TykTechnologies/tyk/vendor/github.com/gorilla/mux.(*Router).ServeHTTP(0xc4202caa50, 0x15559c0, 0xc42025e540, 0xc4205a4000)
/src/github.com/TykTechnologies/tyk/vendor/github.com/gorilla/mux/mux.go:114 +0x10c
main.mainHandler.ServeHTTP(0x15559c0, 0xc42025e540, 0xc4201efa00)
/src/github.com/TykTechnologies/tyk/main.go:1344 +0x4b
main.(*mainHandler).ServeHTTP(0x16282f0, 0x15559c0, 0xc42025e540, 0xc4201efa00)
:614 +0x63
net/http.serverHandler.ServeHTTP(0xc4205ee160, 0x15559c0, 0xc42025e540, 0xc4201efa00)
/usr/local/go/src/net/http/server.go:2568 +0x92
net/http.(*conn).serve(0xc4204f2c80, 0x1556900, 0xc4202a27c0)
/usr/local/go/src/net/http/server.go:1825 +0x612
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2668 +0x2ce

Hi, can you paste your full log? The gateway initialization lines are useful too.

Also check the plugins section here: Docker

Thanks

Hi, I just edited my original reply with the full log. Thanks for looking.

Just realized I deleted some of the info in the previous reply. Here it is.

root@792fbbd658e6:/var/log# ps -ef|grep tyk
root 9 1 0 16:59 ? 00:00:00 ./tyk --conf=/opt/tyk-gateway/tyk.conf
root 45 29 0 17:03 pts/0 00:00:00 tail -f tyk-gateway.stderr tyk-gateway.stdout
root 47 29 0 17:07 pts/0 00:00:00 grep --color=auto tyk
root@792fbbd658e6:/var/log# cd /opt/tyk-gateway/
root@792fbbd658e6:/opt/tyk-gateway# ldd ./tyk-python
linux-vdso.so.1 => (0x00007ffe7bbfa000)
libpython3.4m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.4m.so.1.0 (0x00007f87cfb2c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f87cf90e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f87cf545000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f87cf31b000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f87cf102000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f87ceefe000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f87cecfb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f87ce9f5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f87d0161000)
root@792fbbd658e6:/opt/tyk-gateway# ldd ./tyk
linux-vdso.so.1 => (0x00007ffe69bcb000)
libpython3.4m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.4m.so.1.0 (0x00007ff4d88e2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff4d86c4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4d82fb000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007ff4d80d1000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007ff4d7eb8000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff4d7cb4000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007ff4d7ab1000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4d77ab000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff4d8f17000)
root@792fbbd658e6:/opt/tyk-gateway# ll tyk*
-rwxr-xr-x 1 root root 25959208 Sep 14 10:09 tyk*
-rwxr-xr-x 1 root root 25729416 Sep 14 10:09 tyk-lua*
-rwxr-xr-x 1 root root 25959208 Sep 14 10:09 tyk-python*
-rw-r–r-- 1 root root 1836 Sep 29 21:19 tyk.conf
-rw-r–r-- 1 root root 1013 Sep 14 10:09 tyk.conf.example
-rw-r–r-- 1 root root 1815 Sep 15 21:44 tyk.conf.orig
-rwxr-xr-x 1 root root 25776273 Sep 14 10:09 tyk.orig*
root@792fbbd658e6:/opt/tyk-gateway# cd /etc/init.d/
root@792fbbd658e6:/etc/init.d# diff tyk-gateway tyk-gateway-python
root@792fbbd658e6:/etc/init.d#

Hi,
One additional question: if I’m hosting the bundle.zip from a protected resource/artifactory which is using basic auth, how would I modify tyk.conf to support that? I’m referring to the attribute “bundle_base_url” in tyk.conf.

You must create the bundles directory manually, you may need to use a file mount. This is a known bug.

Thanks Martin. I manually created the middleware/bundles directory and tyk started without any error. However, when I invoked the test-api, I got the same error. Any idea why it’s throwing error?

I’m not very clear on what you meant by “you may need to use a file mount”? Are you referring to the issue I raised with “bundle_base_url” parameter not supporting authentication? If so, what is the syntax for using “file mount”? Is it just the file absolute path instead of URL to the file?

2017/10/07 21:46:23 http: panic serving 172.18.0.1:48680: runtime error: invalid memory address or nil pointer dereference
goroutine 17112 [running]:
net/http.(*conn).serve.func1(0xc4200d9f40)
/usr/local/go/src/net/http/server.go:1721 +0xd0
panic(0xd10d00, 0x1523cf0)
/usr/local/go/src/runtime/panic.go:489 +0x2cf
main.(*DynamicMiddleware).ProcessRequest(0xc4202cb200, 0x15559c0, 0xc4201e07e0, 0xc4205f9900, 0x0, 0x0, 0x0, 0x0, 0x0)
/src/github.com/TykTechnologies/tyk/plugins.go:166 +0xd61
main.CreateMiddleware.func1.1(0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/src/github.com/TykTechnologies/tyk/middleware.go:76 +0x65b
net/http.HandlerFunc.ServeHTTP(0xc420310a40, 0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc420310ac0, 0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc420310b00, 0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/usr/local/go/src/net/http/server.go:1942 +0x44
main.CreateMiddleware.func1.1(0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/src/github.com/TykTechnologies/tyk/middleware.go:100 +0x85b
net/http.HandlerFunc.ServeHTTP(0xc420310b40, 0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/usr/local/go/src/net/http/server.go:1942 +0x44
github.com/TykTechnologies/tyk/vendor/github.com/gorilla/context.ClearHandler.func1(0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/src/github.com/TykTechnologies/tyk/vendor/github.com/gorilla/context/context.go:141 +0x8b
net/http.HandlerFunc.ServeHTTP(0xc4202cb360, 0x15559c0, 0xc4201e07e0, 0xc4205f9900)
/usr/local/go/src/net/http/server.go:1942 +0x44
github.com/TykTechnologies/tyk/vendor/github.com/gorilla/mux.

By file mount I meant the docker -v (volume) mount option to create the directory.

That’s a pretty serious panic - I assume the panic goes away when yu the use the middleware?

Thanks for the clarification. How does the file mount solve my problem of loading the bundle.zip for my api?
As for the exception, it happens every time I invoked my test-api. Is the custom authentication plugin feature officially supported? If so, is there a more detailed step-by-step page that explains how to set it up?

Thanks,
-Jeffrey