python-fido2: talking to a security key from Python
Provides library functionality for FIDO 2.0, including communication with a device over USB.
At a glance
- What is it?
- The Yubico python-fido2 library is the reference implementation for speaking to a FIDO authenticator over USB, and it also carries the higher level client and server classes that most WebAuthn work ends up using. It is a low-level library with real hardware requirements, and its test suite will factory reset the device it runs against.
- Who is it for?
- Adopt python-fido2 if you are implementing a FIDO2 client or a WebAuthn relying party in Python and want a library written by the hardware vendor, with CTAP 1 and 2 support and a maintained migration path from version 1.x. Do not adopt it if you only need to use a security key for logins, since that is what a browser or an operating system already does.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two layers, and the low-level one is the point
This library provides library functionality for communicating with a FIDO device over USB as well as verifying attestation and assertion signatures. The description in the package manifest puts it slightly differently, calling it a FIDO2/WebAuthn library for implementing clients and servers.
The structure is two layers, and the README is clear about which one is which. The library aims to support the FIDO U2F and FIDO 2 protocols for communicating with a USB authenticator via the Client-to-Authenticator Protocol, CTAP 1 and 2. In addition to this low-level device access, classes defined in the fido2.client and fido2.server modules implement higher level operations which are useful when interfacing with an Authenticator, or when implementing WebAuthn support for a Relying Party.
That split is the useful thing to understand about the API. Most WebAuthn work does not need CTAP directly, because the browser does the ceremony, and the server side needs to verify an assertion rather than talk to a key. The fido2.server module is where signature verification lives, and fido2.client is where credential creation and assertion happen against a device you hold.
The library is BSD-2-clause licensed, with two exceptions that the README is explicit about. It contains source code from pyu2f, which is Apache 2.0, located in fido2/hid/, and it bundles the public suffix list, which is MPL 2.0, stored as fido2/public_suffix_list.dat. The COPYING file holds the BSD text, with COPYING.APLv2 and COPYING.MPLv2 alongside it, and the package manifest lists all three licence classifiers because all three are shipped.
It requires Python 3.10 or later, is tested on Windows, MacOS and Linux, and the manifest marks the development status as Production/Stable. Support for OpenBSD, FreeBSD and NetBSD is provided as-is and relies on community contributions.
Installing it, and what the platform needs from you
The install is a pip command, with an extra for NFC:
pip install fido2and to install the dependencies required for communication with NFC authenticators:
pip install fido2[pcsc]The permissions story is the part that catches people out, and the README handles each platform separately.
Under Windows 10, 1903 or later, access to FIDO devices is restricted and requires running as Administrator. The library can still be used when running as non-administrator, via the fido.client.WindowsClient class, and an example of this is included in the file examples/credential.py.
Under Linux you need to add a Udev rule to be able to access the FIDO device, or run as root. The rule the README suggests may contain the following:
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050"The vendor identifier in that rule is Yubico's, which is what makes it a Yubikey-specific example rather than a generic one. The README also notes there may be a package already available for your distribution that does this for you.
Under FreeBSD you will either need to run as root or add rules for your device to /etc/devd.conf, which can be automated by installing security/u2f-devd:
# pkg install u2f-devdThe dependency list is short. The project depends on Cryptography, with instructions at the cryptography site, and NFC support is optionally available via PC/SC using the pyscard library, which is an optional dependency in the manifest as the pcsc extra.
The test suite will factory reset your security key
This is the warning that belongs at the top of any article about this library, because it has a real chance of destroying a device.
While some tests can run on their own, most require a connected FIDO2 device to run. The warning says these tests are destructive, and will factory reset the device under test. As a safety precaution, the tests will only run on a device that is in a newly reset state, as far as the test runner can tell.
The safety precaution is an attempt to protect the user rather than the device, since the test suite exercises credential creation, which on a FIDO2 authenticator involves wiping the resident credentials and the configuration. The runner tries to detect whether the key is already in a state that would lose something, and refuses if it cannot tell.
The test command is:
uv run pytestThe development tooling around it is modern. The library uses uv for development, following the uv Getting Started guide to install and configure it, and pre-commit runs some scans on the code prior to committing. The dev dependency group lists pytest, sphinx with the read the docs theme and sphinx-autoapi, and the pytest configuration points at the tests directory. The lint configuration is ruff with the pycodestyle, pyflakes, isort and bandit rule sets selected, which matters for a library that parses untrusted responses from a device.
The examples directory is where the API is demonstrated, and it is well chosen. There is credential.py, which is the one the Windows section points at, get_info.py for reading device info, bio_enrollment.py, hmac_secret.py for the HMAC secret credential, resident_key.py for the resident key case, large_blobs.py for the large blob extension, and prf.py for the pseudo-random function extension. There are examples for the U2F over NFC path, multi_device.py, cred_blob.py, and a server directory.
Attestation verification, and the examples that show it
The attestation side of the library is the part a relying party developer needs, and the examples are organised around the attestation formats you will actually meet.
There is verify_attestation.py, which is the general case, and verify_attestation_mds3.py, which is the metadata statement version 3 format, and that is the format that a packagaged FIDO key uses. There is acred122u.py and acred122usam.py, which are the two security key models with different identifiers, and acred1252u.py for the other family of keys. The names encode the attestation format and the credential type, which is exactly the axis you need to check when your verification fails.
There is also sign_arkg.py, which is the signing example, and the server directory, which holds the relying party side of the examples. The fido2.server module is where those live, and the README describes its classes as the higher level operations useful when implementing WebAuthn support for a Relying Party.
The distinction between the two layers maps onto that split. The client module talks to a device you have in your hand, through CTAP, and the examples under the top of the examples directory are mostly client side. The server directory is the other half, verifying what a client sends you.
For a server implementer the FIDO2/WebAuthn guide from Yubico and the W3C WebAuthn specification are the two references the README links, along with the FIDO alliance specifications, and the API documentation at developers.yubico.com is where the class reference lives.
Version 2 is a breaking change, with a migration guide
The version line matters here, because the library made a major version change and the README calls it out at the top.
The note says version 2.0 is now released, and for help with migration from version 1.x it points at the migration guide in doc/Migration_1-2.adoc.
The consequence for a new user is straightforward, since there is nothing to migrate. The consequence for an existing user is that the 1.x to 2.x jump was a rewrite of the API surface rather than an additive release, and the guide exists because the class names and the shape of the calls changed.
The release history shows a project in maintenance mode rather than in active churn. python-fido2 2.2.1 came out on 2026-06-29, 2.2.0 on 2026-04-15, and 2.1.1 on 2026-01-19. The manifest carries 2.2.2-dev.0 as the development version, and the last push was on 2026-10-20, so the branch is active between releases.
That combination, a stable major version, a maintenance cadence of a release every couple of months, and a development version in the manifest, is the profile of a library that has settled on an API and is now carrying it.
The README also has a References section for the underlying specifications, which is the right pointer for anyone implementing the relying party side and needing to resolve a question the library does not answer.
Editorial conclusion
Adopt python-fido2 if you are implementing a FIDO2 client or a WebAuthn relying party in Python and want a library written by the hardware vendor, with CTAP 1 and 2 support and a maintained migration path from version 1.x. Do not adopt it if you only need to use a security key for logins, since that is what a browser or an operating system already does. Before you install, check the platform permissions, because on Windows 10 you need Administrator for direct access, on Linux you need a udev rule or root, and on FreeBSD a devd rule, and note that the tests are destructive and will factory reset the device they run against.
Frequently asked questions
How do I install python-fido2?
Run `pip install fido2` for USB authenticators, or `pip install fido2[pcsc]` to add the dependencies needed for NFC authenticators. The library needs Python 3.10 or later, and the manifest lists Cryptography as its only required dependency.
Do I need special permissions to use a security key on Linux?
Yes, you need a Udev rule to access the FIDO device, or you have to run as root. The README gives a sample rule matching hidraw devices with MODE 0664 and the plugdev group, filtered on the Yubico vendor id, and notes that your distribution may already ship a package that does this.
Are the python-fido2 tests safe to run on my security key?
No. The README warns that the tests are destructive and will factory reset the device under test. As a safety precaution they only run on a device that is in a newly reset state, as far as the test runner can tell, and most of them need a connected FIDO2 device.
How do I migrate python-fido2 from version 1.x?
Version 2.0 is released and the README points at a migration guide in doc/Migration_1-2.adoc for the changes from the 1.x API. The release history shows 2.2.1 from 2026-06-29, 2.2.0 from 2026-04-15 and 2.1.1 from 2026-01-19.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yubico-python-fido2)Was this useful?