{"id":22268127,"url":"https://github.com/curityio/nginx-lua-phantom-token-plugin","last_synced_at":"2025-10-27T08:40:42.962Z","repository":{"id":40271013,"uuid":"362405345","full_name":"curityio/nginx-lua-phantom-token-plugin","owner":"curityio","description":"An API gateway plugin to introspect opaque access tokens and forward JWT access tokens to APIs","archived":false,"fork":false,"pushed_at":"2025-02-17T16:15:25.000Z","size":113,"stargazers_count":18,"open_issues_count":0,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-28T12:42:44.084Z","etag":null,"topics":["api-gateway","introspection","kong","nginx","oauth2","openresty","phantom-token"],"latest_commit_sha":null,"homepage":"https://curity.io/resources/learn/integration-kong-open-source/","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/curityio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-04-28T09:07:59.000Z","updated_at":"2025-04-29T13:40:03.000Z","dependencies_parsed_at":"2025-07-28T12:31:25.907Z","dependency_job_id":"8f59446d-d150-44d6-b7f1-72890ac46f99","html_url":"https://github.com/curityio/nginx-lua-phantom-token-plugin","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/curityio/nginx-lua-phantom-token-plugin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curityio%2Fnginx-lua-phantom-token-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curityio%2Fnginx-lua-phantom-token-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curityio%2Fnginx-lua-phantom-token-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curityio%2Fnginx-lua-phantom-token-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/curityio","download_url":"https://codeload.github.com/curityio/nginx-lua-phantom-token-plugin/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curityio%2Fnginx-lua-phantom-token-plugin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281241670,"owners_count":26467371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-27T02:00:05.855Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","introspection","kong","nginx","oauth2","openresty","phantom-token"],"created_at":"2024-12-03T11:11:38.215Z","updated_at":"2025-10-27T08:40:42.941Z","avatar_url":"https://github.com/curityio.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Phantom Token Plugin for NGINX LUA Systems\n\n[![Quality](https://img.shields.io/badge/quality-test-yellow)](https://curity.io/resources/code-examples/status/)\n[![Availability](https://img.shields.io/badge/availability-binary-blue)](https://curity.io/resources/code-examples/status/)\n\nA LUA plugin used to introspect opaque access tokens and forward JWT access tokens to APIs.\n\n## The Phantom Token Pattern\n\nThe [Phantom Token Pattern](https://curity.io/resources/learn/phantom-token-pattern/) is a privacy preserving pattern in API security.\\\nIt ensures that access tokens returned to internet clients are kept confidential.\\\nIt also externalizes introspection and caching from APIs, to keep the API security code simple.\n\n![Phantom Token Pattern](images/phantom-token-pattern.png)\n\n## Installation\n\n### Kong API Gateway\n\nIf you are using luarocks, execute the following command to install the plugin:\n\n```bash\nluarocks install kong-phantom-token 2.0.1\n```\n\nOr deploy the .lua files into Kong's plugin directory, eg `/usr/local/share/lua/5.1/kong/plugins/phantom-token`.\n\n### OpenResty\n\nIf you are using luarocks, execute the following command to install the plugin:\n\n```bash\nluarocks install lua-resty-phantom-token 2.0.1\n```\n\nOr deploy the `access.lua` file to `resty/phantom-token.lua`, where the resty folder is in the `lua_package_path`.\\\nA typical install location for LUA files is at `/usr/local/openresty/luajit/share/lua/5.1/resty`.\n\n## Required Configuration Directives\n\nAll of the settings in this section are required:\n\n#### introspection_endpoint\n\n\u003e **Syntax**: **`introspection_endpoint`** `string`\n\u003e\n\u003e **Context**: `location`\n\nThe URL to the introspection endpoint of the Curity Identity Server.\n\n#### client_id\n\n\u003e **Syntax**: **`client_id`** `string`\n\u003e\n\u003e **Context**: `location`\n\nThe ID of the introspection client configured in the Curity Identity Server.\n\n#### client_secret\n\n\u003e **Syntax**: **`client_secret`** `string`\n\u003e\n\u003e **Context**: `location`\n\nThe string secret of the introspection client configured in the Curity Identity Server.\n\n## Optional Configuration Directives\n\n#### token_cache_seconds\n\n\u003e **Syntax**: **`token_cache_seconds`** `number`\n\u003e\n\u003e **Context**: `location`\n\u003e\n\u003e **Default**: 300\n\nThe maximum time for which introspected JWTs are cached by the plugin.\\\nThis is overridden if the introspection endpoint returns a `max-age` header with a lower value.\\\nThis header derives from the `access-token-ttl` setting for the client that sent the access token.\\\nThis logic helps to prevent an access token from being cached for longer than its lifetime.\n\n#### scope\n\n\u003e **Syntax**: **`scope`** `string`\n\u003e\n\u003e **Context**: `location`\n\u003e\n\u003e **Default**: *`—`*\n\nCan be configured if you want to verify scopes in the gateway.\\\nTo do so, specify the required values(s) for the location as a space separated string, such as `read write`.\\\nAfter succesful introspection, if one or more scopes are not present, the plugin will return a 403 error.\n\n#### verify_ssl\n\n\u003e **Syntax**: **`verify_ssl`** `boolean`\n\u003e\n\u003e **Context**: `location`\n\u003e\n\u003e **Default**: *true*\n\nA convenience option that should only be used during development.\\\nThis setting can be set to `false` if using untrusted server certificates in the Curity Identity Server.\\\nAlternatively you can specify trusted CA certificates via the `lua_ssl_trusted_certificate` directive.\n\n## Example Configurations\n\n### Kong API Gateway\n\nFor each API route, configure the plugin using configuration similar to the following:\n\n```yaml\n- name: myapi\n  url: https://api-internal.example.com:3000\n  routes:\n  - name: myapi-route\n    paths:\n    - /api\n  plugins:\n  - name: phantom-token\n    config:\n      introspection_endpoint: https://login.example.com/oauth/v2/oauth-introspect\n      client_id: introspection-client\n      client_secret: Password1\n      token_cache_seconds: 900\n```\n\nWhen deploying Kong, set an environment variable to activate the plugin in `KONG_PLUGINS`.\\\nAlso define a LUA shared dictionary named `phantom-token` for caching introspection results.\\\nThis  must be provided to Kong via the `KONG_NGINX_HTTP_LUA_SHARED_DICT` environment variable:\n\n```yaml\nenvironment:\n  KONG_DATABASE: 'off'\n  KONG_DECLARATIVE_CONFIG: '/usr/local/kong/declarative/kong.yml'\n  KONG_PROXY_LISTEN: '0.0.0.0:3000'\n  KONG_LOG_LEVEL: 'info'\n  KONG_PLUGINS: 'bundled,phantom-token'\n  KONG_NGINX_HTTP_LUA_SHARED_DICT: 'phantom-token 10m'\n```\n\n### OpenResty\n\nIf using OpenResty, then first configure the cache for introspection results:\n\n```nginx\nhttp {\n    lua_shared_dict phantom-token 10m;\n    server {\n        ...\n    }\n}\n```\n\nThen apply the plugin to one or more locations with configuration similar to the following:\n\n```nginx\nlocation ~ ^/api {\n\n    rewrite_by_lua_block {\n\n        local config = {\n            introspection_endpoint = 'https://login.example.com/oauth/v2/oauth-introspect',\n            client_id = 'introspection-client',\n            client_secret = 'Password1',\n            token_cache_seconds = 900\n        }\n\n        local phantomTokenPlugin = require 'resty.phantom-token'\n        phantomTokenPlugin.execute(config)\n    }\n\n    proxy_pass https://api-internal.example.com:3000;\n}\n```\n\n### Advanced Configurations\n\nYou can apply the plugin to a subset of the API routes, or use the advanced routing features of the reverse proxy.\\\nThe following Kong configuration is for a use case where a route handles both JWTs and opaque tokens.\\\nThis might enable a microservice developer to forward a JWT an upstream microservice behind a gateway.\n\n```yaml\n- name: myapi\n  url: https://api-internal.example.com:3000\n  routes:\n  - name: bypass\n    paths:\n    - /api\n    headers:\n      authorization: [\"~*[Bb]earer\\\\s*[A-Za-z0-9-_]*.[A-Za-z0-9-_]*.[A-Za-z0-9-_]*\"]\n\n  - name: phantom-token\n    paths:\n    - /api\n    plugins:\n    - name: phantom-token\n      config:\n        introspection_endpoint: https://login.example.com/oauth/v2/oauth-introspect\n        client_id: introspection-client\n        client_secret: Password1\n        token_cache_seconds: 900\n```\n\nThe equivalent OpenResty configuration is shown in [these tests](/t/advanced_routing.t).\n\n## Deployment\n\nThe example [Docker Compose File](/docker/docker-compose.yml) provides OpenResty and Kong deployment examples.\n\n## Development and Testing\n\nThe following resources provide further details on how to make code changes to this repo:\n\n- [Kong Phantom Token Tutorial](https://curity.io/resources/learn/integration-kong-open-source/)\n- [OpenResty Phantom Token Tutorial](https://curity.io/resources/learn/integration-openresty/)\n- [Wiki](https://github.com/curityio/kong-phantom-token-plugin/wiki)\n\n## More Information\n\nPlease visit [curity.io](https://curity.io/) for more information about the Curity Identity Server.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcurityio%2Fnginx-lua-phantom-token-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcurityio%2Fnginx-lua-phantom-token-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcurityio%2Fnginx-lua-phantom-token-plugin/lists"}