{"id":15681171,"url":"https://github.com/peter-evans/paseto-lua","last_synced_at":"2025-05-07T12:11:31.772Z","repository":{"id":77843089,"uuid":"134706801","full_name":"peter-evans/paseto-lua","owner":"peter-evans","description":"PASETO (Platform-Agnostic Security Tokens) for Lua","archived":false,"fork":false,"pushed_at":"2023-08-06T07:04:34.000Z","size":136,"stargazers_count":11,"open_issues_count":2,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-31T09:51:09.357Z","etag":null,"topics":["authenticated-encryption","authorization","authorization-token","ed25519","jose","jwt","libsodium","lua","paseto","stateless-token"],"latest_commit_sha":null,"homepage":"","language":"Lua","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/peter-evans.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},"funding":{"github":"peter-evans"}},"created_at":"2018-05-24T11:38:42.000Z","updated_at":"2023-04-29T00:34:47.000Z","dependencies_parsed_at":"2025-03-11T03:40:57.380Z","dependency_job_id":null,"html_url":"https://github.com/peter-evans/paseto-lua","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-evans%2Fpaseto-lua","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-evans%2Fpaseto-lua/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-evans%2Fpaseto-lua/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peter-evans%2Fpaseto-lua/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peter-evans","download_url":"https://codeload.github.com/peter-evans/paseto-lua/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252873904,"owners_count":21817715,"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","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":["authenticated-encryption","authorization","authorization-token","ed25519","jose","jwt","libsodium","lua","paseto","stateless-token"],"created_at":"2024-10-03T16:50:17.350Z","updated_at":"2025-05-07T12:11:31.766Z","avatar_url":"https://github.com/peter-evans.png","language":"Lua","readme":"# [PASETO](https://paseto.io/) (Platform-Agnostic Security Tokens) for Lua\n[![luarocks](https://img.shields.io/badge/luarocks-paseto-blue.svg)](https://luarocks.org/modules/peterevans/paseto)\n[![Build Status](https://travis-ci.org/peter-evans/paseto-lua.svg?branch=master)](https://travis-ci.org/peter-evans/paseto-lua)\n[![Coverage Status](https://coveralls.io/repos/github/peter-evans/paseto-lua/badge.svg?branch=master)](https://coveralls.io/github/peter-evans/paseto-lua?branch=master)\n\nPaseto (Platform-Agnostic SEcurity TOkens) is a specification and reference implementation for secure stateless tokens.\n\n\u003e__*\"Paseto is everything you love about JOSE (JWT, JWE, JWS) without any of the [many design deficits that plague the JOSE standards](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid).\"*__\n\n— [paragonie/paseto](https://github.com/paragonie/paseto)\n\n## Feature Support\n\n| v1.local | v1.public | v2.local | v2.public |\n| :---: | :---: | :---: | :---: |\n| :x: | :x: | :heavy_check_mark: | :heavy_check_mark: |\n\nThis implementation doesn't support the v1 protocol. Please note that v1 should only be used by legacy systems that cannot use modern cryptography.\n\n#### Roadmap\n\n- [x] v2 local authentication (Blake2b and XChaCha20-Poly1305)\n- [x] v2 public authentication (Ed25519 signatures)\n- [x] JSON payload and footer processing\n- [x] Registered claims validation\n- [x] Custom claims validation\n- [ ] High-level token builder API\n- [ ] Integrated key ID (kid) support\n- [ ] API documentation\n\n## Installation\n\n#### Sodium Crypto Library\n\nThis Lua module depends on the [Sodium crypto library (libsodium)](https://github.com/jedisct1/libsodium).\nThe following is a convenient way to install libsodium via LuaRocks. Alternatively, see [libsodium's documentation](https://download.libsodium.org/doc/installation/) for full installation instructions.\n```\nluarocks install libsodium\n```\n\n#### Lua CJSON\n\nThis module also has a dependency on [lua-cjson](https://luarocks.org/modules/openresty/lua-cjson).\nDue to an issue with the latest version you might need to specify an earlier stable version.\nIf you let luarocks install this dependency for you when installing PASETO you might experience problems.\nAdditionally, if using Lua 5.3 you need to build Lua with a compatibility flag for Lua 5.1.\n\n| Lua | Lua CJSON install | Lua compatibility flags |\n| :---: | :---: | :---: |\n| 5.1 | `luarocks install lua-cjson 2.1.0` | |\n| 5.2 | `luarocks install lua-cjson 2.1.0` | |\n| 5.3 | `luarocks install lua-cjson 2.1.0` | -DLUA_COMPAT_5_1 |\n| Lua JIT 2.0 | `luarocks install lua-cjson 2.1.0` | |\n| Lua JIT 2.1 | `luarocks install lua-cjson 2.1.0.6` | |\n\nSee [.travis.yml](.travis.yml) for build configurations.\n\n#### PASETO\n\nFinally, install PASETO:\n```\nluarocks install paseto\n```\n\n## Usage\n\n__v2.local__ :\n```lua\nlocal paseto = require \"paseto.v2\"\n\nlocal key, payload_claims, token, footer_claims, claim_rules\nlocal extracted_footer_claims, extracted_footer, decrypted_claims, enforced_claims\npayload_claims = {\n  iss = \"paragonie.com\",\n  jti = \"87IFSGFgPNtQNNuw0AtuLttP\",\n  aud = \"some-audience.com\",\n  sub = \"test\",\n  iat = \"2018-01-01T00:00:00+00:00\",\n  nbf = \"2018-01-01T00:00:00+00:00\",\n  exp = \"2099-01-01T00:00:00+00:00\",\n  data = \"this is a secret message\",\n  myclaim = \"required value\"\n}\nfooter_claims = { kid = \"MDlCMUIwNzU4RTA2QzZFMDQ4\" }\nclaim_rules = {\n  claim_1 = { claim = \"IssuedBy\", value = \"paragonie.com\" },\n  claim_2 = { claim = \"IdentifiedBy\", value = \"87IFSGFgPNtQNNuw0AtuLttP\" },\n  claim_3 = { claim = \"ForAudience\", value = \"some-audience.com\" },\n  claim_4 = { claim = \"Subject\", value = \"test\" },\n  claim_5 = { claim = \"NotExpired\", value = \"\" },\n  claim_6 = { claim = \"ValidAt\", value = \"\" },\n  claim_7 = { claim = \"ContainsClaim\", value = \"data\" },\n  claim_8 = { claim = \"myclaim\", value = \"required value\" }\n}\n\n-- generate symmetric key\nkey = paseto.generate_symmetric_key()\n\n-- encrypt/decrypt without footer and without enforcing claim rules\ntoken = paseto.encrypt(key, payload_claims)\ndecrypted_claims = paseto.decrypt(key, token)\n\n-- encrypt with footer\ntoken = paseto.encrypt(key, payload_claims, footer_claims)\n\n-- extract footer claims (e.g. to determine public key from kid claim)\nextracted_footer_claims, extracted_footer = paseto.extract_footer_claims(token)\n\n-- decrypt without enforcing claim rules\ndecrypted_claims = paseto.decrypt(key, token, nil, extracted_footer)\n\n-- decrypt and enforce claim rules\nenforced_claims = paseto.decrypt(key, token, claim_rules, extracted_footer)\n```\n\n__v2.public__ :\n```lua\nlocal paseto = require \"paseto.v2\"\n\nlocal secret_key, public_key, payload_claims, token, footer_claims, claim_rules\nlocal extracted_footer_claims, extracted_footer, verified_claims, enforced_claims\npayload_claims = {\n  iss = \"paragonie.com\",\n  jti = \"87IFSGFgPNtQNNuw0AtuLttP\",\n  aud = \"some-audience.com\",\n  sub = \"test\",\n  iat = \"2018-01-01T00:00:00+00:00\",\n  nbf = \"2018-01-01T00:00:00+00:00\",\n  exp = \"2099-01-01T00:00:00+00:00\",\n  data = \"this is a signed message\",\n  myclaim = \"required value\"\n}\nfooter_claims = { kid = \"MDlCMUIwNzU4RTA2QzZFMDQ4\" }\nclaim_rules = {\n  claim_1 = { claim = \"IssuedBy\", value = \"paragonie.com\" },\n  claim_2 = { claim = \"IdentifiedBy\", value = \"87IFSGFgPNtQNNuw0AtuLttP\" },\n  claim_3 = { claim = \"ForAudience\", value = \"some-audience.com\" },\n  claim_4 = { claim = \"Subject\", value = \"test\" },\n  claim_5 = { claim = \"NotExpired\", value = \"\" },\n  claim_6 = { claim = \"ValidAt\", value = \"\" },\n  claim_7 = { claim = \"ContainsClaim\", value = \"data\" },\n  claim_8 = { claim = \"myclaim\", value = \"required value\" }\n}\n\n-- generate key pair\nsecret_key, public_key = paseto.generate_asymmetric_secret_key()\n\n-- sign/verify without footer and without enforcing claim rules\ntoken = paseto.sign(secret_key, payload_claims)\nverified_claims = paseto.verify(public_key, token)\n\n-- sign with footer\ntoken = paseto.sign(secret_key, payload_claims, footer_claims)\n\n-- extract footer claims (e.g. to determine public key from kid claim)\nextracted_footer_claims, extracted_footer = paseto.extract_footer_claims(token)\n\n-- verify without enforcing claim rules\nverified_claims = paseto.verify(public_key, token, nil, extracted_footer)\n\n-- verify and enforce claim rules\nenforced_claims = paseto.verify(public_key, token, claim_rules, extracted_footer)\n```\n\n#### Core API\nThis low-level API should only be used when you cannot use JSON for payload claims and footer claims.\n\n__v2.local__ :\n```lua\nlocal paseto = require \"paseto.v2.core\"\n\nlocal key, message, token, footer, extracted_footer, decrypted\nmessage = \"my secret message\"\nfooter = \"my footer\"\n\n-- generate symmetric key\nkey = paseto.generate_symmetric_key()\n\n-- encrypt/decrypt without footer\ntoken = paseto.encrypt(key, message)\ndecrypted = paseto.decrypt(key, token)\n\n-- encrypt/decrypt with footer\ntoken = paseto.encrypt(key, message, footer)\nextracted_footer = paseto.extract_footer(token)\ndecrypted = paseto.decrypt(key, token, extracted_footer)\n```\n\n__v2.public__ :\n```lua\nlocal paseto = require \"paseto.v2.core\"\n\nlocal secret_key, public_key, message, token, footer, extracted_footer, verified\nmessage = \"my signed message\"\nfooter = \"my footer\"\n\n-- generate key pair\nsecret_key, public_key = paseto.generate_asymmetric_secret_key()\n\n-- sign/verify without footer\ntoken = paseto.sign(secret_key, message)\nverified = paseto.verify(public_key, token)\n\n-- sign/verify with footer\ntoken = paseto.sign(secret_key, message, footer)\nextracted_footer = paseto.extract_footer(token)\nverified = paseto.verify(public_key, token, extracted_footer)\n```\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details\n","funding_links":["https://github.com/sponsors/peter-evans"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-evans%2Fpaseto-lua","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeter-evans%2Fpaseto-lua","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeter-evans%2Fpaseto-lua/lists"}