Interface Credentials

Credentials is a virtual WebAuthn authenticator scoped to a BrowserContext. It lets tests register passkeys and answer navigator.credentials.create() / navigator.credentials.get() ceremonies in the page, without a real authenticator or hardware security key.

There are three common ways to use it:

Usage: seed a known credential

const context = await browser.newContext();

// A passkey your backend already provisioned for a test user.
await context.credentials.create('example.com', {
id: knownCredentialId, // base64url
userHandle: knownUserHandle, // base64url
privateKey: knownPrivateKey, // base64url PKCS#8 (DER)
publicKey: knownPublicKey, // base64url SPKI (DER)
});
await context.credentials.install();

const page = await context.newPage();
await page.goto('https://example.com/login');
// The page's navigator.credentials.get() is answered with the seeded passkey.

Usage: capture a credential, then reuse it

// setup test: let the app register a passkey, then save the storage state with it.
const context = await browser.newContext();
await context.credentials.install();

const page = await context.newPage();
await page.goto('https://example.com/register');
await page.getByRole('button', { name: 'Create a passkey' }).click();

// Read back the passkey the page registered — it includes the private key.
const [credential] = await context.credentials.get({ rpId: 'example.com' });
fs.writeFileSync('playwright/.auth/passkey.json', JSON.stringify(credential));
// later test: seed the captured passkey so the app starts already enrolled.
const credential = JSON.parse(fs.readFileSync('playwright/.auth/passkey.json', 'utf8'));
const context = await browser.newContext();
await context.credentials.create(credential.rpId, credential);
await context.credentials.install();

const page = await context.newPage();
await page.goto('https://example.com/login');
// navigator.credentials.get() resolves the captured passkey — already signed in.

Usage: save credentials in the storage state, restore later

See authentication guide for examples of using saving and resotring the storage state.

Defaults

interface Credentials {
    create(rpId, options?): Promise<{
        id: string;
        privateKey: string;
        publicKey: string;
        rpId: string;
        userHandle: string;
    }>;
    delete(id): Promise<void>;
    get(options?): Promise<{
        id: string;
        privateKey: string;
        publicKey: string;
        rpId: string;
        userHandle: string;
    }[]>;
    install(): Promise<void>;
}

Methods

  • Seeds a virtual WebAuthn credential and returns it.

    With only rpId, generates a fresh ECDSA P-256 keypair, credential id and user handle. The seeded credential is discoverable (resident), so the page can resolve it from both username-then-passkey and usernameless passkey flows. The returned object carries the private and public keys, so it can be persisted to disk and re-seeded in a later test.

    To import a known credential, supply all four of id, userHandle, privateKey and publicKey together.

    Call credentials.install() before navigating to a page that uses WebAuthn.

    Parameters

    • rpId: string

      Relying party id (typically the site's effective domain).

    • Optional options: {
          id?: string;
          privateKey?: string;
          publicKey?: string;
          userHandle?: string;
      }
      • Optional id?: string

        Base64url-encoded credential id. Auto-generated if omitted.

      • Optional privateKey?: string

        Base64url-encoded PKCS#8 (DER) private key. Auto-generated if omitted.

      • Optional publicKey?: string

        Base64url-encoded SPKI (DER) public key. Auto-generated if omitted.

      • Optional userHandle?: string

        Base64url-encoded user handle. Auto-generated if omitted.

    Returns Promise<{
        id: string;
        privateKey: string;
        publicKey: string;
        rpId: string;
        userHandle: string;
    }>

  • Removes a credential from the authenticator by its id. Works for any credential currently held — both those seeded with credentials.create(rpId[, options]) and those the page registered itself by calling navigator.credentials.create().

    Parameters

    • id: string

      Base64url-encoded credential id.

    Returns Promise<void>

  • Returns every credential currently held by the authenticator, optionally filtered by rpId or id. This includes both credentials seeded with credentials.create(rpId[, options]) and credentials the page registered itself by calling navigator.credentials.create().

    Each returned credential includes its private and public keys, so a passkey the app just registered can be saved and re-seeded into a later test with credentials.create(rpId[, options]) — see the second example in the class overview.

    Parameters

    • Optional options: {
          id?: string;
          rpId?: string;
      }
      • Optional id?: string

        Only return the credential with this base64url-encoded id.

      • Optional rpId?: string

        Only return credentials for this relying party id.

    Returns Promise<{
        id: string;
        privateKey: string;
        publicKey: string;
        rpId: string;
        userHandle: string;
    }[]>

  • Installs the virtual WebAuthn authenticator into the context, overriding navigator.credentials.create() and navigator.credentials.get() in all current and future pages. Call this before the page first touches navigator.credentials.

    Required: until credentials.install() is called, no interception is in place and the page sees the platform's native (or absent) WebAuthn behaviour. Seeding credentials with credentials.create(rpId[, options]) without installing populates the authenticator, but the page will never see those credentials.

    Returns Promise<void>