API reference

@wellknown-id/wallet/grants

Delegation for sites (prd.md §7.13): checking a grant that lets one holder act for another at your site, and whether it still stands. A grant is a JWS the granter signs with their key for your site, sealed to your site's HPKE key and posted to the mailbox your config names; look it up at every use (grantStands): gone means taken back.

Classes

GrantError

Why a grant was refused (its message says what was wrong).

Extends

  • Error

Constructors

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

GrantError

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

GrantError

Inherited from
Error.constructor

Type Aliases

Delegation

type Delegation = object;

What a site says about delegation in its wellknown.id config (§5.2): whether it accepts it, its key, its mailbox.

Properties

PropertyTypeDescription
acceptboolean-
keyUint8ArrayThe site's X25519 public key, for HPKE (a JWK: kty OKP, crv X25519).
mailboxstring-
maxDaysnumberThe longest a grant may run there, in days.
scopesobject[]What may be delegated there, in the site's words.

GrantClaims

type GrantClaims = object;

What a grant says, in RFC 8693's terms: the granter (iss = sub) lets may_act.sub act for them at aud.

Properties

PropertyTypeDescription
audstringThe site (its client_id).
expnumberWhen the grant ends, whatever else happens (seconds since the epoch).
iatnumber-
issstringThe granter's did:key at the site.
jtistringThe grant's id: where it's posted in the mailbox (32 random bytes, base64url).
may_actobjectThe actor, by their own did:key at the same site.
may_act.substring-
mbxstringThe mailbox it's posted to (the site's, or wellknown.id's).
nbfnumber-
policystringWhat the actor may do, as a karu policy (§6).
scope?string[]The site's own names for what was granted, from its config's delegation.scopes, for screens.
substringThe granter again: the subject the actor acts for.

Variables

DEFAULT_GRANT_MAILBOX

const DEFAULT_GRANT_MAILBOX: "https://kivi.wellknown.id/relay" = 'https://kivi.wellknown.id/relay';

The mailbox a site that accepts delegation reads from when its config names none: wellknown.id's relay.


GRANT_INFO

const GRANT_INFO: Uint8Array<ArrayBufferLike>;

HPKE's info for a grant sealed to a site: binds the ciphertext to this use.


GRANT_TYP

const GRANT_TYP: "wellknown-grant+jwt" = 'wellknown-grant+jwt';

A grant's JOSE typ (RFC 8725 §3.11, explicit typing).


MAX_GRANT_DAYS

const MAX_GRANT_DAYS: 365 = 365;

The longest a grant may run, whatever a site allows (the mailbox keeps a blob 400 days at most).

Functions

checkGrantClaims()

function checkGrantClaims(c, expect): void;

What every grant must say, whoever signed it (one granter, or a shared identity's members: groups.ts): the site, someone else named to act, a policy, an id and a mailbox, and dates that hold now.

Parameters

ParameterType
cGrantClaims
expect{ actor?: string; leewayS?: number; now?: number; site: string; }
expect.actor?string
expect.leewayS?number
expect.now?number
expect.sitestring

Returns

void


grantClaims()

function grantClaims(jws): GrantClaims;

A grant's claims, unchecked (for screens that hold one already checked).

Parameters

ParameterType
jwsstring

Returns

GrantClaims


grantPosted()

function grantPosted(
   mailbox, 
   jti, 
   fetchImpl?
): Promise<boolean>;

Whether a grant still stands, by its mailbox, as the IdP asks at sign-in: there (200) yes; removed (410) or lapsed or never posted (404) no. Anything else (the mailbox down) throws: a delegated sign-in fails closed.

Parameters

ParameterTypeDefault value
mailboxstringundefined
jtistringundefined
fetchImpl{ (input, init?): Promise<Response>; (input, init?): Promise<Response>; }fetch

Returns

Promise<boolean>


grantStands()

function grantStands(jws, o): Promise<{
  claims: GrantClaims;
  stands: boolean;
}>;

For a site, at every use: whether the grant Bob presented still stands. Fetches it from the site's mailbox by its id, opens it with the site's key and checks it's the very grant presented (and verifies it again). A grant taken back or lapsed: stands: false. Throws if the mailbox can't be asked, or holds something else under that id.

Parameters

ParameterType
jwsstring
o{ actor?: string; fetch?: { (input, init?): Promise<Response>; (input, init?): Promise<Response>; }; mailbox: string; now?: number; site: string; siteKey: { privateKey: Uint8Array; publicKey: Uint8Array; }; }
o.actor?string
o.fetch?{ (input, init?): Promise<Response>; (input, init?): Promise<Response>; }
o.mailboxstring
o.now?number
o.sitestring
o.siteKey{ privateKey: Uint8Array; publicKey: Uint8Array; }
o.siteKey.privateKeyUint8Array
o.siteKey.publicKeyUint8Array

Returns

Promise<{ claims: GrantClaims; stands: boolean; }>


openGrant()

function openGrant(
   sealed, 
   jti, 
   site
): string;

Opens a sealed grant with the site's key pair. Throws if it isn't the site's, or was moved or changed.

Parameters

ParameterType
sealedUint8Array
jtistring
site{ privateKey: Uint8Array; publicKey: Uint8Array; }
site.privateKeyUint8Array
site.publicKeyUint8Array

Returns

string


parseDelegation()

function parseDelegation(config): Delegation | undefined;

The delegation block of a site's config, checked; undefined if it has none. Throws on one that's malformed.

Parameters

ParameterType
configunknown

Returns

Delegation | undefined


policyFor()

function policyFor(scopes, o): string;

The karu policy a grant carries when the holder picks from the site's scopes (§6): each scope an action Bob may take, until the grant ends. Holders will write their own in time (user-authored policy tooling, on the roadmap); a grant's policy is any karu the site's evaluator accepts.

Parameters

ParameterType
scopesstring[]
o{ actor: string; granter: string; site: string; until: number; }
o.actorstring
o.granterstring
o.sitestring
o.untilnumber

Returns

string


postGrant()

function postGrant(
   claims, 
   sealed, 
   write, 
   fetchImpl?
): Promise<void>;

Posts a sealed grant to its mailbox, under its id, with a write key only the granter's devices hold.

Parameters

ParameterTypeDefault value
claimsGrantClaimsundefined
sealedUint8Arrayundefined
writeUint8Arrayundefined
fetchImpl{ (input, init?): Promise<Response>; (input, init?): Promise<Response>; }fetch

Returns

Promise<void>


sealGrant()

function sealGrant(
   jws, 
   jti, 
   siteKey
): Uint8Array<ArrayBufferLike>;

The grant sealed to the site's key, as it's posted: bound to its id (the AAD), so it can't be moved to another.

Parameters

ParameterType
jwsstring
jtistring
siteKeyUint8Array

Returns

Uint8Array<ArrayBufferLike>


signGrant()

function signGrant(key, o): object;

Signs a grant with the granter's key for the site (key): ES256. Returns the JWS and its claims.

Parameters

ParameterType
key{ did: string; secret: Uint8Array; }
key.didstring
key.secretUint8Array
o{ actor: string; days: number; mailbox: string; now?: number; policy: string; scope?: string[]; site: string; }
o.actorstring
o.daysnumber
o.mailboxstring
o.now?number
o.policystring
o.scope?string[]
o.sitestring

Returns

object

NameType
claimsGrantClaims
jwsstring

unpostGrant()

function unpostGrant(
   mailbox, 
   jti, 
   write, 
   fetchImpl?
): Promise<void>;

Takes a grant back: the blob removed from its mailbox, so every later look-up finds it gone.

Parameters

ParameterTypeDefault value
mailboxstringundefined
jtistringundefined
writeUint8Arrayundefined
fetchImpl{ (input, init?): Promise<Response>; (input, init?): Promise<Response>; }fetch

Returns

Promise<void>


verifyGrant()

function verifyGrant(jws, expect): GrantClaims;

Checks a grant for site: its type, the granter's signature, the site, the dates, and (where given) that it names actor. Resolves what it says, or throws why not. It doesn't say whether the grant still stands: that's the mailbox's (grantStands).

Parameters

ParameterType
jwsunknown
expect{ actor?: string; leewayS?: number; now?: number; site: string; }
expect.actor?string
expect.leewayS?number
expect.now?number
expect.sitestring

Returns

GrantClaims