API reference

@wellknown-id/wallet/self-issued

Self-issued proofs (prd.md §4.11): the token a holder's page signs with their key for your site, in SIOPv2's self-issued ID token shape. The IdP checks it and issues an ordinary ID token; a site whose config says self_issued: "allow" may take it straight from the page and check it here with verifySelfIssued. WebCrypto only: it runs in Node, browsers, Deno and Workers alike.

Classes

SelfIssuedError

Why a self-issued token was refused (its message says what was wrong).

Extends

  • Error

Constructors

Constructor
new SelfIssuedError(message?): SelfIssuedError;
Parameters
ParameterType
message?string
Returns

SelfIssuedError

Inherited from
Error.constructor
Constructor
new SelfIssuedError(message?, options?): SelfIssuedError;
Parameters
ParameterType
message?string
options?ErrorOptions
Returns

SelfIssuedError

Inherited from
Error.constructor

Type Aliases

SelfIssuedClaims

type SelfIssuedClaims = object;

What a self-issued token says: the holder's key at the site (iss = sub) answering nonce for aud.

Properties

PropertyTypeDescription
amr?string[]How the holder reached the key, as their page says: passkey, browser (kept in this browser), code, wallet.
audstringThe site's client_id.
expnumberAt most SELF_ISSUED_LIFETIME_S after iat.
iatnumber-
issstringThe holder's did:key at the site: who signed in.
noncestringThe challenge answered: the IdP's, or the site's own (S256 of its verifier).
substringThe same did:key.
wellknown_grant?stringA grant (grants.ts, §7.13) letting this key act for someone else here, checked by whoever takes the token.
wellknown_group?stringA shared identity's statements at the site (groups.ts, §7.14), as JSON: with a grant the group's members signed.
wellknown_succession?stringA succession statement from an earlier wellknown.id at this site (§4.9), checked by whoever takes the token.

Variables

SELF_ISSUED_LIFETIME_S

const SELF_ISSUED_LIFETIME_S: 120 = 120;

A proof's lifetime (Ben, 2026-10-01), and the longest a verifier accepts, whatever exp says.


SELF_ISSUED_SKEW_S

const SELF_ISSUED_SKEW_S: 30 = 30;

How far apart the signer's and the verifier's clocks may be.


SELF_ISSUED_TYP

const SELF_ISSUED_TYP: "wellknown-self-issued+jwt" = 'wellknown-self-issued+jwt';

The token's JOSE typ (RFC 8725 §3.11, explicit typing): the same site key signs succession statements (§4.9).

Functions

didUrl()

function didUrl(did): string;

The DID URL of a did:key's only key: did:key:z…#z…

Parameters

ParameterType
didstring

Returns

string


jwkFromDidKey()

function jwkFromDidKey(did): JsonWebKey;

The public JWK a did:key names: P-256 decompressed here (WebCrypto imports only whole points), or Ed25519.

Parameters

ParameterType
didstring

Returns

JsonWebKey


nonceFor()

function nonceFor(verifier): Promise<string>;

S256(verifier), as PKCE (RFC 7636 §4.2) computes a code_challenge: a direct token's nonce.

Parameters

ParameterType
verifierstring

Returns

Promise<string>


peekNonce()

function peekNonce(token): string | undefined;

The token's nonce, unverified: the IdP finds the challenge it answers by it (and spends it) before verifying. Undefined if the token can't be read.

Parameters

ParameterType
tokenunknown

Returns

string | undefined


signSelfIssued()

function signSelfIssued(key, o): Promise<string>;

Signs a self-issued token with key (the persona's key for the site aud): ES256 for a P-256 did:key, EdDSA for Ed25519; sign returns the raw signature (r||s for ES256). Call it just before the token is sent. now: milliseconds (Date.now(), or the IdP's clock as its challenge said).

Parameters

ParameterType
key{ did: string; sign: | Uint8Array<ArrayBufferLike> | Promise<Uint8Array<ArrayBufferLike>>; }
key.didstring
key.sign
o{ amr?: string[]; aud: string; grant?: string; group?: string; nonce: string; now?: number; succession?: string; }
o.amr?string[]
o.audstring
o.grant?string
o.group?string
o.noncestring
o.now?number
o.succession?string

Returns

Promise<string>


verifySelfIssued()

function verifySelfIssued(token, o): Promise<SelfIssuedClaims>;

Verifies a self-issued token for aud (the client_id), answering nonce (the IdP's challenge, or the site's) or verifier (a site's backend: the nonce is S256 of it). Checks, in order: the compact form, typ (so no succession statement or other JWT a site key signs passes), alg against the did:key's type, kid a key of iss, iss = sub = a did:key, the signature, aud, the nonce, iat and exp with SELF_ISSUED_SKEW_S of skew, and a lifetime of at most SELF_ISSUED_LIFETIME_S. Throws SelfIssuedError saying what's wrong; returns the claims. Single use is the caller's: the IdP spends its challenge, a site its nonce.

Parameters

ParameterType
tokenunknown
o{ aud: string; nonce?: string; now?: number; skewS?: number; verifier?: string; }
o.audstring
o.nonce?string
o.now?number
o.skewS?number
o.verifier?string

Returns

Promise<SelfIssuedClaims>