Extensions

This page is about an advanced feature. You can skip it if you are new with WebAuthn.

WebAuthn extensions are optional features that extend the core WebAuthn specification to support additional use cases and capabilities. They allow authenticators and browsers to provide extra functionality beyond basic authentication.

What Are Extensions?

Extensions provide a standardized way to:

  • Request additional capabilities from authenticators

  • Retrieve extra information during registration or authentication

  • Enable specific features like credential protection or large blob storage

  • Maintain backward compatibility with legacy systems (like U2F)

How Extensions Work

Extensions work in both directions:

  1. Extension Inputs - Sent from the Relying Party to the authenticator via the browser

  2. Extension Outputs - Returned from the authenticator to the Relying Party after processing

Common WebAuthn Extensions

Standard Extensions

The most commonly used WebAuthn extensions include:

Extension
Purpose
Use Case

appid

U2F backward compatibility

Allow existing U2F credentials to work with WebAuthn

credProps

Credential properties

Determine if a credential is discoverable (resident key)

largeBlob

Large blob storage

Store additional data (up to ~2KB) with credentials

credProtect

Credential protection

Require user verification for certain credentials

minPINLength

Minimum PIN length

Enforce PIN complexity requirements

hmacSecret

HMAC secret

Generate symmetric secrets for encryption

prf

Pseudo-Random Function

Generate cryptographic keys for encryption (new in 5.2.0)

uvm

User Verification Method

Information about how the user was verified

Registry

All standard extensions are listed in the IANA WebAuthn Extensions Registry:

https://www.iana.org/assignments/webauthn/webauthn.xhtml

Library Support

This library provides:

  • Core extension infrastructure - Ready to handle extension inputs and outputs

  • AppID extension - Built-in support for U2F backward compatibility

  • ⚠️ Custom extensions - You need to implement extension handlers for other extensions

Basic Usage Example

Here's how to add an extension input when creating credential options:

<?php

declare(strict_types=1);

use Webauthn\AuthenticationExtensions\AuthenticationExtension;
use Webauthn\AuthenticationExtensions\AuthenticationExtensions;
use Webauthn\PublicKeyCredentialCreationOptions;

// Create extension inputs
$extensions = AuthenticationExtensions::create([
    AuthenticationExtension::create('credProps', true)  // Request credential properties
]);

// Add extensions to creation options
$publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::create(
    rp: $rpEntity,
    user: $userEntity,
    challenge: random_bytes(32),
    extensions: $extensions
);

After registration, check the extension outputs:

// After successful registration
$extensionOutputs = $publicKeyCredential->response->getAuthenticatorData()->extensions;

// Check if credential is discoverable (resident key)
if (isset($extensionOutputs['credProps']['rk'])) {
    $isDiscoverable = $extensionOutputs['credProps']['rk'];
    echo $isDiscoverable ? 'Resident key created' : 'Non-resident key';
}

Practical Use Cases

1. U2F Migration (appid Extension)

Allow existing U2F credentials to work with your WebAuthn implementation:

$extensions = AuthenticationExtensions::create([
    AuthenticationExtension::create('appid', 'https://example.com')
]);

$publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::create(
    random_bytes(32),
    extensions: $extensions
);

2. Credential Properties (credProps Extension)

Determine if a credential supports resident keys (usernameless authentication):

$extensions = AuthenticationExtensions::create([
    AuthenticationExtension::create('credProps', true)
]);

// After registration, check:
$rk = $extensionOutputs['credProps']['rk'] ?? false;

3. Large Blob Storage (largeBlob Extension)

Store additional encrypted data with the credential:

// Write blob during registration
$extensions = AuthenticationExtensions::create([
    AuthenticationExtension::create('largeBlob', [
        'support' => 'required',
        'write' => base64_encode('encrypted user data')
    ])
]);

4. Pseudo-Random Function (prf Extension)

PRF extension support was added in version 5.2.0

The PRF (Pseudo-Random Function) extension allows you to generate cryptographic keys from authenticator secrets. This is particularly useful for encryption scenarios:

// Request PRF during authentication
$extensions = AuthenticationExtensions::create([
    AuthenticationExtension::create('prf', [
        'eval' => [
            'first' => base64_encode(random_bytes(32))
        ]
    ])
]);

$publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::create(
    random_bytes(32),
    extensions: $extensions
);

Implementation Considerations

Check Extension Support

Not all authenticators support all extensions. Always:

  1. Check extension outputs to see what was actually processed

  2. Have fallback behavior when extensions aren't supported

  3. Don't rely on extensions for critical security features

Custom Extension Handlers

For extensions beyond appid, you'll need to implement:

  1. Extension Output Checker - Validates extension outputs from authenticators

  2. Extension Input Builder - Constructs proper extension input objects

See the Pure PHP Extensions Guide or Symfony Bundle Extensions Guide for detailed implementation instructions.

When to Use Extensions

Use extensions when you need:

  • U2F compatibility - Migrate existing U2F credentials

  • Credential metadata - Know if credentials are resident keys

  • Additional storage - Store encrypted data with credentials

  • Enhanced protection - Enforce user verification policies

Avoid extensions if:

  • ❌ Basic registration/authentication is sufficient

  • ❌ You need universal compatibility (not all devices support extensions)

  • ❌ You're just getting started with WebAuthn

See Also

Last updated

Was this helpful?