{"id":31144243,"url":"https://github.com/outfoxx/vault-plugin-secrets-jwt","last_synced_at":"2025-09-18T14:37:56.168Z","repository":{"id":46181779,"uuid":"425074152","full_name":"outfoxx/vault-plugin-secrets-jwt","owner":"outfoxx","description":"A Vault secrets plugin for generating and verifying JSON Web Tokens","archived":false,"fork":false,"pushed_at":"2024-09-23T19:50:19.000Z","size":301,"stargazers_count":9,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-01T12:44:41.812Z","etag":null,"topics":["jwk","jwt","vault"],"latest_commit_sha":null,"homepage":"","language":"Go","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/outfoxx.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-11-05T20:18:37.000Z","updated_at":"2025-07-18T04:10:13.000Z","dependencies_parsed_at":"2024-06-21T02:03:58.894Z","dependency_job_id":"1f84e152-9906-4219-ae41-80a98021968c","html_url":"https://github.com/outfoxx/vault-plugin-secrets-jwt","commit_stats":{"total_commits":59,"total_committers":4,"mean_commits":14.75,"dds":0.3389830508474576,"last_synced_commit":"ceed46b2813c01d8a550e1a9922fe03f20b364a7"},"previous_names":["outfoxx/vault-jwt-secrets"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/outfoxx/vault-plugin-secrets-jwt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/outfoxx%2Fvault-plugin-secrets-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/outfoxx%2Fvault-plugin-secrets-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/outfoxx%2Fvault-plugin-secrets-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/outfoxx%2Fvault-plugin-secrets-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/outfoxx","download_url":"https://codeload.github.com/outfoxx/vault-plugin-secrets-jwt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/outfoxx%2Fvault-plugin-secrets-jwt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275781924,"owners_count":25527488,"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-09-18T02:00:09.552Z","response_time":77,"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":["jwk","jwt","vault"],"created_at":"2025-09-18T14:37:54.978Z","updated_at":"2025-09-18T14:37:56.130Z","avatar_url":"https://github.com/outfoxx.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vault Plugin: JWT Secrets\n### A [Hashicorp Vault](https://www.github.com/hashicorp/vault) secrets plugin for generating and verifying JSON Web Tokens  \n\n* [Overview](#overview)\n* [Encryption And Key Managment](#encryption-and-key-management)\n* [Usage](#usage)\n  * [Quick Start](#quick-start)\n  * [Container](#container)\n  * [Configuration](#configuration)\n  * [Roles](#roles)\n  * [Signing](#signing)\n* [Implementation Notes](#implementation-notes)\n* [Contributors](#contributors)\n* [Links](#quick-links)\n\n# Overview\n\nThis plugin provides the ability to generate signed [JSON Web Tokens](https://jwt.io) (JWTs) without the signing keys\never leaving Vault.\n\nThe plugin works by providing a service to sign JWTs using internal private key(s).\nSimultaneously the plugin provides a [JSON Web Key](https://www.ietf.org/rfc/rfc7517.txt)\nRFC compliant HTTP endpoint to publish public verification keys.\n\nThe plugin explicitly does not support verifying JWTs as a service; instead relying on clients to\nfetch the verification keys via HTTP and verify JWTs locally. This dramatically reduces traffic to\nVault as well as allows clients to use standard client libraries for verification.\n\n### ⚠️ Early Access \nThe plugin is still under early development and should be tested thoroughly before being used in\nany environment.\n\n# Encryption and Key Management\n\n## Automatic Key Rotation\n\nThe plugin automatically rotates signing keys and publishes a history of previous keys for\nverification. The rotation schedule is configurable and ensures the keys will be available for\nverification as long as any JWTs signed with them are valid.\n\n## Supported Algorithms\n\nThe plugin supports a subset of the asymmetric encryption algorithms outlined in the JWT\nspecification.\n\n* ES256\n* ES384\n* ES512\n* RS256\n* RS384\n* RS512\n\nNote: Due to its reliance on asymmetric encryption, the plugin will not support symmetric algorithms.\n\n# Usage\n\n## Quick Start\nThe plugin needs to be built and installed into your Vault instance's plugin directory prior\nto any attempt at usage. A prepackaged container is available see [Container](#container).\n\n1. Register the plugin\n\n\n```bash\nexport PLUGIN_SHA=$(sha256sum $VAULT_PLUGIN_PATH/vault-plugin-secrets-jwt | cut -d ' ' -f1)\n```\n\n```bash\nvault plugin register -sha256=$PLUGIN_SHA -command=vault-plugin-secrets-jwt secret jwt\n```\n\n2. Enable the plugin\n\n```bash\nvault secrets enable jwt\n```\n\n3. Create a role specifying the issuer (`iss`) claim of generated JWTs\n\n```bash\nvault write jwt/roles/test-role issuer=test.example.com\n```\n    \n4. Sign a JWT (with default claims)\n    \n```bash\nvault write -f jwt/sign/test-role\n```\n\n5. Retrieve JWKs for verification\n\n```bash\ncurl https://$VAULT_ADDRESS/v1/jwt/jwks\n```\n\n## Container\n\nA containerized version of Vault with the plugin pre-packaged inside is available for testing at\n`https://hub.docker.com/r/outfoxx/vault`.\n\nYou can easily start a server in dev mode, that has the plugin enabled, using:\n```bash\ndocker run --rm -P -e VAULT_DEV_ROOT_TOKEN_ID=root outfoxx/vault\n```\n\n## Configuration\n\nThe plugin has a usable (although probably not useful) default configuration. Although prior to usage\nroles must be configured.\n\n### 🔸 Allowed Claims\n\nThe plugin requires that any claims provided during role creation or JWT signing be explicitly\nallowed in the configuration. By default, only the audience (`aud`) claim is allowed.\n\nAllow `aud` and `groups` claims:\n\n```bash\nvault write jwt/config allowed_claims=\"aud\" allowed_claims=\"groups\" \n```\n\nℹ️ The `allowed_claims` field is a list, passing multiple values to `vault` cli allows you to\ncreate a list.\n\n### 🔸 Allowed Headers\n\nThe plugin requires that any headers provided during role creation be explicitly\nallowed in the configuration.\n\nAllow `iss` and `path` claims:\n\n```bash\nvault write jwt/config allowed_headers=\"iss\" allowed_headers=\"path\" \n```\n\nℹ️ The `allowed_headers` field is a list, passing multiple values to `vault` cli allows you to\ncreate a list.\n\n### 🔸 Signature Algorithm\n\nThe plugin allows configuration of the signature algorithm used to sign JWTs. By default, the\n`ES256`algorithm is used.\n\n```bash\nvault write jwt/config sig_alg=RS256\n```\n\nWhen using an RSA algorithm (e.g. `RS256`) you can also select the size of the RSA key that\nis generated. By default, a `2048` bit key is generated.\n\n```bash\nvault write jwt/config sig_alg=RS256 rsa_key_bits=4096\n```\n\n### 🔸 Key Rotation\n\nKey rotation is automatically done by the plugin. You can configure the key rotation period to\nwhatever duration you wish.\n\n```bash\nvault write jwt/config key_ttl=12h0s\n```\n\nWhen keys are rotated the previous keys are kept to allow verification. Verification keys\nare pruned at a time after which all generated tokens have expired.\n\n### 🔸 Token TTL\n\nEach generated JWT has a finite expiration. Configure the TTL used to determine each token's\nexpiration with the `token_ttl` field. By default, each token expires after `3m0s`.\n\n```bash\nvault write jwt/config token_ttl=3m\n```\n\n### 🔸 Audience \u0026 Subject Restrictions\n\nThe plugin can be configured to restrict the audience (`aud`) and subject (`sub`) claims to\nthose matching a specific pattern. By default, both claims are unrestricted.\n\n```bash\nvault write jwt/config subject_pattern=*.example.com\n```\n\n```bash\nvault write jwt/config audience_pattern=*.example.com\n```\n\nAdditionally, the audience (`aud`) claim (which is a list of stings) can be restricted to\na maximum length. By default, audience length is unrestricted.\n\n```bash\nvault write jwt/config max_audiences=2\n```\n\n### 🔸 Generated Reserved Claims\n\nThe issuer (`iss`) claim for generated tokens can be specified in the configuration. By\ndefault, no issuer claim is added.\n\n```bash\nvault write jwt/config issuer=vault.example.com\n```\n\nThe \"unique token id\" (`jti`) claim can be enabled/disabled. By default, a \"unique token id\" claim is added.\n\n```bash\nvault write jwt/config set_jti=true\n```\n\nThe \"not before\" (`nbf`) claim can be enabled/disabled. By default, a \"not before\" claim is added.\n\n```bash\nvault write jwt/config set_nbf=true\n```\n\nThe \"issued at\" (`iat`) claim can be enabled/disabled. By default, an \"issued at\" claim is added.\n\n```bash\nvault write jwt/config set_iat=true\n```\n\n## Roles\n\nBefore signing a JWT a role must be configured.\n\n### 🔸 Issuer\n\nWhen creating a role a value for the `issuer` field must be provided. The role issuer field specifies the\nissuer (`iss`) claim for signed JWTs. This is the only method of providing the issuer claim for JWTs.\n\n```bash\nvault write jwt/roles/test-role issuer=test.example.com\n```\n\n### 🔸 Other Claims\n\nRoles can additionally include any other claims that are allowed by the configuration.\n\n```bash\necho claims '{\"claims\": {\"groups\":\"test-group\"}}' | vault write jwt/roles/test-role -\n```\n\n⚠️ Due to deficiencies of the `vault` cli, you need to pass `claims` in as JSON.\n\nℹ️ Any claims set in a role's `claims` field must be explicitly allowed in the\nplugin's configuration and can no longer be set during a sign request.\n\n### 🔸 Other Headers\n\nRoles can additionally include any other headers that are allowed by the configuration.\n\n```bash\necho claims '{\"headers\": {\"iss\":\"some-key-issuer\"}}' | vault write jwt/roles/test-role -\n```\n\n⚠️ Due to deficiencies of the `vault` cli, you need to pass `headers` in as JSON.\n\nℹ️ Any headers set in a role's `headers` field must be explicitly allowed in the\nplugin's configuration.\n\n### 🔸 Audience \u0026 Subject Restrictions\n\nThe role can be configured to restrict the audience (`aud`) and subject (`sub`) claims to\nthose matching a specific pattern; this restriction is in addition to the pattern restrictions\ndefined in the configuration. By default, both claims are unrestricted.\n\n```bash\nvault write jwt/roles/test-role subject_pattern=*.example.com\n```\n\n```bash\nvault write jwt/roles/test-role audience_pattern=*.example.com\n```\n\n## Signing\n\nSigning a JWT requires a role be configured and is easily done using the `sign` service,\nproviding the role name.\n\nSign a JWT with default configured claims.\n```bash\nvault write -f jwt/sign/test-role\n```\n\nAdditionally, when signing a JWT, any claims allowed by the `allowed_claims` configuration and\ncan be specified.\n\n```bash\necho claims '{\"claims\": {\"groups\":\"test-group\"}}' | vault write jwt/sign/test-role -\n```\n\n⚠️ If a claim value has been specified in the role's `claims` field, it cannot\nbe overridden during the sign request.\n\n# Implementation Notes\n\n## `keysutil` Usage \n\nThe plugin uses the same mechanism as the builtin `Transit` secrets engine. Using `keysutil`\nensures the key management and rotation is built on a solid cryptographic engine.  \n\n# Contributors\n\nThe original plugin started life as a learning exercise for [Ian Fox](https://github.com/ian-fox) and\nI'd like to thank him for his initial proof-of-concept. As we make improvements he has kindly allowed\nus to take over the project and move it forward.\n\nWe have taken the original proof-of-concept and rewrote it in hopes of providing a solid plugin that\ncan be used in production.\n\n# Quick Links\n    - Vault Website: https://www.vaultproject.io\n    - Main Project Github: https://www.github.com/hashicorp/vault\n    - JWT docs: https://jwt.io\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foutfoxx%2Fvault-plugin-secrets-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foutfoxx%2Fvault-plugin-secrets-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foutfoxx%2Fvault-plugin-secrets-jwt/lists"}