Gathering detailed insights and metrics for paseto-ts
Gathering detailed insights and metrics for paseto-ts
Gathering detailed insights and metrics for paseto-ts
Gathering detailed insights and metrics for paseto-ts
npm install paseto-ts
Typescript
Module System
Node Version
NPM Version
TypeScript (99.84%)
JavaScript (0.16%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
60 Stars
57 Commits
10 Forks
3 Watchers
1 Branches
2 Contributors
Updated on Jun 28, 2025
Latest Version
2.0.5
Package Id
paseto-ts@2.0.5
Unpacked Size
84.90 kB
Size
19.33 kB
File Count
35
NPM Version
10.9.2
Node Version
22.13.1
Published on
Apr 12, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
4
PASETO v4 implementation written in TypeScript. Does not require Node.js.
The code is well-documented and has 100% unit test coverage ensuring it conforms with the best practices laid out in the PASETO implementation guide.
If you are unfamiliar with PASETO, please see Okta's blog post "A Thorough Introduction to PASETO".
The only dependencies are the Blake2b, Ed25519 and XChaCha20 cryptographic primitives, which do not yet exist in the standard Web Crypto API, provided by stablelib. If you wish to use other primitives, feel free to fork the project and implement them; it should be straightforward.
1npm install --save paseto-ts
This library is an ES Module!
Remember: You need to put "type": "module"
in your package.json to enable ESM in Node! If you are getting an export error, this is probably why.
Version | Purpose |
---|---|
v4.public | Public-key signatures (sign and verify ) |
v4.local | Symmetric encryption (encrypt and decrypt ) |
This library implements the k4.local
, k4.public
and k4.secret
PASERK compatible key formats. It does not accept arbitrary key data that is not scoped to a specific purpose. It also does not implement key wrapping or other PASERK features.
The package will not work in commonjs environments without a transpilation step. It has been tested in Node > 16 and modern browsers. As it depends on the Web Crypto API being available, Deno and Bun should work, but are not tested.
1import * as crypto from 'node:crypto'; 2import { generateKeys } from 'paseto-ts/v4'; 3 4const getRandomValues = (array: Uint8Array): Uint8Array => { 5 const bytes = crypto.randomBytes(array.length); 6 array.set(bytes); 7 return array; 8}; 9 10generateKeys('local', { format: 'paserk', getRandomValues });
When using the encrypt
and sign
functions, the iat
(issued at) and exp
(expires at) claims are added to your payload if they do not exist. By default, the exp
claim will be set one hour in the future.
You can disable this behaviour by passing addIat: false
and/or addExp: false
as options to create tokens that do not expire.
You can provide an exp
and nbf
(not before) claim as a relative time, e.g. exp: "1 hour"
or nbf: "1 day"
. The iat
claim only accepts string-formatted ISO dates (e.g. iat: "2023-01-01T00:00:00Z"
).
Registered claims will be validated against the spec. To disable this behaviour, pass validatePayload: false
as an option.
This library conforms to the best practices laid out in the PASETO implementation guide regarding JSON parsing. It will throw an error if the payload or footer is not valid JSON, if the JSON is too deep or has too many keys. You can disable this behaviour by passing maxDepth: 0
and/or maxKeys: 0
to the options object.
You use the same key to encrypt and decrypt your message.
The PASETO spec requires local and public keys to be separated. Therefore, to use the encrypt
and decrypt
functions in this library, k4.local.
must be prepended to the key data to prevent accidental key sharing between local and public functions. Please refer to the table below:
Type | Expected format | Length |
---|---|---|
PASERK | k4.local.[key data as base64url] | 52 characters |
Uint8Array | [0x6b, 0x34, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2e, ...key] | 41 bytes |
There is no functional difference between the two formats; if you are passing the key in from an environment variable, you may prefer to use PASERK
format. If you are generating the key elsewhere, you may prefer to use Uint8Array
and prepend the magic bytes yourself.
You can generate a local key in PASERK format using the generateKeys
function:
1import { generateKeys } from 'paseto-ts/v4'; 2 3const localKey = generateKeys('local'); 4// localKey: k4.local.xxx..
If you need the key as a buffer, you can pass in buffer
as the second argument:
1import { generateKeys } from 'paseto-ts/v4'; 2 3const localKeyBuffer = generateKeys('local', { format: 'buffer' }); 4// localKeyBuffer: Uint8Array(41)
1import { encrypt } from 'paseto-ts/v4'; 2 3try { 4 5 const token = await encrypt( 6 // localKey = k4.local.xxx.. 7 localKey, // string | Uint8Array 8 // payload = { sub: '1234567890', name: 'John Doe' } 9 payload, // Payload | string | Uint8Array 10 { 11 // Optional: If footer parses to an object, its `kid` and `wpk` claims will be validated. 12 footer, // Footer | string | Uint8Array 13 // Optional: Assertion is a JSON.stringifyable object, string or buffer. 14 assertion, // Assertion | string | Uint8Array 15 // Optional: If true, a default `exp` claim of 1 hour will be added to the payload. 16 addExp, // boolean; defaults to true 17 // Optional: If true, a default `iat` claim of the current time will be added to the payload. 18 addIat, // boolean; defaults to true 19 // Optional: Maximum depth of the JSON in the payload and footer objects (if footer parses to an object) 20 maxDepth, // number; defaults to 32. 0 to disable 21 // Optional: Maximum number of keys in the payload and footer objects (if footer parses to an object) 22 maxKeys, // number; defaults to 128. 0 to disable 23 // Optional: If true, the payload will be validated against the registered claims. 24 validatePayload, // boolean; defaults to true 25 // Optional: crypto.getRandomValues implementation (for Node < 19) 26 getRandomValues, // (array: Uint8Array) => Uint8Array 27 } 28 ); 29 30 // token: v4.local.xxx.. 31 32} catch(err) { 33 // err: Error 34}
1import { decrypt } from 'paseto-ts/v4'; 2 3try { 4 5 // generic type parameter is optional but will give you type safety on the payload 6 const { payload, footer } = await decrypt<{ foo: string }>( 7 // localKey = k4.local.xxx.. 8 localKey, // string | Uint8Array 9 // token = v4.local.xxx.. 10 token, // string | Uint8Array 11 { 12 // Optional: Assertion is a JSON.stringifyable object, string or buffer. 13 assertion, // Assertion | string | Uint8Array 14 // Optional: Maximum depth of the JSON in the payload and footer objects (if footer parses to an object) 15 maxDepth, // number; defaults to 32. 0 to disable 16 // Optional: Maximum number of keys in the payload and footer objects (if footer parses to an object) 17 maxKeys, // number; defaults to 128. 0 to disable 18 // Optional: If true, the payload will be validated against the registered claims. 19 validatePayload, // boolean; defaults to true 20 } 21 ); 22 23 // payload: { sub: '1234567890', name: 'John Doe', iat: "2023-01-01T00:00:00.000Z" } 24 // footer: { kid: 'xxx..', wpk: 'xxx..' } 25 26} catch(err) { 27 // err: Error 28}
You use a secret key to sign your payload, and a public key to verify the generated token.
The PASETO spec dictates that you use Ed25519 keys, which are 64 bytes long. To use the sign
and verify
functions in this library, k4.public.
must be prepended to the public key data and k4.secret.
must be prepended to the secret key data to prevent accidental key sharing between local and public functions. Please refer to the table below:
Type | Expected format | Length |
---|---|---|
PASERK | k4.secret.[key data as base64url] | 96 characters |
Uint8Array | [0x6b, 0x34, 0x2e, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, ...key] | 41 bytes |
Type | Expected format | Length |
---|---|---|
PASERK | k4.public.[key data as base64url] | 53 characters |
Uint8Array | [0x6b, 0x34, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, ...key] | 41 bytes |
You can generate a public/secret key pair in PASERK format using the generateKeys
function:
1import { generateKeys } from 'paseto-ts/v4'; 2 3const { secretKey, publicKey } = generateKeys('public'); 4// secretKey: k4.secret.xxx.. 5// publicKey: k4.public.xxx..
If you need the keys as buffers, you can pass in buffer
as the second argument:
1import { generateKeys } from 'paseto-ts/v4'; 2 3const { secretKey, publicKey } = generateKeys('public', { format: 'buffer' }); 4// secretKey: Uint8Array(41) 5// publicKey: Uint8Array(41)
You can pass a Payload
object, a string
or an Uint8Array
to the sign
function. PASETO defines a set of registered claims that you can use in your payload. Any registered claims are validated.
1import { sign } from 'paseto-ts/v4'; 2 3try { 4 5 const token = await sign( 6 // secretKey = k4.secret.xxx.. 7 secretKey, // string | Uint8Array 8 // payload = { sub: '1234567890', name: 'John Doe' } 9 payload, // Payload | string | Uint8Array 10 { 11 // Optional: If footer parses to an object, its `kid` and `wpk` claims will be validated. 12 footer, // Footer | string | Uint8Array 13 // Optional: Assertion is a JSON.stringifyable object, string or buffer. 14 assertion, // Assertion | string | Uint8Array 15 // Optional: If true, a default `exp` claim of 1 hour will be added to the payload. 16 addExp, // boolean; defaults to true 17 // Optional: If true, a default `iat` claim of the current time will be added to the payload. 18 addIat, // boolean; defaults to true 19 // Optional: Maximum depth of the JSON in the payload and footer objects (if footer parses to an object) 20 maxDepth, // number; defaults to 32. 0 to disable 21 // Optional: Maximum number of keys in the payload and footer objects (if footer parses to an object) 22 maxKeys, // number; defaults to 128. 0 to disable 23 // Optional: If true, the payload will be validated against the registered claims. 24 validatePayload, // boolean; defaults to true 25 } 26 ); 27 28 // token: v4.public.xxx.. 29 30} catch(err) { 31 // err: Error 32}
1import { verify } from 'paseto-ts/v4'; 2 3try { 4 5 // generic type parameter is optional but will give you type safety on the payload 6 const { payload, footer } = await verify<{ foo: string }>( 7 // publicKey = k4.public.xxx.. 8 publicKey, // string | Uint8Array 9 // token = v4.public.xxx.. 10 token, // string | Uint8Array 11 { 12 // Optional: Assertion is a JSON.stringifyable object, string or buffer. 13 assertion, // Assertion | string | Uint8Array 14 // Optional: Maximum depth of the JSON in the payload and footer objects (if footer parses to an object) 15 maxDepth, // number; defaults to 32. 0 to disable 16 // Optional: Maximum number of keys in the payload and footer objects (if footer parses to an object) 17 maxKeys, // number; defaults to 128. 0 to disable 18 // Optional: If true, the payload will be validated against the registered claims. 19 validatePayload, // boolean; defaults to true 20 } 21 ); 22 23 // payload: { sub: '1234567890', name: 'John Doe', iat: "2023-01-01T00:00:00.000Z" } 24 // footer: { kid: 'xxx..', wpk: 'xxx..' } 25 26} catch(err) { 27 // err: Error 28}
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
MIT
No vulnerabilities found.
No security vulnerabilities found.