### Install dependencies with uv sync Source: https://github.com/duo-labs/py_webauthn/blob/master/README.md Sets up a virtual environment and installs project dependencies using uv. ```sh $> uv sync ``` -------------------------------- ### Encode bytes to Base64URL example Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Example usage of bytes_to_base64url, showing the expected output for the input b"hello". ```python from webauthn.helpers import bytes_to_base64url assert bytes_to_base64url(b"hello") == "aGVsb28" ``` -------------------------------- ### Example usage of decode_credential_public_key Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/decode-credential-public-key.md Demonstrates how to decode a key and handle potential InvalidPublicKeyStructure exceptions, followed by type checking the result. ```python from webauthn.helpers import decode_credential_public_key from webauthn.helpers.decode_credential_public_key import DecodedEC2PublicKey from webauthn.helpers.exceptions import InvalidPublicKeyStructure try: decoded = decode_credential_public_key(encoded_cbor_key) except InvalidPublicKeyStructure as e: print(f"malformed key: {e}") if isinstance(decoded, DecodedEC2PublicKey): print(decoded.alg, decoded.crv, decoded.x.hex(), decoded.y.hex()) ``` -------------------------------- ### verify_android_key() usage example Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/registration-formats.md Example call to verify_android_key() with keyword arguments. Imports the function from webauthn.registration.formats.android_key and passes attestation data, client data, credential public key, and an empty root certificates list. ```python from webauthn.registration.formats.android_key import verify_android_key ok = verify_android_key( attestation_statement=att_stmt, attestation_object=attestation_object_bytes, client_data_json=client_data_bytes, credential_public_key=credential_public_key_bytes, pem_root_certs_bytes=[], ) ``` -------------------------------- ### Example usage of verify_packed Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/registration-formats.md Example showing how to import and call verify_packed with an attestation statement, attestation object, client data JSON, credential public key, and an empty list of root certificates. Returns True on success or raises InvalidRegistrationResponse on failure. ```python from webauthn.registration.formats.packed import verify_packed ok = verify_packed( attestation_statement=att_stmt, attestation_object=attestation_object_bytes, client_data_json=client_data_bytes, credential_public_key=credential_public_key_bytes, pem_root_certs_bytes=[], ) ``` -------------------------------- ### Using options_to_json() to serialize registration options Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Example of generating registration options and converting them to JSON for sending to the front end with `Content-Type: application/json`. ```python from webauthn import generate_registration_options, options_to_json options = generate_registration_options(rp_id="example.com", rp_name="Example Co", user_name="bob") # send to the front end as JSON json_body = options_to_json(options) ``` -------------------------------- ### Encode and decode CBOR example Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Example showing round-trip encoding and decoding of CBOR data using encode_cbor and parse_cbor. ```python from webauthn.helpers import encode_cbor, parse_cbor blob = encode_cbor({"fmt": "none"}) decoded = parse_cbor(blob) # {"fmt": "none"} ``` -------------------------------- ### Basic authentication verification example Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Basic usage of verify_authentication_response with default require_user_verification=False. The credential is the value returned from navigator.credentials.get(). After verification, update the stored sign count with authentication_verification.new_sign_count. ```python from webauthn import verify_authentication_response authentication_verification = verify_authentication_response( credential=credential_json, # from navigator.credentials.get() expected_challenge=challenge, expected_rp_id="example.com", expected_origin="https://example.com", credential_public_key=stored_public_key, credential_current_sign_count=stored_sign_count, ) # update stored sign count with authentication_verification.new_sign_count ``` -------------------------------- ### Using base64url_to_bytes() to decode a challenge Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Example usage of `base64url_to_bytes()` to decode a Base64URL-encoded challenge string into bytes. ```python from webauthn import base64url_to_bytes challenge = base64url_to_bytes("iPmAi1Pp1XL6oAgq3PWZtZPnZa1zFUDoGbaQ0_KvVG1lF2s3Rt_3o4uSzccy0tmcTIpTTT4BU1T-I4maavndjQ") ``` -------------------------------- ### Verify registration with multiple origins and error handling Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Example with error handling and multiple allowed origins. Pass a list of origins to `expected_origin` and set `require_user_verification=True`. On failure, `InvalidRegistrationResponse` is raised; inspect `e.__cause__` for malformed `clientDataJSON` or `attestationObject`. ```python from webauthn import verify_registration_response from webauthn.helpers.exceptions import InvalidRegistrationResponse try: verified = verify_registration_response( credential=credential_json, expected_challenge=challenge, expected_rp_id="example.com", expected_origin=["https://example.com", "https://example.co"], require_user_verification=True, ) # store verified.credential_id, verified.credential_public_key # and verified.sign_count in your database except InvalidRegistrationResponse as e: # see e.__cause__ when the failure was a malformed clientDataJSON # or attestationObject print(f"registration rejected: {e}") ``` -------------------------------- ### Convert decoded public key to cryptography object Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/decode-credential-public-key.md This example demonstrates decoding a credential public key from CBOR and converting it into a cryptography library key object. ```python from webauthn.helpers import decode_credential_public_key, decoded_public_key_to_cryptography from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey decoded = decode_credential_public_key(encoded_cbor_key) crypto_key = decoded_public_key_to_cryptography(decoded) assert isinstance(crypto_key, Ed25519PublicKey) # for an EdDSA/Ed25519 key ``` -------------------------------- ### aaguid_to_string() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Converts a 16-byte AAGUID into a GUID string format. ```APIDOC ## aaguid_to_string(val: bytes) -> str ### Description Converts 16 AAGUID bytes into a GUID string like `"00000000-0000-0000-0000-000000000000"`. ### Method Function ### Endpoint `webauthn.helpers.aaguid_to_string` ### Parameters - **val** (bytes) - Required - The 16-byte AAGUID to convert. ### Returns - **str** - The GUID string representation. ### Throws - **ValueError** - If `len(val) != 16`. ### Example ```python from webauthn.helpers import aaguid_to_string guid = aaguid_to_string(b'\x00' * 16) ``` ``` -------------------------------- ### Generate registration options with minimal parameters Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Generates registration options with minimal parameters. The resulting options.challenge and options.user.id each contain 64 random bytes. ```python from webauthn import generate_registration_options options = generate_registration_options( rp_id="example.com", rp_name="Example Co", user_name="bob", ) # options.challenge and options.user.id now hold 64 random bytes each ``` -------------------------------- ### Generate challenge and user handle with webauthn.helpers Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Imports and calls generate_challenge() and generate_user_handle() to obtain 64 random bytes each. The user_id value is intended to be passed as user_id to generate_registration_options() and stored for later authentication matching. ```python from webauthn.helpers import generate_challenge, generate_user_handle challenge = generate_challenge() # 64 random bytes user_id = generate_user_handle() # 64 random bytes, pass as user_id ``` -------------------------------- ### Lint with mypy Source: https://github.com/duo-labs/py_webauthn/blob/master/README.md Runs mypy for linting on the webauthn package. Expected output: 'Success: no issues found in 52 source files'. ```sh venv $> uv run -m mypy webauthn Success: no issues found in 52 source files ``` -------------------------------- ### Basic generate_authentication_options() call Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Basic usage with only rp_id. The challenge defaults to 64 random bytes. ```python from webauthn import generate_authentication_options options = generate_authentication_options(rp_id="example.com") # options.challenge holds 64 random bytes ``` -------------------------------- ### Format with black Source: https://github.com/duo-labs/py_webauthn/blob/master/README.md Formats the entire library using black with a line length of 99. Expected output: 'All done! ✨ 🍰 ✨' and '52 files left unchanged.' ```sh venv $> uv run -m black webauthn --line-length=99 All done! ✨ 🍰 ✨ 52 files left unchanged. ``` -------------------------------- ### Using apple_webauthn_root_ca with verify_registration_response Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/known-root-certs.md Shows how to import and use the `apple_webauthn_root_ca` constant when calling `verify_registration_response`. The Apple root is appended automatically for apple attestations; extra custom roots can still be supplied via `pem_root_certs_bytes_by_fmt`. ```python from webauthn import verify_registration_response from webauthn.helpers.structs import AttestationFormat from webauthn.helpers.known_root_certs import apple_webauthn_root_ca verified = verify_registration_response( credential=credential, expected_challenge=challenge, expected_rp_id="example.com", expected_origin="https://example.com", # the Apple root is appended automatically for apple attestations; # extra custom roots can still be supplied here pem_root_certs_bytes_by_fmt={AttestationFormat.APPLE: [apple_webauthn_root_ca]}, ) ``` -------------------------------- ### Generate registration options with advanced settings Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Generates registration options with advanced settings: direct attestation, platform authenticator attachment, required resident key, and a 12000 ms timeout. Setting resident_key to REQUIRED implies requireResidentKey: true. Invalid options raise a ValueError that is caught and printed. ```python from webauthn import generate_registration_options from webauthn.helpers.structs import ( AuthenticatorAttachment, AuthenticatorSelectionCriteria, AttestationConveyancePreference, ResidentKeyRequirement, ) try: options = generate_registration_options( rp_id="example.com", rp_name="Example Co", user_id=bytes([1, 2, 3, 4]), user_name="lee", attestation=AttestationConveyancePreference.DIRECT, authenticator_selection=AuthenticatorSelectionCriteria( authenticator_attachment=AuthenticatorAttachment.PLATFORM, resident_key=ResidentKeyRequirement.REQUIRED, ), timeout=12000, ) # residentKey: "required" in options implies requireResidentKey: true except ValueError as e: print(f"invalid options: {e}") ``` -------------------------------- ### generate_registration_options() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Documentation for the generate_registration_options function from the webauthn root package. ```APIDOC ## `generate_registration_options()` ### Description Generates options for a new WebAuthn credential registration ceremony. This is the first step in registering a new authenticator for a user. ### Method Function call ### Endpoint `webauthn.generate_registration_options` ### Parameters All parameters are keyword-only. #### Path Parameters None #### Query Parameters None #### Request Body - `rp_id` (str) - Required - A unique, constant identifier for this Relying Party. Must be a non-empty string or `ValueError` is raised. - `rp_name` (str) - Required - A user-friendly, readable name for the Relying Party. Must be non-empty or `ValueError` is raised. - `user_name` (str) - Required - A value that helps the user identify which account the credential is associated with (e.g. email address). Must be non-empty or `ValueError` is raised. - `user_id` (Optional[bytes]) - Optional - Random bytes identifying the user account. Defaults to 64 random bytes from `generate_user_handle()`. If provided, must be `bytes` or `ValueError` is raised. - `user_display_name` (Optional[str]) - Optional - User-friendly representation of the account. Defaults to the value of `user_name` when falsy. - `challenge` (Optional[bytes]) - Optional - Byte sequence for the authenticator to return. Defaults to 64 random bytes from `generate_challenge()`. - `timeout` (int) - Optional - Milliseconds the browser should give the user to choose an authenticator. A hint, may be ignored by the browser. Defaults to `60000`. - `attestation` (AttestationConveyancePreference) - Optional - Level of attestation to be provided by the authenticator. Defaults to `AttestationConveyancePreference.NONE`. - `authenticator_selection` (Optional[AuthenticatorSelectionCriteria]) - Optional - Requirements for authenticator characteristics. If supplied with `resident_key == ResidentKeyRequirement.REQUIRED`, `require_resident_key` is force-set to `True` per WebAuthn spec. - `exclude_credentials` (Optional[List[PublicKeyCredentialDescriptor]]) - Optional - Credentials already registered to the user, to prevent re-enrollment. Defaults to `[]`. - `supported_pub_key_algs` (Optional[List[COSEAlgorithmIdentifier]]) - Optional - Public-key algorithm IDs the RP restricts support to. Defaults to `default_supported_pub_key_algs`: `EDDSA` (-8), `ECDSA_SHA_256` (-7), `RSASSA_PKCS1_v1_5_SHA_256` (-257). - `hints` (Optional[List[PublicKeyCredentialHint]]) - Optional - Suggestions to the browser about authenticator type, ordered by decreasing preference. ### Request Example ```python from webauthn import generate_registration_options options = generate_registration_options( rp_id="example.com", rp_name="Example Corp", user_name="user@example.com", ) ``` ### Response #### Success Response - `PublicKeyCredentialCreationOptions` - Registration options ready for the browser. See [types.md](../types.md) for fields. Convert to JSON for transmission with `options_to_json()` or `webauthn.helpers.options_to_json_dict`. #### Response Example ```python # The returned object is a PublicKeyCredentialCreationOptions instance. # Convert to JSON using options_to_json() or options_to_json_dict. ``` ### Error Handling - `ValueError` - Raised if `rp_id`, `rp_name`, or `user_name` is an empty string; or if `user_id` is provided but not `bytes`. ``` -------------------------------- ### Import and use COSEAlgorithmIdentifier enum Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/cose.md Shows how to import COSEAlgorithmIdentifier and verify that enum members compare equal to their integer values. Also demonstrates building a list of supported algorithms using the enum members. ```python from webauthn.helpers.cose import COSEAlgorithmIdentifier assert COSEAlgorithmIdentifier.ECDSA_SHA_256 == -7 algorithms = [ COSEAlgorithmIdentifier.EDDSA, COSEAlgorithmIdentifier.ECDSA_SHA_256, COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_256, ] ``` -------------------------------- ### Options ↔ JSON Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Documentation for the options_to_json and options_to_json_dict helper functions. ```APIDOC ## `options_to_json(options: Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) -> str` ### Description Converts WebAuthn options to a JSON string. This is a convenience wrapper around `options_to_json_dict` and `json.dumps`. ### Parameters - `options` (Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) - Required - The options object to convert. ### Returns - `str` - JSON string representation of the options. ### Throws - `TypeError` if `options` is neither options type (raised by `options_to_json_dict`). ### Example ```python from webauthn.helpers import options_to_json json_str = options_to_json(options) ``` ``` ```APIDOC ## `options_to_json_dict(options: Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions], bytes_encoder: Callable[[bytes], Any] = bytes_to_base64url) -> Dict[str, Any]` ### Description Converts options into a plain `dict` ready for JSON encoding. Allows custom encoding of `bytes` values. ### Parameters - `options` (Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) - Required - The options object to convert. - `bytes_encoder` (Callable[[bytes], Any]) - Optional - Custom method to encode `bytes` values; defaults to `bytes_to_base64url`. ### Returns - `Dict[str, Any]` - Dictionary representation of the options. ### Notes - `id` fields are only included when present (`rp.id` is skipped when falsy). - `.value` is used for all enum members. - For registration options the result contains keys: `rp` `{name, id?}`, `user` `{id, name, displayName}`, `challenge`, `pubKeyCredParams` `[{type, alg}]`, and optionally `timeout`, `excludeCredentials`, `authenticatorSelection` `{authenticatorAttachment?, residentKey?, requireResidentKey?, userVerification?}`, `attestation`, `hints`. - For authentication options: `challenge`, optionally `timeout`, `rpId`, `allowCredentials`, `userVerification` (only when truthy). ### Example ```python from webauthn.helpers import options_to_json_dict def hex_encoder(val: bytes) -> str: return val.hex() d = options_to_json_dict(options, bytes_encoder=hex_encoder) ``` ``` -------------------------------- ### Library default constants for supported public key algorithms Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/configuration.md Defines the default supported public key algorithms and generates corresponding credential parameters. These constants are importable from webauthn.registration.generate_registration_options. ```python default_supported_pub_key_algs = [ COSEAlgorithmIdentifier.EDDSA, # -8 COSEAlgorithmIdentifier.ECDSA_SHA_256, # -7 COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_256, # -257 ] default_supported_pub_key_params = _generate_pub_key_cred_params(default_supported_pub_key_algs) ``` -------------------------------- ### Run all tests with unittest Source: https://github.com/duo-labs/py_webauthn/blob/master/README.md Runs all tests in the tests/ directory using Python's unittest module. ```sh venv $> uv run -m unittest ``` -------------------------------- ### generate_authentication_options() with custom parameters Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Advanced usage with custom timeout, allow_credentials, and user_verification. Requires importing PublicKeyCredentialDescriptor and UserVerificationRequirement. ```python from webauthn import generate_authentication_options from webauthn.helpers.structs import PublicKeyCredentialDescriptor, UserVerificationRequirement options = generate_authentication_options( rp_id="example.com", timeout=12000, allow_credentials=[PublicKeyCredentialDescriptor(id=stored_credential_id)], user_verification=UserVerificationRequirement.REQUIRED, ) ``` -------------------------------- ### verify_authentication_response() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Verifies a WebAuthn authentication response. Takes the credential from navigator.credentials.get(), expected challenge, RP ID, origin, stored public key, and current sign count, and returns a VerifiedAuthentication object. Optionally requires user verification. ```APIDOC ## verify_authentication_response() ### Description Verifies a WebAuthn authentication response. It validates the credential against the expected challenge, RP ID, origin, and stored public key, and returns a VerifiedAuthentication object with the new sign count and device flags. ### Method Function call ### Signature ```python def verify_authentication_response( *, credential: Union[str, Dict[str, Any], AuthenticationCredential], expected_challenge: bytes, expected_rp_id: str, expected_origin: Union[str, List[str]], credential_public_key: bytes, credential_current_sign_count: int, require_user_verification: bool = False, ) -> VerifiedAuthentication: ``` ### Parameters - **credential** (Union[str, Dict[str, Any], AuthenticationCredential]) - Required - Value returned from navigator.credentials.get(). Stringified JSON and dicts are parsed via parse_authentication_credential_json(). - **expected_challenge** (bytes) - Required - The challenge passed to the authenticator in the preceding authentication options. - **expected_rp_id** (str) - Required - RP's unique identifier from the preceding authentication options. - **expected_origin** (Union[str, List[str]]) - Required - Domain with HTTP protocol on which the authentication ceremony should have occurred. - **credential_public_key** (bytes) - Required - Public key for the credential's ID provided in a preceding registration ceremony. - **credential_current_sign_count** (int) - Required - Current known number of times the authenticator was used. - **require_user_verification** (bool) - Optional, default False - Whether to require the authenticator verified the user. ### Return Type VerifiedAuthentication (dataclass at webauthn/authentication/verify_authentication_response.py:29): | Field | Type | Description | |-------|------|-------------| | credential_id | bytes | The credential's raw_id | | new_sign_count | int | The sign count reported in this response | | credential_device_type | CredentialDeviceType | SINGLE_DEVICE or MULTI_DEVICE from backup flags | | credential_backed_up | bool | Backup state flag | | user_verified | bool | Whether the user was verified by the authenticator | ### Throws - **webauthn.helpers.exceptions.InvalidAuthenticationResponse** - Any verification failure — see errors.md. Replay protection: if either the response sign count or credential_current_sign_count is greater than 0, the response sign count must be strictly greater than the current count. The signature is verified over authenticatorData || SHA-256(clientDataJSON) using the decoded credential public key converted via decoded_public_key_to_cryptography(). ### Examples ```python from webauthn import verify_authentication_response authentication_verification = verify_authentication_response( credential=credential_json, # from navigator.credentials.get() expected_challenge=challenge, expected_rp_id="example.com", expected_origin="https://example.com", credential_public_key=stored_public_key, credential_current_sign_count=stored_sign_count, ) # update stored sign count with authentication_verification.new_sign_count ``` ```python from webauthn import verify_authentication_response from webauthn.helpers.exceptions import InvalidAuthenticationResponse try: verification = verify_authentication_response( credential=credential_json, expected_challenge=challenge, expected_rp_id="example.com", expected_origin="https://example.com", credential_public_key=stored_public_key, credential_current_sign_count=stored_sign_count, require_user_verification=True, ) except ( InvalidAuthenticationResponse, # decode_credential_public_key raises subclasses of WebAuthnException too ) as e: print(f"authentication rejected: {e}") ``` ``` -------------------------------- ### WebAuthn input and option dataclasses in webauthn/helpers/structs.py Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/types.md Defines the WebAuthn input and option dataclasses used by py_webauthn, including TokenBinding, PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity, PublicKeyCredentialParameters, PublicKeyCredentialDescriptor, AuthenticatorSelectionCriteria, CollectedClientData, PublicKeyCredentialCreationOptions, AuthenticatorAttestationResponse, RegistrationCredential, AttestationStatement, AuthenticatorDataFlags, AttestedCredentialData, AuthenticatorData, AttestationObject, PublicKeyCredentialRequestOptions, AuthenticatorAssertionResponse, and AuthenticationCredential. These classes mirror the WebAuthn specification structures and are used to construct registration and authentication options. ```python @dataclass class TokenBinding: # line 181 status: TokenBindingStatus id: Optional[str] = None @dataclass class PublicKeyCredentialRpEntity: # line 191 name: str id: Optional[str] = None @dataclass class PublicKeyCredentialUserEntity: # line 206 id: bytes name: str display_name: str @dataclass class PublicKeyCredentialParameters: # line 223 type: Literal["public-key"] alg: COSEAlgorithmIdentifier @dataclass class PublicKeyCredentialDescriptor: # line 238 id: bytes type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY transports: Optional[List[AuthenticatorTransport]] = None @dataclass class AuthenticatorSelectionCriteria: # line 255 authenticator_attachment: Optional[AuthenticatorAttachment] = None resident_key: Optional[ResidentKeyRequirement] = None require_resident_key: Optional[bool] = False user_verification: Optional[UserVerificationRequirement] = ( UserVerificationRequirement.PREFERRED ) @dataclass class CollectedClientData: # line 276 type: ClientDataType challenge: bytes origin: str cross_origin: Optional[bool] = None token_binding: Optional[TokenBinding] = None @dataclass class PublicKeyCredentialCreationOptions: # line 304 rp: PublicKeyCredentialRpEntity user: PublicKeyCredentialUserEntity challenge: bytes pub_key_cred_params: List[PublicKeyCredentialParameters] timeout: Optional[int] = None exclude_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None authenticator_selection: Optional[AuthenticatorSelectionCriteria] = None hints: Optional[List[PublicKeyCredentialHint]] = None attestation: AttestationConveyancePreference = AttestationConveyancePreference.NONE @dataclass class AuthenticatorAttestationResponse: # line 333 client_data_json: bytes attestation_object: bytes transports: Optional[List[AuthenticatorTransport]] = None @dataclass class RegistrationCredential: # line 351 id: str raw_id: bytes response: AuthenticatorAttestationResponse authenticator_attachment: Optional[AuthenticatorAttachment] = None type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY @dataclass class AttestationStatement: # line 371 sig: Optional[bytes] = None x5c: Optional[List[bytes]] = None response: Optional[bytes] = None alg: Optional[COSEAlgorithmIdentifier] = None ver: Optional[str] = None cert_info: Optional[bytes] = None pub_area: Optional[bytes] = None @dataclass class AuthenticatorDataFlags: # line 391 up: bool uv: bool be: bool bs: bool at: bool ed: bool @dataclass class AttestedCredentialData: # line 414 aaguid: bytes credential_id: bytes credential_public_key: bytes @dataclass class AuthenticatorData: # line 431 rp_id_hash: bytes flags: AuthenticatorDataFlags sign_count: int attested_credential_data: Optional[AttestedCredentialData] = None extensions: Optional[bytes] = None @dataclass class AttestationObject: # line 453 fmt: AttestationFormat auth_data: AuthenticatorData att_stmt: AttestationStatement = field(default_factory=AttestationStatement) @dataclass class PublicKeyCredentialRequestOptions: # line 477 challenge: bytes timeout: Optional[int] = None rp_id: Optional[str] = None allow_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None user_verification: Optional[UserVerificationRequirement] = ( UserVerificationRequirement.PREFERRED ) @dataclass class AuthenticatorAssertionResponse: # line 500 client_data_json: bytes authenticator_data: bytes signature: bytes user_handle: Optional[bytes] = None @dataclass class AuthenticationCredential: # line 519 id: str raw_id: bytes response: AuthenticatorAssertionResponse authenticator_attachment: Optional[AuthenticatorAttachment] = None type: Literal[PublicKeyCredentialType.PUBLIC_KEY] = PublicKeyCredentialType.PUBLIC_KEY ``` -------------------------------- ### verify_apple() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/registration-formats.md Verifies an 'apple' attestation statement as per WebAuthn §8.6. It requires an x5c certificate chain, validates the chain with the Apple WebAuthn root CA, checks the nonce in the certificate extension, and ensures the credential public key matches the certificate's subject public key. ```APIDOC ## verify_apple() ### Description Verifies an "apple" attestation statement (WebAuthn §8.6). ### Signature ```python def verify_apple( *, attestation_statement: AttestationStatement, attestation_object: bytes, client_data_json: bytes, credential_public_key: bytes, pem_root_certs_bytes: List[bytes], ) -> bool: ``` ### Parameters - **attestation_statement** (AttestationStatement) - Required - The attestation statement to verify. - **attestation_object** (bytes) - Required - The attestation object bytes. - **client_data_json** (bytes) - Required - The client data JSON bytes. - **credential_public_key** (bytes) - Required - The credential public key bytes. - **pem_root_certs_bytes** (List[bytes]) - Required - List of PEM root certificates. The list is mutated in place by appending the Apple WebAuthn root CA. ### Verification Steps 1. Requires `x5c` in the attestation statement. 2. Chain validation with `apple_webauthn_root_ca` appended to provided roots. 3. Computes `nonce = SHA-256(authenticatorData || SHA-256(clientDataJSON))` and requires the certificate extension OID `1.2.840.113635.100.8.2` to contain that nonce (first 6 ASN.1 OCTET STRING structure bytes are trimmed). 4. Requires the certificate's Subject Public Key (DER SPKI) to equal the credential public key's DER SPKI. ### Returns - **bool** - True if the attestation statement is valid. ``` -------------------------------- ### Use options_to_json_dict with custom bytes_encoder Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Shows how to call options_to_json_dict with a custom bytes_encoder that converts bytes to hex strings instead of the default base64url encoding. ```python from webauthn.helpers import options_to_json_dict def hex_encoder(val: bytes) -> str: return val.hex() d = options_to_json_dict(options, bytes_encoder=hex_encoder) ``` -------------------------------- ### verify_android_key() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/registration-formats.md Verifies an 'android-key' attestation statement (WebAuthn §8.2). It requires sig, alg, and x5c, validates the certificate chain against a known Google root, verifies the signature over authenticatorData and clientDataHash, and checks the KeyDescription extension. ```APIDOC ## verify_android_key() ### Description Verifies an "android-key" attestation statement (WebAuthn §8.2). It requires `sig`, `alg`, `x5c`, validates the certificate chain, and checks the KeyDescription extension. ### Method Function call ### Endpoint `webauthn.registration.formats.android_key.verify_android_key` ### Parameters #### Keyword Arguments - **attestation_statement** (AttestationStatement) - Required - The attestation statement object. - **attestation_object** (bytes) - Required - The attestation object bytes. - **client_data_json** (bytes) - Required - The client data JSON bytes. - **credential_public_key** (bytes) - Required - The credential public key bytes. - **pem_root_certs_bytes** (List[bytes]) - Required - List of PEM root certificates. ### Request Example ```python from webauthn.registration.formats.android_key import verify_android_key ok = verify_android_key( attestation_statement=att_stmt, attestation_object=attestation_object_bytes, client_data_json=client_data_bytes, credential_public_key=credential_public_key_bytes, pem_root_certs_bytes=[], ) ``` ### Response #### Success Response - Returns `True` if verification succeeds. #### Error Handling Raises `InvalidRegistrationResponse` tagged `(Android Key)` on any failure. ``` -------------------------------- ### parse_registration_options_json Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Parses JSON-form registration options into PublicKeyCredentialCreationOptions. ```APIDOC ## parse_registration_options_json ### Description Parses JSON-form registration options back into `PublicKeyCredentialCreationOptions`. Useful for round-tripping `generate_registration_options()` output persisted as JSON (e.g. Redis). Required: `rp.name`, `rp.id` (nullable), `user.id/name/displayName`, `attestation`, `challenge`, `pubKeyCredParams`. Optional: `authenticatorSelection`, `excludeCredentials`, `timeout`, `hints`. ### Signature ```python def parse_registration_options_json(json_val: Union[str, Dict[str, Any]]) -> PublicKeyCredentialCreationOptions ``` ### Parameters - **json_val** (Union[str, Dict[str, Any]]) - Required - The registration options JSON string or dict to parse. ### Returns - **PublicKeyCredentialCreationOptions** - The parsed registration options object. ### Throws - `helpers.exceptions.InvalidJSONStructure` - On malformed values (e.g. invalid enum values, fails e.g. `COSEAlgorithmIdentifier` lookup, non-bool `requireResidentKey`). - `helpers.exceptions.InvalidRegistrationOptions` - With `__cause__` if construction fails. ``` -------------------------------- ### Authentication verification with error handling Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Authentication verification with require_user_verification=True and error handling. Catches InvalidAuthenticationResponse and other WebAuthnException subclasses (e.g., from decode_credential_public_key) and prints a rejection message. ```python from webauthn import verify_authentication_response from webauthn.helpers.exceptions import InvalidAuthenticationResponse try: verification = verify_authentication_response( credential=credential_json, expected_challenge=challenge, expected_rp_id="example.com", expected_origin="https://example.com", credential_public_key=stored_public_key, credential_current_sign_count=stored_sign_count, require_user_verification=True, ) except ( InvalidAuthenticationResponse, # decode_credential_public_key raises subclasses of WebAuthnException too ) as e: print(f"authentication rejected: {e}") ``` -------------------------------- ### PublicKeyCredentialCreationOptions dataclass Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers-structs.md Return type of `generate_registration_options()`. Acceptable by `options_to_json`, `options_to_json_dict`, and `parse_registration_options_json`. ```python @dataclass class PublicKeyCredentialCreationOptions: rp: PublicKeyCredentialRpEntity user: PublicKeyCredentialUserEntity challenge: bytes pub_key_cred_params: List[PublicKeyCredentialParameters] timeout: Optional[int] = None exclude_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None authenticator_selection: Optional[AuthenticatorSelectionCriteria] = None hints: Optional[List[PublicKeyCredentialHint]] = None attestation: AttestationConveyancePreference = AttestationConveyancePreference.NONE ``` -------------------------------- ### generate_registration_options Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Generates WebAuthn registration options. This function is used to create options for the WebAuthn registration ceremony, including challenge and user ID generation. ```APIDOC ## generate_registration_options ### Description Generates WebAuthn registration options. This function is used to create options for the WebAuthn registration ceremony, including challenge and user ID generation. ### Method Function call ### Endpoint webauthn.generate_registration_options ### Parameters #### Function Parameters - **rp_id** (string) - Required - The relying party identifier (e.g., "example.com"). - **rp_name** (string) - Required - The relying party display name (e.g., "Example Co"). - **user_name** (string) - Required - The user's display name (e.g., "bob"). - **user_id** (bytes) - Optional - The user's unique identifier. If not provided, 64 random bytes are generated. - **attestation** (AttestationConveyancePreference) - Optional - The attestation conveyance preference (e.g., DIRECT). - **authenticator_selection** (AuthenticatorSelectionCriteria) - Optional - Criteria for authenticator selection, including authenticator_attachment and resident_key. - **timeout** (int) - Optional - Timeout in milliseconds (e.g., 12000). ### Request Example ```python from webauthn import generate_registration_options options = generate_registration_options( rp_id="example.com", rp_name="Example Co", user_name="bob", ) ``` ### Response #### Success Response - **options** (PublicKeyCredentialCreationOptions) - The generated registration options, including challenge and user ID. #### Response Example ```python # options.challenge and options.user.id now hold 64 random bytes each ``` ### Notes - If resident_key is set to REQUIRED, then requireResidentKey is implied to be true. - Raises ValueError for invalid options. ``` -------------------------------- ### generate_authentication_options() signature Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Function signature for generating authentication options. Requires rp_id; other parameters have defaults. Throws ValueError if rp_id is empty. ```python def generate_authentication_options( *, rp_id: str, challenge: Optional[bytes] = None, timeout: int = 60000, allow_credentials: Optional[List[PublicKeyCredentialDescriptor]] = None, user_verification: UserVerificationRequirement = UserVerificationRequirement.PREFERRED, ) -> PublicKeyCredentialRequestOptions: ``` -------------------------------- ### PublicKeyCredentialHint Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers-structs.md Enum defining categories of authenticators for registration hints. ```APIDOC ## Enum: PublicKeyCredentialHint ### Description Categories of authenticators passed to browsers during registration (less strict than `authenticatorAttachment`). ### Members - `SECURITY_KEY` = `"security-key"` - `CLIENT_DEVICE` = `"client-device"` - `HYBRID` = `"hybrid"` ### Usage Used by `PublicKeyCredentialCreationOptions.hints`, `generate_registration_options.hints`. ``` -------------------------------- ### PublicKeyCredentialHint enum Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/types.md Enum for public key credential hints. Accepted/returned by generate_registration_options(hints) and PublicKeyCredentialCreationOptions.hints. ```python class PublicKeyCredentialHint(str, Enum): SECURITY_KEY = "security-key" CLIENT_DEVICE = "client-device" HYBRID = "hybrid" ``` -------------------------------- ### decoded_public_key_to_cryptography(public_key: Union[DecodedOKPPublicKey, DecodedEC2PublicKey, DecodedRSAPublicKey, DecodedMLDSAPublicKey]) -> Union[Ed25519PublicKey, EllipticCurvePublicKey, RSAPublicKey, MLDSA44PublicKey, MLDSA65PublicKey, MLDSA87PublicKey] Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/decode-credential-public-key.md Converts raw decoded public key parameters into cryptography library key objects. Supports EC2, RSA, OKP (EdDSA/Ed25519 only), and ML-DSA keys. ```APIDOC ## `decoded_public_key_to_cryptography(public_key: Union[DecodedOKPPublicKey, DecodedEC2PublicKey, DecodedRSAPublicKey, DecodedMLDSAPublicKey]) -> Union[Ed25519PublicKey, EllipticCurvePublicKey, RSAPublicKey, MLDSA44PublicKey, MLDSA65PublicKey, MLDSA87PublicKey]` ### Description Converts raw decoded public key parameters into `cryptography` library key objects. Supports EC2, RSA, OKP (EdDSA/Ed25519 only), and ML-DSA keys. ### Method Function ### Endpoint `webauthn/helpers/decoded_public_key_to_cryptography.py:27` ### Parameters #### Input - **public_key** (DecodedOKPPublicKey | DecodedEC2PublicKey | DecodedRSAPublicKey | DecodedMLDSAPublicKey) - Required - The decoded public key to convert. ### Conversion Details - `DecodedEC2PublicKey` → `EllipticCurvePublicNumbers(x, y, curve).public_key()` - curve from `get_ec2_curve(crv)`. - `DecodedRSAPublicKey` → `RSAPublicNumbers(e, n).public_key()`. - `DecodedOKPPublicKey` → only supported when `alg == COSEAlgorithmIdentifier.EDDSA` and `crv == COSECRV.ED25519`; otherwise `UnsupportedPublicKey`. Constructs `Ed25519PublicKey.from_public_bytes(x)`. - `DecodedMLDSAPublicKey` → `MLDSA44PublicKey` / `MLDSA65PublicKey` / `MLDSA87PublicKey` per `alg`; anything else or any decoding error raises `UnsupportedPublicKey` (errors chained in `__cause__`). ### Return Value | For input | Output key type | |-----------|-----------------| | `DecodedEC2PublicKey` | `EllipticCurvePublicKey` | | `DecodedRSAPublicKey` | `RSAPublicKey` | | `DecodedOKPPublicKey` | `Ed25519PublicKey` | | `DecodedMLDSAPublicKey` | `MLDSA44PublicKey` \| `MLDSA65PublicKey` \| `MLDSA87PublicKey` | ### Throws | Error | Condition | |-------|-----------| | `helpers.exceptions.UnsupportedPublicKey` | OKP with non-EdDSA alg / non-Ed25519 crv; unknown decoded key type; ML-DSA decode error | ### Example ```python from webauthn.helpers import decode_credential_public_key, decoded_public_key_to_cryptography from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey decoded = decode_credential_public_key(encoded_cbor_key) crypto_key = decoded_public_key_to_cryptography(decoded) assert isinstance(crypto_key, Ed25519PublicKey) # for an EdDSA/Ed25519 key ``` ``` -------------------------------- ### options_to_json(options: Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) -> str Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Converts registration or authentication options into a JSON string suitable for Content-Type: application/json. Bytes are Base64URL-encoded by default. ```APIDOC ## options_to_json(options: Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) -> str ### Description Converts registration or authentication options into a JSON string (via `options_to_json_dict()`) suitable for `Content-Type: application/json`. Bytes are Base64URL-encoded by default. ### Method Function ### Signature ```python def options_to_json( options: Union[ PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions, ], ) -> str: ``` ### Parameters - **options** (Union[PublicKeyCredentialCreationOptions, PublicKeyCredentialRequestOptions]) - Required - The registration or authentication options to convert. ### Returns - **str** - The JSON string representation of the options. ### Example ```python from webauthn import generate_registration_options, options_to_json options = generate_registration_options(rp_id="example.com", rp_name="Example Co", user_name="bob") # send to the front end as JSON json_body = options_to_json(options) ``` ``` -------------------------------- ### Encode bytes to Base64URL with bytes_to_base64url Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/helpers.md Function signature for Base64URL-encoding bytes. The implementation uses urlsafe_b64encode(...).decode("utf-8").rstrip("="). ```python def bytes_to_base64url(val: bytes) -> str: ``` -------------------------------- ### Module-Level Constants Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Constants defined in webauthn/registration/generate_registration_options.py for default supported public key algorithms and parameters. ```APIDOC ## Module-Level Constants ### Description Constants defined in webauthn/registration/generate_registration_options.py for default supported public key algorithms and parameters. ### Constants - **default_supported_pub_key_algs** (list) - Default supported public key algorithms: [COSEAlgorithmIdentifier.EDDSA, COSEAlgorithmIdentifier.ECDSA_SHA_256, COSEAlgorithmIdentifier.RSASSA_PKCS1_v1_5_SHA_256] - **default_supported_pub_key_params** (list) - List of PublicKeyCredentialParameters derived from the above via _generate_pub_key_cred_params(). ``` -------------------------------- ### generate_authentication_options() Source: https://github.com/duo-labs/py_webauthn/blob/master/_autodocs/api-reference/webauthn.md Generates authentication options for WebAuthn. Returns a PublicKeyCredentialRequestOptions object. Throws ValueError if rp_id is empty. ```APIDOC ## generate_authentication_options() ### Description Generates authentication options for WebAuthn authentication. Returns a PublicKeyCredentialRequestOptions object. ### Method Function call ### Endpoint webauthn.authentication.generate_authentication_options.generate_authentication_options ### Parameters #### Function Parameters - **rp_id** (str) - Required - The Relying Party's unique identifier as specified in attestations. Must be non-empty or ValueError. - **challenge** (Optional[bytes]) - Optional - Byte sequence for the authenticator to return. Defaults to 64 random bytes from generate_challenge(). - **timeout** (int) - Optional - Milliseconds the browser should give the user to choose an authenticator. A hint. Default: 60000. - **allow_credentials** (Optional[List[PublicKeyCredentialDescriptor]]) - Optional - Credentials registered to the user. Defaults to []. - **user_verification** (UserVerificationRequirement) - Optional - RP's preference for enforcement of the "user verified" flag. Default: UserVerificationRequirement.PREFERRED. ### Return Type PublicKeyCredentialRequestOptions ### Throws - **ValueError** - If rp_id is an empty string. ### Examples ```python from webauthn import generate_authentication_options options = generate_authentication_options(rp_id="example.com") # options.challenge holds 64 random bytes ``` ```python from webauthn import generate_authentication_options from webauthn.helpers.structs import PublicKeyCredentialDescriptor, UserVerificationRequirement options = generate_authentication_options( rp_id="example.com", timeout=12000, allow_credentials=[PublicKeyCredentialDescriptor(id=stored_credential_id)], user_verification=UserVerificationRequirement.REQUIRED, ) ``` ```