@cybertoken/cybertoken@3.0.2Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
A token format for APIs inspired by the GitHub's API token format.
cybertoken

A token format inspired by GitHub's new API token format. Think of it as a standardized password format with some handy properties. Intended for API token and password generation.
What is this?
GitHub changed their token format a while back and explained the reasons in an insightful blog post[^1].
tl;dr:
- Having a defined format for secrets is good for automated secret scanning.
- Putting some prefix to a secret makes debugging easier when looking at some random token.
- Using
_
instead of-
is better for double-click text selection:abc_def
vsabc-def
. - Using Base62[^2] instead of Base64 results in less encoding errors when passing the token somewhere.
- CRC32 checksum at the end of the token for faster offline syntactic check of a token (used as a heuristic, not for security).
These properties make this token format suitable for things like API tokens, which is what cybertoken is.
Usage
Install:
npm install cybertoken
Also available on JSR:
npx jsr add @cybertoken/cybertoken
import { createTokenGenerator } from "cybertoken"; const apiTokenGenerator = createTokenGenerator({ prefixWithoutUnderscore: "contoso", }); const token = apiTokenGenerator.generateToken(); // Securely hash `token` and save it in your database. Return `token` to the user once. console.log(token); // contoso_IvN2xEuHUDjQ3PNQgZkILWc7GUxpmThDD410NQxJalD5GjY
Bonus
You can also use cybertokens as passwords. If you use GitHub, you can set up a custom secret scanning pattern that will prevent anyone from pushing anything that looks like a cybertoken that your org uses.
For example, use this pattern for Cybertokens with the prefix contosopass
:
contosopass_[0-9A-Za-z]{10,}
CLI Usage
The npm package also offers a command-line utility to generate tokens.
npm install -g cybertoken
Usage:
cybertoken <prefix> # example: cybertoken test test_KOK5QxQr4GBGk97X8Ij5ZnyZO24kMIEiW1LdUYIqEj7A5Nv
You can also provide the token prefix via an env variable:
CYBERTOKEN_PREFIX=foo cybertoken
To make thing easier, you can put this in your .bashrc
:
echo "export CYBERTOKEN_PREFIX=foo" >> ~/.bashrc
...and now you can just use cybertoken
!
Anatomy
This is what a cybertoken consists of:
prefix base62(n-bytes + v + crc32(n-bytes + v)) ┌────────┐ ┌──────────────────────────────────────────────┐ myapitoken_161YNJQOaoFoWLaoXeMVHYyrSLhGPOjSBYBtxY6V3GqFFZKV
Explanation:
n-bytes
aren
random bytes, but at least 21 (default: 22), generated by a cryptographically secure random sourcev
is a single byte containing the version of the cybertoken format used (currently, only0x00
)- The bytes are concatenated with the version and their CRC32 sum before base62 encoding
- base62 alphabet used:
0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
[^1]: GitHub's blog post covering this: https://github.blog/2021-04-05-behind-githubs-new-authentication-token-formats [^2]: More info in Base62: https://en.wikipedia.org/wiki/Base62
Add Package
deno add jsr:@cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";
Import directly with a jsr specifier
import * as cybertoken from "jsr:@cybertoken/cybertoken";
Add Package
pnpm i jsr:@cybertoken/cybertoken
pnpm dlx jsr add @cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";
Add Package
yarn add jsr:@cybertoken/cybertoken
yarn dlx jsr add @cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";
Add Package
vlt install jsr:@cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";
Add Package
npx jsr add @cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";
Add Package
bunx jsr add @cybertoken/cybertoken
Import symbol
import * as cybertoken from "@cybertoken/cybertoken";