{"id":20722069,"url":"https://github.com/max-lt/nginx-jwt-module","last_synced_at":"2026-01-18T11:22:56.772Z","repository":{"id":41377790,"uuid":"137529771","full_name":"max-lt/nginx-jwt-module","owner":"max-lt","description":"NGINX module to check for a valid JWT.","archived":false,"fork":false,"pushed_at":"2025-03-14T18:40:45.000Z","size":103,"stargazers_count":97,"open_issues_count":1,"forks_count":40,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-10T23:32:44.295Z","etag":null,"topics":["alpine","jwt","light","nginx","nginx-jwt","nginx-module","nginx-proxy"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/max-lt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2018-06-15T20:34:55.000Z","updated_at":"2025-03-28T13:31:00.000Z","dependencies_parsed_at":"2022-09-05T11:21:17.271Z","dependency_job_id":"fd80640b-2d8a-4920-835c-924d83929f93","html_url":"https://github.com/max-lt/nginx-jwt-module","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/max-lt/nginx-jwt-module","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-lt%2Fnginx-jwt-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-lt%2Fnginx-jwt-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-lt%2Fnginx-jwt-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-lt%2Fnginx-jwt-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/max-lt","download_url":"https://codeload.github.com/max-lt/nginx-jwt-module/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-lt%2Fnginx-jwt-module/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28535162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T10:13:46.436Z","status":"ssl_error","status_checked_at":"2026-01-18T10:13:11.045Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["alpine","jwt","light","nginx","nginx-jwt","nginx-module","nginx-proxy"],"created_at":"2024-11-17T03:34:00.754Z","updated_at":"2026-01-18T11:22:56.753Z","avatar_url":"https://github.com/max-lt.png","language":"C","funding_links":[],"categories":["[🎛️ yunohost](https://github.com/stars/ketsapiwiq/lists/yunohost)"],"sub_categories":[],"readme":"[github-license-url]: /blob/master/LICENSE\n[action-docker-url]: https://github.com/max-lt/nginx-jwt-module/actions/workflows/docker.yml\n[github-container-url]: https://github.com/max-lt/nginx-jwt-module/pkgs/container/nginx-jwt-module\n\n# Nginx jwt auth module\n[![License](https://img.shields.io/github/license/maxx-t/nginx-jwt-module.svg)][github-license-url]\n[![Build Status](https://github.com/max-lt/nginx-jwt-module/actions/workflows/docker.yml/badge.svg)][action-docker-url]\n[![Build Status](https://ghcr-badge.deta.dev/max-lt/nginx-jwt-module/size)][action-docker-url]\n\nThis is an NGINX module to check for a valid JWT, this module intend to be as light as possible and to remain simple:\n - Docker image based on the [official nginx Dockerfile](https://github.com/nginxinc/docker-nginx) (alpine).\n - Light image (~400KB more than the official one).\n\n### Table of Contents:\n\n  - [Module configuration](#module-configuration)\n  - [Directives](#directives)\n  - [Embedded variables](#embedded-variables)\n  - [Image](#image)\n  - [Example configurations](#example-configurations)\n\n### Module Configuration:\n\n#### Example Configuration:\n```nginx\n# nginx.conf\nload_module /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so;\n\nhttp {\n    server {\n        auth_jwt_key \"0123456789abcdef\" hex; # Your key as hex string\n        auth_jwt     off;\n\n        # Default auth method is \"Authentication\" header\n        location /secured-by-auth-header/ {\n            auth_jwt on;\n        }\n\n        # But you can use a cookie instead\n        location /secured-by-cookie/ {\n            auth_jwt $cookie_MyCookieName;\n        }\n\n        # JWT keys are inherited from the previous configuration level\n        # but you can have different keys for different locations\n        location /secured-by-auth-header-too/ {\n            auth_jwt_key \"another-secret\"; # Your key as utf8 string\n            auth_jwt on;\n        }\n\n        location /secured-by-rsa-key/ {\n            auth_jwt_key /etc/keys/rsa-public.pem file; # Your key from a PEM file\n            auth_jwt on;\n        }\n\n        location /not-secure/ {}\n    }\n}\n```\n\nNote: don't forget to [load](http://nginx.org/en/docs/ngx_core_module.html#load_module) the module in the main context: \n```nginx\nload_module /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so;\n```\n\n### Directives:\n\n#### auth_jwt\n\n    Syntax:\t auth_jwt $variable | on | off;\n    Default: auth_jwt off;\n    Context: http, server, location\n\nEnables validation of JWT.\n\nThe `auth_jwt $variable` value can be used to set a custom way to get the JWT, for example to get it from a cookie instead of the default `Authentication` header: ` auth_jwt $cookie_MyCookieName;`\n\n\u003chr\u003e\n\n#### auth_jwt_key\n\n    Syntax:\t auth_jwt_key value [encoding];\n    Default: ——\n    Context: http, server, location\n\nSpecifies the key for validating JWT signature (must be hexadecimal).\u003cbr\u003e\nThe *encoding* option may be `hex | utf8 | base64 | file` (default is `utf8`).\u003cbr\u003e\nThe `file` option requires the *value* to be a valid file path (pointing to a PEM encoded key).\n\n\u003chr\u003e\n\n#### auth_jwt_alg\n\n    Syntax:\t auth_jwt_alg any | HS256 | HS384 | HS512 | RS256 | RS384 | RS512 | ES256 | ES384 | ES512;\n    Default: auth_jwt_alg any;\n    Context: http, server, location\n\nSpecifies which algorithm the server expects to receive in the JWT.\n\n\u003chr\u003e\n\n#### auth_jwt_require\n\n    Syntax:\t auth_jwt_require $value ... [error=401 | 403];\n    Default: ——\n    Context: http, server, location\n\nSpecifies additional checks for JWT validation. The authentication will succeed only if all the values are not empty and are not equal to “0”.\n\nThese directives are inherited from the previous configuration level if and only if there are no auth_jwt_require directives defined on the current level.\n\nIf any of the checks fails, the 401 error code is returned. The optional error parameter allows redefining the error code to 403.\n\nExample:\n```nginx\n# server.conf\n\nmap $jwt_claim_role $jwt_has_admin_role {\n    \\\"admin\\\"  1;\n}\n\nmap $jwt_claim_scope $jwt_has_restricted_scope {\n    \\\"restricted\\\"  1;\n}\n\nserver {\n  # ...\n\n  location /auth-require {\n    auth_jwt_require $jwt_has_admin_role error=403;\n    # ...\n  }\n\n  location /auth-compound-require {\n    auth_jwt_require $jwt_has_admin_role $jwt_has_restricted_scope error=403;\n    # ...\n  }\n}\n```\n\n\u003e Note that as `$jwt_claim_` returns a JSON-encoded value, so we have to check `\\\"value\\\"` (and not  `value`)\n\n### Embedded Variables:\nThe ngx_http_auth_jwt_module module supports embedded variables:\n- $jwt_header_*name* returns the specified header value\n- $jwt_claim_*name* returns the specified claim value\n- $jwt_headers returns headers\n- $jwt_payload returns payload\n\n\u003e Note that as all returned values are JSON-encoded, so string will be surrounded by `\"` character\n\n### Image:\nImage is generated with Github Actions (see [nginx-jwt-module:latest][github-container-url])\n\n```\ndocker pull ghcr.io/max-lt/nginx-jwt-module:latest\n```\n\n#### Simply create your image from Github's generated one\n```dockerfile\nFROM ghcr.io/max-lt/nginx-jwt-module:latest\n\n# Copy your nginx conf\n# Don't forget to include this module in your configuration\n# load_module /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so;\nCOPY my-nginx-conf /etc/nginx\n\nEXPOSE 8000\n\nSTOPSIGNAL SIGTERM\n\nCMD [\"nginx\", \"-g\", \"daemon off;\"]\n```\n\n#### Or use the provided one directly\n```bash\ndocker run -p 80:80 \\\n  -v ./nginx.conf:/etc/nginx/nginx.conf \\\n  ghcr.io/max-lt/nginx-jwt-module\n```\n\n### Build:\nThis module is built inside a docker container, from the [nginx](https://hub.docker.com/_/nginx/)-alpine image.\n\n```bash\nmake build # Will create a \"jwt-nginx\" image\n# or\ndocker build -f Dockerfile -t jwt-nginx .\n```\n\n### Test:\n\n#### Default usage:\n```bash\nmake test # Will build a test image and run the test suite\n```\n\n### Example configurations:\n\nIn this section, we will see some examples of how to use this module.\n\n#### Redirect to login page if JWT is invalid:\n```nginx\nload_module /usr/lib/nginx/modules/ngx_http_auth_jwt_module.so;\n\n# ...\n\nhttp {\n    server {\n        listen 80;\n        server_name _;\n\n        auth_jwt_key \"0123456789abcdef\" hex; # Your key as hex string\n        auth_jwt     off;\n\n        location @login_err_redirect {\n            return 302 $scheme://$host:$server_port/login?redirect=$request_uri;\n        }\n\n        location /secure/ {\n            auth_jwt on;\n            error_page 401 = @login_err_redirect;\n        }\n\n        location / {\n            return 200 \"OK\";\n        }\n    }\n}\n```\n\nTrying `curl -i http://localhost/secure/path?param=value` will return a 302 redirect to `/login?redirect=/secure/path?param=value` if the JWT is invalid.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-lt%2Fnginx-jwt-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmax-lt%2Fnginx-jwt-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-lt%2Fnginx-jwt-module/lists"}