{"id":21700397,"url":"https://github.com/articulate/authentic","last_synced_at":"2025-04-12T13:34:28.743Z","repository":{"id":28533264,"uuid":"118512551","full_name":"articulate/authentic","owner":"articulate","description":"Proper validation of JWT's against JWK's","archived":false,"fork":false,"pushed_at":"2024-01-03T17:05:27.000Z","size":268,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":56,"default_branch":"main","last_synced_at":"2025-04-08T22:02:12.368Z","etag":null,"topics":["auth0","javascript","jwks","jwt","nodejs","oidc","okta"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/articulate.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-01-22T20:41:46.000Z","updated_at":"2023-12-29T19:09:48.000Z","dependencies_parsed_at":"2023-12-26T14:11:21.162Z","dependency_job_id":null,"html_url":"https://github.com/articulate/authentic","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/articulate%2Fauthentic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/articulate%2Fauthentic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/articulate%2Fauthentic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/articulate%2Fauthentic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/articulate","download_url":"https://codeload.github.com/articulate/authentic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248573571,"owners_count":21126859,"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":["auth0","javascript","jwks","jwt","nodejs","oidc","okta"],"created_at":"2024-11-25T20:14:12.833Z","updated_at":"2025-04-12T13:34:28.722Z","avatar_url":"https://github.com/articulate.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @articulate/authentic\n\nProper validation of JWT's against JWK's.\n\n## Motivation\n\nThe process of validating JWT's against JWK's is [quite involved](https://auth0.com/blog/navigating-rs256-and-jwks/), but at the end of the day, you probably have an auth server with a `/.well-known/openid-configuration` endpoint, and you just want to know if an incoming JWT is valid.  End of story.  You don't want to fumble with parsing the JWT, matching `kid` values, converting certs, or caching JWK's.\n\nNow you don't need to.  Initialize `authentic` with an `issWhitelist`, and you'll receive a function that accepts a JWT and validates it.  The rest is handled for you.\n\n## Usage\n\n```haskell\nauthentic :: { k: v } -\u003e String -\u003e Promise Boom { k: v }\n```\n\nInitialize `authentic` with an options object containing an `issWhitelist` array listing the `token.payload.iss` values you will accept.  For example:\n\n| Provider | Sample `issWhitelist` |\n| -------- | ------------------- |\n| [Auth0](https://auth0.com/) | `[ 'https://${tenant}.auth0.com/' ]` |\n| [Okta](https://www.okta.com/) | `[ 'https://${tenant}.oktapreview.com/oauth2/${appName}' ]` |\n\n**Note:** The urls in the list need to be **exact matches** of the `payload.iss` values in your JWT's.\n\nYou'll receive a unary function which takes a JWT and returns a `Promise` that resolves with the parsed JWT payload if it is valid, or rejects with a `401` [Boom](https://github.com/hapijs/boom) error if it is invalid.\n\n```js\n// lib/authentic.js\nimport { authentic } from '@articulate/authentic'\n\nexport default authentic({\n  issWhitelist: process.env.ISS_WHITELIST.split('|'),\n})\n\n// main.js\nimport authentic from './lib/authentic'\n\nconst handler = req =\u003e\n  authentic(req.cookies.token)\n    .then(token =\u003e {\n      /* the JWT has been validated */\n    })\n    .catch(/* invalid token */)\n```\n\n## Options\n\n`authentic` accepts a JSON object with the following options:\n\n* `jwks` Object: options to forward to `jose.createRemoteJWKSet` from [`jose`](https://github.com/panva/jose/blob/main/docs/interfaces/jwks_remote.RemoteJWKSetOptions.md) with the following defaults:\n\n| option      | default |\n| ----------- | ------- |\n| `timeoutDuration` | `5000` (5 seconds)  |\n| `cooldownDuration` | `30000` (30 seconds)  |\n| `cacheMaxAge` | `60000` (10 minutes)  |\n\n* `verify` Object: options to forward to `jose.jwtVerify` from [`jose`](https://github.com/panva/jose/blob/main/docs/interfaces/jwt_verify.JWTVerifyOptions.md)\n* `issWhitelist` Array: list of trusted OIDC issuers\n* `claimsInError` Array: list of jwt payload claims to receive as the `data` property of the error when verification fails.  When a list is not provided a `data` property will not be added to the error.\n\n## Contributing\n\nChanges are tracked \u0026 published using [changesets](https://github.com/changesets/changesets).\n\n### Adding a Changeset\n\n1. Create a git branch. Make your desired changes.\n1. Run `yarn changesets`. Follow the prompts \u0026 specify if your change is a\n    major, minor, or patch change.\n1. Add all the changes to `.changesets` \u0026 commit.\n1. Create a Pull Request. Merge into the main branch when ready.\n\n### Publishing to NPM\n\nChangesets will create a \"Release\" pull request whenever unpublished changesets\nare merged into main. When ready to publish to NPM, merge this pull request,\nand changes will be automatically published.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farticulate%2Fauthentic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farticulate%2Fauthentic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farticulate%2Fauthentic/lists"}