CLI tool
Yubico/libfido2 avatar
Yubico/libfido2

libfido2 gives programs direct access to FIDO2 tokens

Provides library functionality for FIDO2, including communication with a device over USB or NFC.

741 stars192 forksCNOASSERTION

At a glance

What is it?
libfido2 is a C library plus command line tools for talking to FIDO devices over USB or NFC and for checking attestation and assertion signatures. It is the layer underneath security keys, not the layer end users ever touch.
Who is it for?
Adopt libfido2 if you are writing the code that a browser or a server would otherwise duplicate, and you can live with a library that needs a udev rule, a C toolchain and a maintained OpenSSL. Do not adopt it for a consumer facing product, for NFC on platforms where the netlink path is unavailable, or for anything that needs release tarballs fetched from a static page.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem libfido2 solves is talking to the key, not to the service

Almost every project that depends on a FIDO2 authenticator eventually hits the same wall: the token speaks a USB or NFC protocol, and something has to translate that protocol into structured results. libfido2 is that translation layer. It describes itself as providing library functionality and command line tools to communicate with a FIDO device over USB or NFC, and to verify attestation and assertion signatures. The audience is therefore developers, not end users. A password manager, a desktop login screen, or a server side relying party all need different pieces, but they all need to enumerate devices, talk CTAP over the right transport, and check that the crypto blobs are well formed. The project documentation points new users to the `examples/` directory for usage rather than describing a workflow in prose, which is a tell that this is a library with sample programs rather than a finished application. It is also a Yubico project, so the surrounding context is security keys and the FIDO2 ecosystem, but the code itself does not require a Yubikey. Any device implementing CTAP 1 or CTAP 2 is in scope.

CTAP 1 and CTAP 2 sit behind one device abstraction

The protocol support is what makes the library interesting to implementers. Yubico's own description states plainly that libfido2 supports the FIDO U2F (CTAP 1) and FIDO2 (CTAP 2) protocols. Keeping both alive means a program can drive a legacy U2F key and a modern FIDO2 key through the same entry points, which matters for deployments where hardware refresh is slow and old keys stay in circulation for years. Underneath, the top level directory listing shows a `src/` tree, a `tools/` directory for the command line utilities, a `man/` directory for documentation, and `examples/` holding small C programs such as `cred.c`, `info.c`, `manifest.c`, `largeblob.c`, `reset.c`, `setpin.c`, `select.c`, `retries.c` and `bio.c`. Those file names describe the capability set concretely: credential management, device info, resident key style manifest handling, large blob storage, device reset, PIN setting and PIN retry logic, plus biometric enrollment. The presence of `fuzz/` and a `regress/` directory indicates that the parsing and protocol surfaces are treated as attack surface worth testing, which is consistent with a library whose input is untrusted hardware responses.

Installing from a package manager on Linux

The installation path is straightforward on the two major distributions the README names. On Fedora 34 and later, and on Ubuntu 20.04 (Focal) and later, the packages cover the shared library, the development headers, the documentation and the command line tools in one command. The documentation also points to Yubico's PPA for newer versions on Ubuntu, and spells out the older Bionic route if you need it. Here is the Fedora and Ubuntu command line as the project gives it:

bash
  $ sudo dnf install libfido2 libfido2-devel fido2-tools
bash
  $ sudo apt install libfido2-1 libfido2-dev libfido2-doc fido2-tools

After that, the first real check is not an API call. It is whether the process can open the device at all, and that is where Linux permissions come in. A separate path for building from source is also given, which is the one to use if you need a configuration the packages do not ship. On UNIX-like systems:

bash
  $ cmake -B build
  $ make -C build
  $ sudo make -C build install

The build notes warn that pkg-config may need to be installed or `PKG_CONFIG_PATH` set depending on the platform, and points at the `.actions/` and `windows/` directories for complete platform specific instructions.

The udev rule decides whether your process can open the key

This is the failure mode that catches most first time Linux users. A FIDO key presents itself as a HID device, and the default udev rules on many distributions do not let an ordinary user open the corresponding `hidraw` node. On Linux a udev rule is usually required before a process can open the device, and the documentation says so directly, and it offers a sample rule for HID access to Yubico devices:

code
#udev rule for allowing HID access to Yubico devices for FIDO support.

KERNEL=="hidraw*", SUBSYSTEM=="hidraw", \
  MODE="0664", GROUP="plugdev", ATTRS{idVendor}=="1050"

Read the rule carefully before reusing it. It matches by vendor identifier, and the identifier it filters on belongs to one manufacturer, so a key from another vendor will not match and will still be blocked. The rule grants group read and write, which means membership of the named group becomes a privilege decision rather than a technical one. The repository keeps a `udev/` directory at the top level, and `openbsd-compat/` and `windows/` sit alongside it, so platform specific plumbing is separated from the core sources. If your application is going to a fleet of machines, this rule, and the group membership behind it, is the part that decides whether the feature works at all on a locked down workstation.

CMake options decide what the library can reach on a given platform

The build is configurable, and the option table in the README is worth reading closely because the defaults encode Yubico's own priorities rather than a neutral guess. `BUILD_EXAMPLES`, `BUILD_MANPAGES`, `BUILD_SHARED_LIBS`, `BUILD_STATIC_LIBS` and `BUILD_TOOLS` are all on by default, so a default build gives you everything: shared and static libraries, the utilities, the manual pages and the sample programs. `NFC_LINUX` is on, which enables netlink NFC support on Linux, and `USE_WINHELLO` is on, which abstracts Windows Hello as a FIDO device so the same code path works when no physical key is inserted. Two options are off by default, and the option table states that options disabled by default are not officially supported. `USE_HIDAPI` would use hidapi as the HID backend and requires the hidapi library. `USE_PCSC` would enable experimental PCSC support, requires pcsc-lite on Linux, and is labelled experimental in the table itself. `FUZZ` is off unless you want the fuzzing instrumentation. The practical consequence is that enabling PCSC is a support risk you take knowingly, while switching the Windows Hello abstraction off or the netlink NFC path off changes what hardware the built library can reach.

Windows deployment is about DLL placement, not about compilation

The Windows guidance is short but carries a specific warning. Rather than publishing binaries in the usual way, the project directs Windows users to Yubico's release page for ARM, ARM64, Win32 and Win64 artefacts. The safe usage guidance is explicit: unpack the artefacts in a trusted, non-writable directory with DLLs alongside the executable, and consult Microsoft's own documentation for general guidance on DLL deployment and safe packaging. The same guidance notes that the dynamically linked artefacts are built with `/MD` and may require the corresponding Visual C++ runtime to be present. That detail has bitten integrators: a build that links the shared library can fail on a machine that has no matching runtime, and the failure looks like a missing entry point rather than a packaging problem. `USE_WINHELLO` being on by default is worth pairing with this. If Windows Hello is abstracted as a FIDO device, then the same application code can prompt a platform biometric prompt as a fallback, which changes what the security properties of your flow are. That is a design decision to make explicitly rather than inherit by default.

Releases live off GitHub, and the license is a two clause BSD

Two operational facts stand out. First, the project identifies the current release as 1.17.0 and points to Yubico's release page for signed release tarballs, which is where you should fetch a version you intend to ship. Second, and more awkwardly for automation, the repository itself has no GitHub releases, so tooling that watches the GitHub releases API for a version bump will find nothing to react to. Maintenance signals come from the commit history: the last push landed on 2026-10-19, and the repository is not archived, so it is being worked on. The license is BSD 2-clause, with the full text in the LICENSE file for the full text. A two clause BSD is permissive, requiring only that the copyright notice and conditions travel with redistributed copies, and it carries no copyleft obligation on the surrounding application. That is straightforward, though it is not the same as a legal opinion, and the fact that the GitHub metadata flags the license as something it cannot classify only reflects that the file format did not match its known patterns. Security issues are handled separately from ordinary bugs: the project asks for regular bugs through GitHub Issues and directs security reports to [email protected], with a PGP key reference for encrypted mail.

Editorial conclusion

Adopt libfido2 if you are writing the code that a browser or a server would otherwise duplicate, and you can live with a library that needs a udev rule, a C toolchain and a maintained OpenSSL. Do not adopt it for a consumer facing product, for NFC on platforms where the netlink path is unavailable, or for anything that needs release tarballs fetched from a static page. Before starting, verify that your target platform builds the NFC_LINUX path you need, that the current release is still 1.17.0, and that your Windows deployment places the DLLs in a trusted, non-writable directory.

Frequently asked questions

How do I install libfido2 on Ubuntu?

A single apt command is given for Ubuntu 20.04 (Focal) and later that installs the library, the development files, the documentation and the command line tools. Newer versions are also available through Yubico's PPA.

What does libfido2 depend on to build?

It depends on libcbor, OpenSSL 3.0 or newer, and zlib. On Linux, libudev from systemd is required as well, and pkg-config may need to be installed or PKG_CONFIG_PATH set.

Does libfido2 work on macOS and Windows?

Linux, macOS, Windows, OpenBSD and FreeBSD are listed as supported platforms. On macOS it installs with a brew command, while on Windows the artefacts come from Yubico's release page for ARM, ARM64, Win32 and Win64.

Which FIDO protocols does libfido2 speak?

It supports both the FIDO U2F (CTAP 1) and FIDO2 (CTAP 2) protocols, communicating with devices over USB or NFC.

Why can my program not open the security key on Linux?

A udev rule is needed to access the FIDO device in many setups, and a sample rule granting access to hidraw nodes for Yubico vendor identifiers with mode 0664 and group plugdev. A key from another vendor will not match that rule.

Official sources

  1. Issues
  2. README
  3. Yubico/libfido2 on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yubico-libfido2.svg)](https://hysenlabs.com/projects/yubico-libfido2)

Was this useful?