Skip to content

API reference / @jsprismarine/auth

@jsprismarine/auth ​

The login identity of Minecraft: Bedrock Edition, for both ends of a connection. A client uses it to present an identity: the JWT chain or multiplayer token, the client data blob, and the key both are signed with. A server uses it to check that a login belongs to the account it names.

It is a package of its own so that a provider is chosen at the edge of an application: nothing in the client core imports one, and Xbox Live code loads only when a provider signs in.

Client: presenting an identity ​

Every provider implements IAuthProvider. Two ship with the package:

  • OfflineAuthProvider signs its own identity, which is what the game client sends when it is not signed in. A server in online mode refuses it, since there is no XUID to check; a server with online-mode off accepts it.
  • XboxAuthProvider signs in to Xbox Live and presents the chain and multiplayer token that Minecraft services issue for its key. A server in online mode admits it.
typescript
import { OfflineAuthProvider } from '@jsprismarine/auth';

const auth = new OfflineAuthProvider({ displayName: 'Steve' });
const credentials = await auth.createLoginCredentials({
    serverAddress: '127.0.0.1:19132',
    protocolVersion: 2193
});

XboxAuthProvider signs in through prismarine-auth, an optional peer dependency. Install it beside this package to use the provider:

sh
pnpm add @jsprismarine/auth prismarine-auth

The first sign-in asks for a device code. prismarine-auth caches the account, so later runs sign in without one:

typescript
import { XboxAuthProvider } from '@jsprismarine/auth';

const auth = new XboxAuthProvider({
    cacheDirectory: './auth-cache',
    onDeviceCode: (code) => console.log(code.message)
});

getMultiplayerToken() returns the token for a transport that presents the identity before the login does. @jsprismarine/client signs its NetherNet offer with it.

To choose a provider from a setting, createAuthProvider builds one by name:

typescript
import { createAuthProvider } from '@jsprismarine/auth';

const auth = createAuthProvider({ provider: 'xbox', cacheDirectory: './auth-cache' });

A provider of your own can extend KeyedAuthProvider, which holds the identity key and signs the client data, and supply only the identity and the chain.

Server: verifying a login ​

verifyLogin checks a login's two signatures: Minecraft services signed the multiplayer token, which names the account and the client's key, and that key signed the client data. It fails closed and throws LoginRefused, whose message is safe to show the player.

typescript
import { LoginRefused, verifyLogin } from '@jsprismarine/auth/server';

try {
    const { xuid, displayName } = await verifyLogin(login);
} catch (error) {
    if (error instanceof LoginRefused) disconnect(error.message);
}

The issuer's public keys come from MojangKeys, fetched on demand and kept for an hour. useLoginKeys replaces the source in a test.

Entry points ​

  • @jsprismarine/auth exports everything.
  • @jsprismarine/auth/client exports the providers and the client data.
  • @jsprismarine/auth/server exports login verification.
  • @jsprismarine/auth/protocol exports the values both ends agree on, such as TOKEN_ISSUER and AuthenticationType.

The default skin ​

The default skin is generated, not shipped: flat color blocks laid out over the regions the classic humanoid geometry samples. Mojang's textures cannot be redistributed, and a client that refused to log in without one would be useless.

Classes ​

Interfaces ​

AnimatedImage ​

Defined in: ClientData.ts:51

Properties ​

AnimationExpression ​

AnimationExpression: number

Defined in: ClientData.ts:57

Frames ​

Frames: number

Defined in: ClientData.ts:55

Image ​

Image: string

Defined in: ClientData.ts:52

ImageHeight ​

ImageHeight: number

Defined in: ClientData.ts:54

ImageWidth ​

ImageWidth: number

Defined in: ClientData.ts:53

Type ​

Type: number

Defined in: ClientData.ts:56


ClientDataOptions ​

Defined in: ClientData.ts:60

Properties ​

clientRandomId ​

readonly clientRandomId: number

Defined in: ClientData.ts:62

deviceId? ​

readonly optional deviceId?: string

Defined in: ClientData.ts:74

deviceModel? ​

readonly optional deviceModel?: string

Defined in: ClientData.ts:75

deviceOS? ​

readonly optional deviceOS?: number

Defined in: ClientData.ts:76

displayName? ​

readonly optional displayName?: string

Defined in: ClientData.ts:71

The name to play under when nothing vouched for one.

Only an unauthenticated login needs it. Up to 1.26.10 the name traveled in the certificate chain's extraData, and this stayed empty; a login that carries a token instead of a chain has nowhere else to put it.

gameVersion? ​

readonly optional gameVersion?: string

Defined in: ClientData.ts:73

languageCode? ​

readonly optional languageCode?: string

Defined in: ClientData.ts:72

selfSignedId ​

readonly selfSignedId: string

Defined in: ClientData.ts:63

serverAddress ​

readonly serverAddress: string

Defined in: ClientData.ts:61

skinHeight? ​

readonly optional skinHeight?: number

Defined in: ClientData.ts:81

skinId? ​

readonly optional skinId?: string

Defined in: ClientData.ts:77

skinImage? ​

readonly optional skinImage?: Buffer<ArrayBufferLike>

Defined in: ClientData.ts:79

Raw RGBA, width * height * 4 bytes. Defaults to the generated skin.

skinWidth? ​

readonly optional skinWidth?: number

Defined in: ClientData.ts:80


ClientDataPayload ​

Defined in: ClientData.ts:13

The payload of the second JWT a Login carries.

Every field is PascalCase because that is how Mojang names them on the wire, and the server reads them by those exact names. The shape is not optional in practice: the server builds a Skin out of this and reads SkinData, SkinResourcePatch, CapeData, SkinGeometryData and AnimatedImageData unconditionally, so a client that omits any of them crashes the handler rather than being politely refused.

Indexable ​

[key: string]: unknown

Properties ​

AnimatedImageData ​

AnimatedImageData: AnimatedImage[]

Defined in: ClientData.ts:30

ArmSize ​

ArmSize: string

Defined in: ClientData.ts:31

CapeData ​

CapeData: string

Defined in: ClientData.ts:32

CapeId ​

CapeId: string

Defined in: ClientData.ts:33

CapeImageHeight ​

CapeImageHeight: number

Defined in: ClientData.ts:34

CapeImageWidth ​

CapeImageWidth: number

Defined in: ClientData.ts:35

CapeOnClassicSkin ​

CapeOnClassicSkin: boolean

Defined in: ClientData.ts:36

ClientRandomId ​

ClientRandomId: number

Defined in: ClientData.ts:14

CurrentInputMode ​

CurrentInputMode: number

Defined in: ClientData.ts:15

DefaultInputMode ​

DefaultInputMode: number

Defined in: ClientData.ts:16

DeviceId ​

DeviceId: string

Defined in: ClientData.ts:17

DeviceModel ​

DeviceModel: string

Defined in: ClientData.ts:18

DeviceOS ​

DeviceOS: number

Defined in: ClientData.ts:19

GameVersion ​

GameVersion: string

Defined in: ClientData.ts:20

GuiScale ​

GuiScale: number

Defined in: ClientData.ts:21

LanguageCode ​

LanguageCode: string

Defined in: ClientData.ts:22

PersonaSkin ​

PersonaSkin: boolean

Defined in: ClientData.ts:37

PlatformOnlineId ​

PlatformOnlineId: string

Defined in: ClientData.ts:23

PlayFabId ​

PlayFabId: string

Defined in: ClientData.ts:24

PremiumSkin ​

PremiumSkin: boolean

Defined in: ClientData.ts:38

SelfSignedId ​

SelfSignedId: string

Defined in: ClientData.ts:25

ServerAddress ​

ServerAddress: string

Defined in: ClientData.ts:26

SkinAnimationData ​

SkinAnimationData: string

Defined in: ClientData.ts:39

SkinColor ​

SkinColor: string

Defined in: ClientData.ts:40

SkinData ​

SkinData: string

Defined in: ClientData.ts:41

SkinGeometryData ​

SkinGeometryData: string

Defined in: ClientData.ts:42

SkinId ​

SkinId: string

Defined in: ClientData.ts:43

SkinImageHeight ​

SkinImageHeight: number

Defined in: ClientData.ts:44

SkinImageWidth ​

SkinImageWidth: number

Defined in: ClientData.ts:45

SkinResourcePatch ​

SkinResourcePatch: string

Defined in: ClientData.ts:46

ThirdPartyName ​

ThirdPartyName: string

Defined in: ClientData.ts:27

ThirdPartyNameOnly ​

ThirdPartyNameOnly: boolean

Defined in: ClientData.ts:28


DeviceCode ​

Defined in: XboxAuthProvider.ts:45

The code a person enters to sign in, the first time an account is used.

Properties ​

expiresInSeconds ​

readonly expiresInSeconds: number

Defined in: XboxAuthProvider.ts:51

How long the code is good for.

message ​

readonly message: string

Defined in: XboxAuthProvider.ts:53

Microsoft's own instruction, naming both.

userCode ​

readonly userCode: string

Defined in: XboxAuthProvider.ts:47

The code to enter.

verificationUri ​

readonly verificationUri: string

Defined in: XboxAuthProvider.ts:49

Where to enter it.


IAuthProvider ​

Defined in: IAuthProvider.ts:48

Where a login identity comes from.

The seam exists so that what the bot harness needs - hundreds of throwaway identities, no network, no token cache - and what a real client needs are the same shape to everything upstream. It is also what keeps Xbox Live out of the headless build: a provider is chosen at the edge, and nothing in the client core imports one.

Properties ​

name ​

readonly name: string

Defined in: IAuthProvider.ts:50

For logs and for choosing between cached sessions.

Methods ​

createLoginCredentials() ​

createLoginCredentials(request): Promise<LoginCredentials>

Defined in: IAuthProvider.ts:67

Signs, or fetches, the credentials for one login.

Called once per connection attempt rather than cached, because the client data carries the address being dialled and the chain carries an expiry.

Parameters ​
request ​

LoginRequest

Returns ​

Promise<LoginCredentials>

getIdentity() ​

getIdentity(): Promise<Identity>

Defined in: IAuthProvider.ts:59

The identity this provider will log in as.

Available before createLoginCredentials so a caller can label a connection before it has made one - a bot harness reporting which of five hundred it is waiting on, say.

Returns ​

Promise<Identity>

getIdentityPrivateKey() ​

getIdentityPrivateKey(): Promise<string>

Defined in: IAuthProvider.ts:84

The private key, for the ECDH half of the encryption handshake.

Returned as a PEM-encoded PKCS#8 string rather than a KeyObject so that a provider backed by something that is not node's crypto stays possible.

Returns ​

Promise<string>

getIdentityPublicKey() ​

getIdentityPublicKey(): Promise<string>

Defined in: IAuthProvider.ts:76

The public half of the key the chain is signed with, DER encoded and base64'd - the same string the chain's identityPublicKey claim carries.

Encryption derives its shared secret from this key, so a provider has to expose it even though nothing in the login itself asks for it separately.

Returns ​

Promise<string>

getMultiplayerToken()? ​

optional getMultiplayerToken(): Promise<string | undefined>

Defined in: IAuthProvider.ts:93

The multiplayer token Minecraft services issued for this provider's key, for a transport that presents the identity before the login does: NetherNet signs its WebRTC offer with it.

Undefined, or left out, for a provider nobody vouches for; the transport then signs a token of its own.

Returns ​

Promise<string | undefined>


Identity ​

Defined in: IAuthProvider.ts:24

Who the player is, as far as the login is concerned.

Properties ​

displayName ​

readonly displayName: string

Defined in: IAuthProvider.ts:29

identity ​

readonly identity: string

Defined in: IAuthProvider.ts:28

The uuid the client is known by. The server rejects a login with no identity.

titleId? ​

readonly optional titleId?: string

Defined in: IAuthProvider.ts:30

xuid ​

readonly xuid: string

Defined in: IAuthProvider.ts:26

Empty when not authenticated. A server in online mode refuses that.


LoginCredentials ​

Defined in: IAuthProvider.ts:9

The two JWT blobs a Login packet carries.

Deliberately the encoded form rather than the data behind it: an offline provider signs these itself, and an Xbox one receives most of the chain already signed by Mojang and cannot reconstruct it. What they have in common is the pair of strings that goes on the wire, so that is what the interface is about.

Properties ​

chainData ​

readonly chainData: string

Defined in: IAuthProvider.ts:18

The chain JSON. For a server from 1.26.10 on this is the envelope {"Certificate": "<json>", "AuthenticationType": n, "Token": "<JWT>"}, where Certificate holds {"chain": [...]} as a string and Token carries the identity. Older servers take {"chain": [...]} directly, one JWT per link. Offline that is a single self-signed link; authenticated it is the client's own token followed by Mojang's.

clientData ​

readonly clientData: string

Defined in: IAuthProvider.ts:20

One JWT: skin, device, language, and the address the client thinks it dialled.


LoginKeySource ​

Defined in: LoginVerifier.ts:25

Where the signing keys come from; a test supplies its own.

Methods ​

keyFor() ​

keyFor(kid): Promise<VerificationKey | undefined>

Defined in: LoginVerifier.ts:27

The public key a token's kid names, or undefined when the issuer has no such key.

Parameters ​
kid ​

string

Returns ​

Promise<VerificationKey | undefined>


LoginRequest ​

Defined in: IAuthProvider.ts:33

Properties ​

protocolVersion ​

readonly protocolVersion: number

Defined in: IAuthProvider.ts:37

The protocol version being spoken, echoed into the client data.

serverAddress ​

readonly serverAddress: string

Defined in: IAuthProvider.ts:35

Where we are connecting, as the client reports it: host:port.


OfflineAuthOptions ​

Defined in: OfflineAuthProvider.ts:11

Properties ​

clientData? ​

readonly optional clientData?: Partial<ClientDataOptions>

Defined in: OfflineAuthProvider.ts:21

displayName ​

readonly displayName: string

Defined in: OfflineAuthProvider.ts:13

The name that shows up in chat and the player list.

identity? ​

readonly optional identity?: string

Defined in: OfflineAuthProvider.ts:20

The uuid the server knows this player by, stable across reconnects if you supply it.

Worth supplying for a client with a world to come back to, and worth not supplying for a bot fleet, where five hundred connections each need their own.

key? ​

readonly optional key?: IdentityKey

Defined in: OfflineAuthProvider.ts:23

The identity key, a fresh one by default.


VerifiedLogin ​

Defined in: LoginVerifier.ts:43

The claims a verified multiplayer token vouches for.

Properties ​

displayName ​

readonly displayName: string

Defined in: LoginVerifier.ts:46

identity ​

readonly identity: string | undefined

Defined in: LoginVerifier.ts:48

The player's persistent uuid when the token carries one.

identityPublicKey ​

readonly identityPublicKey: string

Defined in: LoginVerifier.ts:50

The client's identity key, base64 DER, which also signed the client data.

xuid ​

readonly xuid: string

Defined in: LoginVerifier.ts:45

The Xbox Live id.


XboxAuthOptions ​

Defined in: XboxAuthProvider.ts:57

How XboxAuthProvider signs in.

Properties ​

account? ​

readonly optional account?: string

Defined in: XboxAuthProvider.ts:62

The name the sign-in is cached under, so several accounts can share a cache directory. Defaults to default.

cacheDirectory? ​

readonly optional cacheDirectory?: string

Defined in: XboxAuthProvider.ts:64

Where prismarine-auth keeps the sign-in between runs. Defaults to its own location.

clientData? ​

readonly optional clientData?: Partial<ClientDataOptions>

Defined in: XboxAuthProvider.ts:72

key? ​

readonly optional key?: IdentityKey

Defined in: XboxAuthProvider.ts:74

The identity key, a fresh one by default.

now? ​

readonly optional now?: () => number

Defined in: XboxAuthProvider.ts:76

The clock, in milliseconds since the epoch.

Returns ​

number

onDeviceCode? ​

readonly optional onDeviceCode?: (code) => void

Defined in: XboxAuthProvider.ts:69

Called with the device code when nobody is signed in yet. Without it prismarine-auth prints the code itself.

Parameters ​
code ​

DeviceCode

Returns ​

void

tokens? ​

readonly optional tokens?: XboxTokenSource

Defined in: XboxAuthProvider.ts:71

Where the tokens come from. Defaults to prismarine-auth, which must then be installed.


XboxLogin ​

Defined in: XboxAuthProvider.ts:18

What Xbox Live issues for an identity key: Mojang's chain for it, and the multiplayer token.

Properties ​

chain ​

readonly chain: readonly string[]

Defined in: XboxAuthProvider.ts:20

The chain Minecraft services signed, starting with the link that names the client's key.

token ​

readonly token: string

Defined in: XboxAuthProvider.ts:22

The multiplayer token, whose cpk claim is the client's key.


XboxTokenSource ​

Defined in: XboxAuthProvider.ts:36

Where a signed-in account's tokens come from. prismarine-auth's Authflow fits; a test supplies its own.

Methods ​

getMinecraftBedrockToken() ​

getMinecraftBedrockToken(publicKey): Promise<{ chain: string[]; token?: string; }>

Defined in: XboxAuthProvider.ts:41

Signs in, or reuses a cached sign-in, and has Minecraft services issue a chain and a multiplayer token for the key.

Parameters ​
publicKey ​

KeyObject

Returns ​

Promise<{ chain: string[]; token?: string; }>

Type Aliases ​

AuthProviderName ​

AuthProviderName = AuthProviderOptions["provider"]

Defined in: createAuthProvider.ts:12

The names createAuthProvider knows.


AuthProviderOptions ​

AuthProviderOptions = object & OfflineAuthOptions | object & XboxAuthOptions

Defined in: createAuthProvider.ts:8

A provider chosen by name, with that provider's options: the shape a config file or a command line gives.


AuthenticationType ​

AuthenticationType = typeof AuthenticationType[keyof typeof AuthenticationType]

Defined in: protocol.ts:29

One of the AuthenticationType values.

Variables ​

AuthenticationType ​

const AuthenticationType: object

Defined in: protocol.ts:29

The connection request's AuthenticationType: who vouches for the identity it carries.

Type Declaration ​

Full ​

readonly Full: 0 = 0

A signed-in Xbox Live account, vouched for by Minecraft services.

Guest ​

readonly Guest: 1 = 1

A guest of a signed-in player, such as a split-screen second player.

SelfSigned ​

readonly SelfSigned: 2 = 2

Nobody: the client signed its identity itself.


DEFAULT_SKIN_RESOURCE_PATCH ​

const DEFAULT_SKIN_RESOURCE_PATCH: string

Defined in: DefaultSkin.ts:79

Which model the client should hang the texture on.

geometry.humanoid.custom is resolved by the client against a model it already has, so this is a reference rather than geometry we would have to ship. SkinGeometryData stays empty for the same reason.


FIRST_TOKEN_PROTOCOL ​

const FIRST_TOKEN_PROTOCOL: 944 = 944

Defined in: protocol.ts:13

The first protocol whose servers want a multiplayer token rather than a certificate chain.

1.26.10 moved the identity out of the chain: a server at or past this reads the Token field of a connection request, and refuses the old shape by going quiet at the RakNet layer rather than by answering, which is why the version is worth stating rather than discovering.


MOJANG_ROOT_KEY ​

const MOJANG_ROOT_KEY: "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAECRXueJeTDqNRRgJi/vlRufByu/2G0i2Ebt6YMar5QX/R0DIIyrJMcUpruK4QveTfJSTp3Shlq4Gk34cD/4GUWwkv0DVuzeuB+tXija7HBxii03NHDbPAD0AKnLr2wdAp" = 'MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAECRXueJeTDqNRRgJi/vlRufByu/2G0i2Ebt6YMar5QX/R0DIIyrJMcUpruK4QveTfJSTp3Shlq4Gk34cD/4GUWwkv0DVuzeuB+tXija7HBxii03NHDbPAD0AKnLr2wdAp'

Defined in: protocol.ts:25

Mojang's root key, base64 DER. A signed-in client's own chain link names it as the key that signs the next link, and the chain Xbox Live issued continues from there.


MULTIPLAYER_AUDIENCE ​

const MULTIPLAYER_AUDIENCE: "api://auth-minecraft-services/multiplayer" = 'api://auth-minecraft-services/multiplayer'

Defined in: protocol.ts:16

What a multiplayer token says it is for. A server checks the audience even when it verifies nothing else.


SKIN_HEIGHT ​

const SKIN_HEIGHT: 64 = 64

Defined in: DefaultSkin.ts:3


SKIN_WIDTH ​

const SKIN_WIDTH: 64 = 64

Defined in: DefaultSkin.ts:2

A Bedrock skin texture is always RGBA, and 64x64 is the classic layout.


TOKEN_ISSUER ​

const TOKEN_ISSUER: "https://authorization.franchise.minecraft-services.net/" = 'https://authorization.franchise.minecraft-services.net/'

Defined in: protocol.ts:19

Who signs the multiplayer token of a signed-in account, and where the keys that check it are published.

Functions ​

createAuthProvider() ​

createAuthProvider(options): IAuthProvider

Defined in: createAuthProvider.ts:23

Builds the provider a setting names, so an application picks one at its edge without importing each.

Parameters ​

options ​

AuthProviderOptions

The provider's name and its options.

Returns ​

IAuthProvider

Example ​

typescript
const auth = createAuthProvider(signedIn ? { provider: 'xbox' } : { provider: 'offline', displayName: 'Steve' });

createClientData() ​

createClientData(options): ClientDataPayload

Defined in: ClientData.ts:91

Builds the client data a login carries, filling in everything the server insists on.

The defaults describe a Windows client on the pinned protocol version, which is what the bot harness and the headless client both want; a GUI client overrides the few fields that are genuinely about the machine it is running on.

Parameters ​

options ​

ClientDataOptions

Returns ​

ClientDataPayload


createDefaultSkinImage() ​

createDefaultSkinImage(): Buffer

Defined in: DefaultSkin.ts:51

The skin the client wears when nothing else has been supplied.

Generated rather than shipped as a PNG, and generated from flat color blocks that are ours: Mojang's textures cannot be redistributed, and a client that refuses to log in without one would be useless. It is deliberately plain - the point is a valid, original 16 KiB of RGBA, not a good-looking character.

Returns ​

Buffer

64 * 64 * 4 bytes of RGBA, row major from the top left.


loginKeys() ​

loginKeys(): LoginKeySource

Defined in: LoginVerifier.ts:87

The key source logins are checked against.

Returns ​

LoginKeySource


useLoginKeys() ​

useLoginKeys(keys): () => void

Defined in: LoginVerifier.ts:90

Replaces the key source, for a test; returns a function that puts the old one back.

Parameters ​

keys ​

LoginKeySource

Returns ​

() => void


verifyLogin() ​

verifyLogin(login, keys?, now?): Promise<VerifiedLogin>

Defined in: LoginVerifier.ts:140

Checks that a login belongs to the account it names.

Two signatures carry that. The multiplayer token is signed by Minecraft services and states the account and the client's identity key (cpk); the client data, which holds the skin and device, is signed by that key. Together they say that whoever holds the key was issued this account, and that the data in the login came from them. Everything else in the connection request is ignored: a certificate chain is not evidence of an account.

jose checks both signatures and the token's iss, exp and nbf. The algorithms are fixed here, never read from a token, or a token could choose its own check ("none", or a MAC keyed with the public key).

Fails closed. A missing token, an unknown key, an expired or foreign token, a bad signature and an issuer that cannot be reached each refuse the login.

Parameters ​

login ​

LoginCredentials

The login's two JWT blobs; a decoded Login packet has both.

keys? ​

LoginKeySource = ...

Where to find the issuer's public keys.

now? ​

number = ...

The current time in milliseconds, for expiry.

Returns ​

Promise<VerifiedLogin>

Throws ​

when the login cannot be attributed to an account.