Skip to main content

Python WebAuthn Relying Party library

Project description

PyWARP is an implementation of the W3C WebAuthn standard’s Relying Party component in Python. The WebAuthn standard is used to provide advanced authentication security for two-factor, multifactor and passwordless authentication models through the use of dedicated hardware security keys and biometric devices such as Yubico YubiKey, Google Titan, TPM, and Touch ID.

Compared to more basic two-factor standards like HOTP (RFC 4226) and TOTP (RFC 6238), the FIDO U2F profile of WebAuthn uses asymmetric cryptography to avoid using a shared secret design, which strengthens your authentication solution against server-side attacks. Hardware U2F also sequesters the client secret in a dedicated single-purpose device, which strengthens your clients against client-side attacks. And by automating scoping of credentials to relying party IDs (application origin/domain names), U2F adds protection against phishing attacks.

PyWARP implements the Relying Party component of WebAuthn. A Relying Party is a server-side application that instructs the browser (user agent) to use WebAuthn APIs to authenticate its users.

To see an example of PyWARP in action, check the examples directory. Two demos are included: an AWS Chalice app and a Flask app.

In addition to reading the WebAuthn standard, we recommend that implementers read the OWASP Authentication Cheat Sheet and NIST SP 800-63-3: Digital Authentication Guideline for a high level overview of authentication best practices.

Installation

pip install pywarp

PyWARP depends on cryptography, which in turn requires OpenSSL and CFFI.

Synopsis

from pywarp import RelyingPartyManager, Credential
from pywarp.backends import DynamoBackend  # This is an example. See "storage backends" below for other databases.

rp_id = "myapp.example.com"  # This must match the origin domain of your app, as seen by the browser.
rp = RelyingPartyManager("PyWARP demo", rp_id=rp_id, credential_storage_backend=DynamoBackend())

# Get options for navigator.credentials.create() - pass these to your frontend when registering a user
rp.get_registration_options(email=str)

# Run the protocol in https://www.w3.org/TR/webauthn/#registering-a-new-credential,
# then call the credential storage backend to store the credential public key.
rp.register(attestation_object=bytes, client_data_json=bytes, email=bytes)

# Get options for navigator.credentials.get() - pass these to your frontend when logging in a user
rp.get_authentication_options(email=str)

# Run the protocol in https://www.w3.org/TR/webauthn/#verifying-assertion,
# calling the credential storage backend to retrieve the credential public key.
# If no exception is raised, proceed with user login.
rp.verify(authenticator_data=bytes, client_data_json=bytes, signature=bytes, user_handle=bytes, raw_id=bytes,
          email=bytes)

See examples/chalice/app.py and examples/chalice/chalicelib/index.html (frontend) for a complete example.

Storage backends

Your application is presumably using an application server like uWSGI, a database backend like MySQL, PostgreSQL or MongoDB, and maybe a framework like Flask or Django to tie them together. PyWARP makes no assumptions about your database, schema, or model. Instead, it provides an abstract class (pywarp.backends.CredentialStorageBackend) representing an interface for storing and retrieving WebAuthn credential data for your users.

To deploy PyWARP, declare a subclass of CredentialStorageBackend. In your subclass, implement bindings to your database, then pass an instance of your subclass to pywarp.RelyingPartyManager(credential_storage_backend=...):

class CredentialStorageBackend:
    def __init__(self):
        self.database_client = ...

    def get_credential_by_email(self, email):
        user_record = self.database_client.get(email)
        return Credential(credential_id=user_record["cred_id"],
                          credential_public_key=user_record["cred_pub_key"])

    def save_credential_for_user(self, email, credential):
        self.database_client.update(email, {"cred_id": credential.credential_id,
                                            "cred_pub_key": bytes(credential.public_key)})

    def save_challenge_for_user(self, email, challenge, type):
        self.database_client.update(email, {type + "challenge": challenge})

    def get_challenge_for_user(self, email, type):
        user_record = self.database_client.get(email)
        return user_record[type + "challenge"]

Example: Chalice app

The Chalice app example (in the examples/chalice directory) can be deployed as an AWS Lambda application when used with conventional AWS account credentials (configured via aws configure in the AWS CLI. This example uses DynamoDB as a storage backend.

See the API documentation for more.

Authors

  • Andrey Kislyuk

Bugs

Please report bugs, issues, feature requests, etc. on GitHub.

License

Licensed under the terms of the Apache License, Version 2.0.

https://img.shields.io/travis/pyauth/pywarp.svg https://codecov.io/github/pyauth/pywarp/coverage.svg?branch=master https://img.shields.io/pypi/v/pywarp.svg https://img.shields.io/pypi/l/pywarp.svg https://readthedocs.org/projects/pywarp/badge/?version=latest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pywarp-0.0.4.tar.gz (11.7 kB view details)

Uploaded Source

Built Distribution

pywarp-0.0.4-py2.py3-none-any.whl (10.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file pywarp-0.0.4.tar.gz.

File metadata

  • Download URL: pywarp-0.0.4.tar.gz
  • Upload date:
  • Size: 11.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/2.7

File hashes

Hashes for pywarp-0.0.4.tar.gz
Algorithm Hash digest
SHA256 bda9312cdb3fa2d19d10cead6764a716f803ee77eb2cf15fc1f08c8c3902ca05
MD5 313a79a620491d0b57e56625c8a1786c
BLAKE2b-256 962dfbb95b3c0c7e26a6df730555736c9f7c08c86d3d069d48ff374bcd155e7f

See more details on using hashes here.

File details

Details for the file pywarp-0.0.4-py2.py3-none-any.whl.

File metadata

  • Download URL: pywarp-0.0.4-py2.py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: Python-urllib/2.7

File hashes

Hashes for pywarp-0.0.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 da5bc50307e1cd9b055cde1c3a1f67a42ff3e61854b0c1792ddbcfd7d8b11479
MD5 5b4e76b3a402ee453bed6ae2725bbec7
BLAKE2b-256 08df25c2143a0566f0be50c5caf910d8cef52c951eefa7e7f0c86e84d95e3c11

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page