{"id":19736106,"url":"https://github.com/arnauld/jwtd","last_synced_at":"2025-04-30T04:31:57.533Z","repository":{"id":38214616,"uuid":"363845725","full_name":"Arnauld/jwtd","owner":"Arnauld","description":"Simple WebServices that sign JWT's claims (with private RSA key)","archived":false,"fork":false,"pushed_at":"2025-02-17T09:46:24.000Z","size":260,"stargazers_count":2,"open_issues_count":0,"forks_count":4,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-04-05T22:31:57.462Z","etag":null,"topics":["jwt","rust","webserver"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/Arnauld.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2021-05-03T07:08:52.000Z","updated_at":"2025-02-17T13:35:36.000Z","dependencies_parsed_at":"2024-09-14T01:52:12.537Z","dependency_job_id":"37d02915-f53f-42b8-a318-2d5522d3bcd4","html_url":"https://github.com/Arnauld/jwtd","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arnauld%2Fjwtd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arnauld%2Fjwtd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arnauld%2Fjwtd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Arnauld%2Fjwtd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Arnauld","download_url":"https://codeload.github.com/Arnauld/jwtd/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251643044,"owners_count":21620412,"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":["jwt","rust","webserver"],"created_at":"2024-11-12T01:05:17.355Z","updated_at":"2025-04-30T04:31:57.527Z","avatar_url":"https://github.com/Arnauld.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JWTd\n\n[![GitHub license](https://img.shields.io/github/license/Arnauld/jwtd.svg)](https://github.com/Arnauld/jwtd/blob/master/LICENSE)\n[![GitHub release](https://img.shields.io/github/release/Arnauld/jwtd.svg)](https://GitHub.com/Arnauld/jwtd/releases/)\n[![Docker](https://badgen.net/badge/icon/docker?icon=docker\u0026label)](https://hub.docker.com/r/technbolts/jwtd/tags)\n[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/Arnauld/jwtd/Rust)](https://github.com/Arnauld/jwtd/actions/workflows/rust.yml)\n\n      curl  -d '{\"aid\":\"AGENT:007\", \"huk\":[\"r001\", \"r002\"]}' \\\n            -H \"Content-Type: application/json\" \\\n            http://localhost:8080/sign?generate=iat,exp,iss\n\n\n      curl -d '{\"aid\":\"AGENT:007\", \"huk\":[\"r001\", \"r002\"], \"iss\":\"tok\"}' \\\n            -H \"Content-Type: application/json\" \\\n            -H \"x-api-key: $API_KEY\" \\\n            http://localhost:$PORT/sign?generate=iat,exp\n\n\n      echo -n '{\"hash\":\"$2b$07$WkBvSy5KcOQ4Wm1WhgVJveS4xYHOlGFP/c5kwb7Xz3H15/1lXFEZK\", \"plain\":\"CarmenMcCallum\"}' \u003e tmp/data.txt\n      curl -X POST -d @tmp/data.txt \\\n            -H \"Content-Type: application/json\" \\\n            http://localhost:$PORT/bcrypt/check\n\n\n\nIf `jwt` cli is installed (https://github.com/mike-engel/jwt-cli)\n\n      curl  -s -d '{\"aid\":\"AGENT:007\", \"huk\":[\"r001\", \"r002\"]}' \\\n            -H \"Content-Type: application/json\" \\\n            http://localhost:8080/sign?generate=iat,exp,iss \\\n            | jwt decode -\n\nOverride default token duration (when generating `exp`)\n\n      curl  -d '{\"aid\":\"AGENT:007\", \"huk\":[\"r001\", \"r002\"]}' \\\n            -H \"Content-Type: application/json\" \\\n            http://localhost:8080/sign?generate=iat,exp,iss\u0026duration_seconds=180\n\n## Building and Running a Cargo Project\n\n      cargo build\n\n      cd local\n      # start jwtd server\n      ./start-dev.sh\n\n      cd local\n      # launch sample usecases\n      ./usecases.sh\n\n### Powershell\n\n````powershell\n$Env:JWT_PRIV_KEY_LOCATION=\"$pwd\\local\\key_prv.pem\"\ncargo run\n````\n\n## Release\n\n      # 1. update Cargo.toml/package.version\n      cargo install cargo-edit\n      cargo set-version 0.6.1\n\n      # 2. build app (this also update Cargo.lock)\n      cargo build --release\n\n      # 3. track all changes\n      git add Cargo.toml Cargo.lock README.md\n      git commit -m \"release: v0.6.1\"\n      git tag v0.6.1\n      \n      # 4. push changes, this will trigger github action and release Docker image\n      git push --tags\n\n\nTroubleshoots when installing `cargo-edit`\n\n      sudo apt update\n      sudo apt install pkg-config libssl-dev\n\n\nDebug release (dependency hell!!)\n\n````bash\npodman run \\\n-v $(pwd)/src:/home/rust/src/src \\\n-v $(pwd)/Cargo.toml:/home/rust/src/Cargo.toml \\\n-v $(pwd)/Cargo.lock:/home/rust/src/Cargo.lock \\\n-w /home/rust/src \\\n-it rust:1.67.0 /bin/bash\n#-it ekidd/rust-musl-builder:1.57.0 /bin/bash\n````\n\n\n## Docker (or without rust env.) build\n\n      podman build -t technbolts/jwtd:LOCAL .\n      podman run -v $(pwd)/local:/keys -e JWT_PRIV_KEY_LOCATION=/keys/key_prv.pem  -it technbolts/jwtd:LOCAL\n\n      docker tag -i 7358d9f4b652 technbolts/jwtd:0.1.0\n      docker login -u xxxx -p xxxx\n      docker push technbolts/jwtd:0.1.0\n\n## Local setup (for testing purpose)\n\n      openssl genrsa -out key_prv.pem 2048\n      openssl rsa -in key_prv.pem -outform PEM -pubout -out key_pub.pem\n\n\n# Troubleshoots\n\n      error: linker `cc` not found\n      |\n      = note: No such file or directory (os error 2)\n\n      sudo apt install build-essential\n\n# Buffer\n\n        #!/bin/bash\n        function urldecode() { : \"${*//+/ }\"; echo -e \"${_//%/\\\\x}\"; }\n        DATA_B64ENC=$(cat data.b64-urlencoded)\n        DATA_B64DEC=$(urldecode $DATA_B64ENC)\n        echo $DATA_B64DEC \u003e data.b64\n        cat data.b64 | base64 -d \u003e data.raw\n        openssl rsautl -inkey priv_key.pem -decrypt -oaep -in data.raw\n\n# Environment Variables\n\nThis application supports several environment variables to control its behavior.\n\n## Server configuration\n- **`ADDR`**:\nThe bind address to listen for requests\n- **`PORT`**:\nThe port to listen for requests\n- **`RUST_LOG`**:\nControls the logging level for Rust applications, allowing you to specify which logs should be shown during the execution. By setting this variable, you can adjust the verbosity of the logs for debugging or monitoring purposes.\n- **`URL_PREFIX`**:\nOptional : let you configure a prefix to all endpoints, e.g. if you set URL_PREFIX=jwtd, then a valid sign http query will look like (notice target url change) :\n    \n      curl  -d '{\"aid\":\"AGENT:007\", \"huk\":[\"r001\", \"r002\"]}' -H \"Content-Type: application/json\" http://localhost:8080/jwtd/sign?generate=iat,exp,iss\n\n  \"/\" characters can be included or not in the env variable, because they are ignored. URL_PREFIX=/jwtd/ will have the same effect as above. Thus, url prefixes with multiple levels are not supported: URL_PREFIX=/jw/td/ will behave like URL_PREFIX=jwtd.\n\n## Token configuration\n- **`API_KEYS`**:\nA list of API keys used to authenticate requests. This variable should contain a comma-separated list of keys.\n- **`JWT_ISSUER`**:\niss claims value if required in 'generated' query param\n\n## CORS Configuration (Cross-Origin Resource Sharing)\nThese environment variables allow you to manage security and access control mechanisms for your API.\n\n- **`CORS_ENABLED`**:  \n  A boolean flag to enable or disable CORS. Set this variable to `\"true\"` to allow cross-origin requests, or `\"false\"` to disable them. When disabled, no CORS-related headers are included in the server's responses.\n\n- **`CORS_ALLOWED_ORIGINS`**:  \n  Specifies the allowed origins for cross-origin requests. This should be a comma-separated list of origins (e.g., `\"http://example.com,http://localhost:4200\"`). The wildcard (`\"*\"`) can be used to allow requests from any origin, but it's recommended to be explicit for security reasons.\n\n- **`CORS_ALLOWED_METHODS`**:  \n  Defines the HTTP methods that are allowed when accessing resources. Common values include `\"GET,POST,OPTIONS\"`, but you can add others such as `\"PUT,DELETE\"` based on your API's needs. This restricts which methods clients can use.\n\n- **`CORS_ALLOWED_HEADERS`**:  \n  Specifies the allowed headers in requests. You can define which headers clients are allowed to send, such as `\"Authorization,Content-Type\"`. This is useful when allowing credentials or custom content types.\n\n- **`CORS_ALLOW_CREDENTIALS`**:  \n  A boolean flag (`\"true\"` or `\"false\"`) that indicates whether or not the response can be exposed when credentials (cookies or HTTP authentication) are included in cross-origin requests. Set this to `\"true\"` to allow credentials.\n\n- **`CORS_MAX_AGE`**:  \n  Defines the maximum time (in seconds) that the results of a preflight request can be cached. For example, `\"86400\"` (24 hours) will allow the browser to cache preflight responses for 24 hours, reducing the number of preflight requests. Default value is typically 86400 seconds (1 day).\n\n- **`CORS_EXPOSE_HEADERS`**:  \n  A comma-separated list of headers that the client is allowed to access in the response. By default, only a few headers like `Content-Type` are exposed. If your API sends custom headers that clients need to access, list them here (e.g., `\"X-Custom-Header,X-Another-Header\"`).\n\n- **`CORS_ALLOW_PRIVATE_NETWORK`** (optional, not available in all versions):  \n  A boolean flag (`\"true\"` or `\"false\"`) that indicates whether cross-origin requests from private networks are allowed. This is useful for allowing access from internal networks, but should be handled carefully for security reasons.\n\n### Example Usage\n\nTo enable CORS with specific origins, methods, and headers:\n\n```bash\nCORS_ENABLED=true\nCORS_ALLOWED_ORIGINS=http://example.com,http://localhost:4200\nCORS_ALLOWED_METHODS=GET,POST,OPTIONS\nCORS_ALLOWED_HEADERS=Authorization,Content-Type\nCORS_ALLOW_CREDENTIALS=true\nCORS_MAX_AGE=86400\nCORS_EXPOSE_HEADERS=X-Custom-Header,X-Another-Header\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farnauld%2Fjwtd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farnauld%2Fjwtd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farnauld%2Fjwtd/lists"}