https://github.com/tsuru/lua-resty-libjwt
Lua bindings to libjwt (https://github.com/benmcollins/libjwt) using FFI
https://github.com/tsuru/lua-resty-libjwt
authentication authorization jwt lua nginx openresty
Last synced: 29 days ago
JSON representation
Lua bindings to libjwt (https://github.com/benmcollins/libjwt) using FFI
- Host: GitHub
- URL: https://github.com/tsuru/lua-resty-libjwt
- Owner: tsuru
- License: bsd-3-clause
- Created: 2025-02-06T12:18:42.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-10-16T18:42:38.000Z (8 months ago)
- Last Synced: 2025-10-17T17:46:17.516Z (8 months ago)
- Topics: authentication, authorization, jwt, lua, nginx, openresty
- Language: Lua
- Homepage:
- Size: 154 KB
- Stars: 4
- Watchers: 5
- Forks: 1
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# lua-resty-libjwt
[](https://luarocks.org/modules/tsuru/lua-resty-libjwt)
## Overview
The **lua-resty-libjwt** module is a **Lua** library with **C** bindings that validates JWT tokens directly in **Nginx**. Built with **OpenResty** and leveraging **FFI** (Foreign Function Interface), it provides Lua bindings to [libjwt](https://github.com/benmcollins/libjwt). By handling JWT validation at the Nginx level, it prevents unauthorized requests from reaching the API, reducing the load on application servers.
## Requirements
* [Nginx](https://nginx.org) with the [Lua module](https://github.com/openresty/lua-nginx-module)
* [libjwt](https://github.com/benmcollins/libjwt) (≥ 3.2.0)
* [lua-cjson](https://luarocks.org/modules/openresty/lua-cjson) (≥ 2.1.0)
## Install
You can easily install it with [Luarocks](https://luarocks.org):
```bash
luarocks install lua-resty-libjwt
```
## Configuration and Usage
To use **Libjwt**, you need to provide the path to the **jwks.json** file, which contains the public keys for JWT token verification.
### Configuration Parameters
The module accepts the following parameters:
### `jwks_files` (Required)
- An **array of paths** pointing to files containing **JWKS (JSON Web Key Set)** keys.
- At least one file must be valid; otherwise, an error will be returned.
**Configuration example:**
```lua
libjwt.validate({
jwks_files = {"/usr/share/tokens/jwks.json"}
})
```
### `header_token` (Optional)
- Defines the **HTTP header field** where the JWT token will be retrieved.
- The default value is **"Authorization"**.
- If the token is in a different header, this value can be modified.
**Example:**
```lua
libjwt.validate({
jwks_files = {"/usr/share/tokens/jwks.json"},
header_token = "X-Custom-Token"
})
```
### `return_unauthorized_default` (Optional)
- Defines whether a **401 Unauthorized** response should be automatically returned if the token is invalid.
- The default value is **true** (automatically generates an error).
- If set to **false**, the error must be handled manually in `nginx.conf`.
**Example:**
```lua
libjwt.validate({
jwks_files = {"/usr/share/tokens/jwks.json"},
return_unauthorized_default = false
})
```
If `return_unauthorized_default` is **false**, the error must be handled directly:
```lua
local token, err = libjwt.validate({
jwks_files = {"/usr/share/tokens/jwks.json"},
return_unauthorized_default = false
})
```
## Example Nginx Configuration
Here is an example of how to configure **libjwt** in `nginx.conf`:
```perl
server {
listen 80;
location /private {
access_by_lua_block {
local libjwt = require("resty.libjwt")
local token, err = libjwt.validate({
jwks_files = {"/usr/share/tokens/jwks.json"}
})
if token then
-- You may add logic as needed, accessing the JWT claims:
-- token.claim.sub
-- token.claim.iss
end
}
proxy_pass http://your_backend;
}
}
```
### JWT Token Validation
The `libjwt.validate()` function returns the **decoded claim** of the token or an error if the token is invalid.
**Example:**
```lua
local token, err = libjwt.validate()
if token then
ngx.log(ngx.ERR, "Valid JWT token: ", token)
else
ngx.log(ngx.ERR, "Token validation error: ", err)
end
```
### Claims-based Authorization
Some backends are restricted so that only certain users can access them, allowing us to restrict access based on [Claims].
See the Lua configuration `validate_claims` below:
```lua
local libjwt = require("resty.libjwt")
libjwt.validate({
jwks_files = {"/etc/nginx/jwks.json"},
validate_claims = {
iss = {exact = "myiss"},
aud = {one_of = {"audience1", "audience2"}},
sub = {pattern = ".*@mycompany%.com"},
},
})
```
#### Validation Types
Note that we have 3 types of validations:
* `{exact = "TERM"}`: ensures that a claim must be exactly equal to TERM, otherwise the user will receive a 403 (Forbidden)
* `{one_of = {"TERM1", "TERM2"}}`: allows a list of permitted CLAIMS, if not in the list the user will receive a 403 (Forbidden)
* `{pattern = ".*@mycompany%.com"}`: Allows validation using [Lua Pattern Matching](https://www.lua.org/pil/20.2.html), an expression language similar to Regex. In the example above, we can ensure that only users from the mycompany.com domain can access; if the expression doesn't match, the user will receive a 403 (Forbidden)
## Final Considerations
- Ensure that the **jwks.json** file is accessible by Nginx.
- If using a **custom header_token**, make sure the client is sending it correctly.
- The module improves system efficiency by preventing unauthorized requests from reaching the API.