cybertoken
    Preparing search index...

    cybertoken

    cybertoken CI CD npm badge

    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.

    GitHub changed their token format a while back and explained the reasons in an insightful blog post[^1].

    tl;dr:

    1. Having a defined format for secrets is good for automated secret scanning.
    2. Putting some prefix to a secret makes debugging easier when looking at some random token.
    3. Using _ instead of - is better for double-click text selection: abc_def vs abc-def.
    4. Using Base62[^2] instead of Base64 results in less encoding errors when passing the token somewhere.
    5. 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.

    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

    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,}
    

    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!

    This is what a cybertoken consists of:

      prefix      base62(n-bytes + v + crc32(n-bytes + v))
    ┌────────┐ ┌──────────────────────────────────────────────┐
    myapitoken_161YNJQOaoFoWLaoXeMVHYyrSLhGPOjSBYBtxY6V3GqFFZKV

    Explanation:

    • n-bytes are n random bytes, but at least 21 (default: 22), generated by a cryptographically secure random source
    • v is a single byte containing the version of the cybertoken format used (currently, only 0x00)
    • 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