Core - v1.0.0
    Preparing search index...

    Class Signature

    Stateless signed tokens over HMAC-SHA-256.

    For the case where a value has to travel through somewhere you do not control — a query string, a URL fragment, a cookie, a redirect — and come back unmodified. The signature is verified rather than looked up, so issuing and checking one costs no storage read, nothing accumulates, and nothing has to be expired.

    What this is not: it does not hide the value, it proves the value is one you issued. Anyone holding the token can read what it covers. And because there is no stored record, a token cannot be revoked before whatever bound it expires — build an expiry into the signed value when that matters.

    Reach for it when an identifier alone is doing work it cannot do. An unguessable id is not a secret: it travels in URLs and therefore into access logs, proxies, and referrer headers. A signature over that id is what makes presenting it evidence of anything.

    // Issue a token a client presents to rejoin a session it already owns.
    const token = await Signature.sign(env.API_AUTH_TOKEN_VALUE, 'session/resume/v1', sessionId)

    // On the way back in.
    if (!(await Signature.verify(env.API_AUTH_TOKEN_VALUE, 'session/resume/v1', sessionId, token))) {
    // Start fresh rather than reject: a stale token should not be an error page.
    }

    Bayu Dwiyan Satria

    1.0.0

    1.0.0

    Index
    • Signs a value under a scope.

      Parameters

      • secret: string

        The shared secret. Any sufficiently random value; reusing an existing API token is fine and saves operating a second secret.

      • scope: string

        What this token is for, e.g. session/resume/v1.

      • value: string

        The value being signed.

      Returns Promise<string>

      The signature, hex-encoded. An empty string when secret is unset, which callers should read as "cannot issue" rather than as a token.

      The scope is domain separation, and it is not optional decoration. Two different kinds of token signed with the same secret and no scope are interchangeable — a signature issued for one purpose verifies for the other, and whichever check is laxer becomes the one that matters. Give every use its own scope, and version it (.../v1), so changing what a token covers invalidates the old ones instead of silently accepting them.

    • Checks a token against a value and scope.

      Parameters

      • secret: string

        The shared secret the token was signed with.

      • scope: string

        The scope the token was issued under. Must match exactly.

      • value: string

        The value being claimed.

      • token: string

        The token presented.

      Returns Promise<boolean>

      true only when the token was issued for that value under that scope with that secret.

      Goes through crypto.subtle.verify rather than re-signing and comparing strings, so the comparison is constant-time for free. A malformed token is false rather than a throw — it arrives from outside, so it is input, not an error.