top of page

Bulk deployment of Yubico FIDO2 security key

  • Writer: Pascal
    Pascal
  • 2 days ago
  • 6 min read

Introduction

In this blog, we’ll dive into the bulk enrollment of Yubico Security Keys in combination with Microsoft Entra ID (formerly Azure AD). While Microsoft’s standard approach is to have end users register their keys via self-service, large-scale deployments quickly raise the question: how can we centrally, efficiently, and reliably enroll FIDO2 keys for a large group of users?


Both Jan Bakker and YubicoLabs have previously shared solutions that use Python scripts to automate this process. In theory, this approach provides a workable path for bulk registration of security keys. However, in practice, implementation is not always straightforward—particularly because the correct Python version must be used carefully.


Personally, I ran into several challenges trying to get this solution working. Fortunately, I received support from Yubico themselves, as there are indeed some pitfalls in the practical implementation—such as the need for a new Python script that can be used. That’s why I’d like to walk you step-by-step through how I managed to get it working.


For your information: Currently, there is no out-of-the-box solution available, and this bulk enrollment method is considered a proof of concept.

Prerequisites

The following components are essential for this solution (note: specific versions are also important):

Tip: If you already have Python installed, I recommend fully uninstalling it or at least starting with a clean installation.

The following components are essential for this Bulk Enrollment PoC:

  1. Python 3.10 for Windows (link)

  2. GIT for Windows (link)

  3. Python scripts (YubicoLabs Github)

  4. Entra Registered App (ClientID + Secret)

  5. Sufficient permissions, both locally (e.g., to run Python) and within Entra ID

  6. YubiKeys (Security Keys or YubiKey by Yubico)

  7. Entra ID Security Group

  8. User CSV file

  9. Config JSON file

  10. Requirement text file


Process Flow

For the bulk enrollment, two Python scripts are used. On the GitHub page of Saint-ScobberLotcher, the process involving these two scripts is clearly explained. Below is a summary:

Process Flow Bulk-Enrollment FIDO2 Python Scripts
Process Flow Bulk-Enrollment FIDO2 Python Scripts

Script 1The first script, step1GetFIDO2Challenges.py, is used to:


  • Retrieve a list of users eligible for FIDO2 registration. This is currently determined by membership in a group specified in the configs.json file.

  • For each group member, the script calls the Microsoft Graph API endpoint:/users/{userPrincipalName | id}/authentication/fido2Methods/creationOptions.This endpoint returns the parameters required to generate FIDO2 credentials. These will later be used to create a credential on a YubiKey.

  • The script writes the relevant details to a CSV file.


Script 2The second script, step2CreateAndActivateCredential.py, is used to:


  • Process the CSV file line by line, and:

    • Use the information from the CSV to build the FIDO2 credential creation request for a YubiKey.

    • Capture the YubiKey’s response and call the Graph API endpoint:/users/{userPrincipalName | id}/authentication/fido2Methods.This endpoint assigns and activates the FIDO2 credential on the user’s profile in Entra ID.

  • The script also writes a new row to a CSV file containing:

    • the userPrincipalName

    • the Entra object ID of the registration

    • the serial number of the YubiKey (if available)

    • and the PIN, if it was randomly generated by the script.


Setup

Step 1: Create an Entra App Registration


Register an Entra App Registration

  • Go to the Entra ID > App registrations section.

  • Create a standard app registration and give it a logical name.

  • Note the Application (Client) ID generated upon creation — this will be used as the client_id in Step 2.


Configure API Permissions

  • Navigate to API permissions and add the following Application permissions for Microsoft Graph(make sure to select Application permissions, not Delegated permissions):

  • Grant admin consent for these permissions.


Create a Client Secret

  • Go to Certificates & secrets and add a New client secret.

  • Make note of the Value shown upon creation — this will be used as the client_secret in the configs.json file.

  • Also note the Client ID and Tenant name (or Tenant ID), as these will also be required later.


Step 2: Installing and Running the Scripts


  1. Download and install Python 3.10 for Windows (later versions may cause errors) from the following link:https://www.python.org/ftp/python/3.10.11/python-3.10.11-amd64.exe

  2. Choose Advanced Options/Advanced Install during setup and make sure to check Add Python to environment variables.


    Python install advanced options
    Python install advanced options

    During the installation (last page), select the option “Disable path length limit.”

    Python install Disable path length limit
    Python install Disable path length limit


  3. If you haven’t installed Git yet, do so now. You can download it here:https://git-scm.com/downloads/win

    Install it on your system and make sure to select the option “Use Git and optional Unix tools from the Command Prompt.” If Git is already installed, you may need to reinstall it and select this option. Choosing the default settings on the other installation pages is usually sufficient unless you have specific requirements beyond using the bulk enrollment script.

    GIT install path environment
    GIT install path environment


  4. Open a command prompt window (not PowerShell) as an administrator and run python to confirm it launches without issues and that the version is correct (3.10.11).


    Once the version is verified, type exit() to close Python.

    Python version check
    Python version check


  5. Create a virtual environment by typing the following command: python -m venv bulkreg-env Note: Running this command will create the environment in the current working directory.

    This process will take a few seconds to complete. Once finished, activate the environment by typing: bulkreg-env\Scripts\activate.bat You should now see a prompt that starts with bulkreg-env.


    Whenever you want to run the scripts in the future, make sure to run this activate.bat command first to activate the virtual environment.

    Python create environment
    Python create environment


  6. Add the following to a new Notepad text file named requirements.txt inside the bulkreg-env folder (you can run notepad bulkreg-env\requirements.txt from the command prompt) and save the file.

    Make sure the content of the requirements.txt file includes the necessary Python packages for running the scripts. The file might look like this: cryptography==42.0.5

    requests==2.31.0

    fido2==1.1.1

    pywin32; platform_system=="Windows"

    Python requirement text file
    Python requirement text file


  7. Navigate to the bulkreg-env folder and run dir to confirm that requirements.txt is in the correct location.

    Python environment Bulk
    Python environment Bulk

  8. Install YubiKey Manager using Git. Note the “.” at the end of the last command — this is required. Run command: git clone https://github.com/Yubico/yubikey-manager.git Open folder: cd yubikey-manager Run command: python -m pip install .

    Git and install yubikey-manager
    Git and install yubikey-manager

  9. Navigate back to the bulkreg-env folder (using cd ..) and run the following command: pip install -r requirements.txt

    Install Python Yubico Requirements
    Install Python Yubico Requirements

  10. Install the bulk enrollment script. This is necessary even if you have installed and used it previously. git clone https://github.com/YubicoLabs/entraId-register-passkeys-on-behalf-of-users.git Navigate to the bulkRegistration folder within the cloned repository: cd entraId-register-passkeys-on-behalf-of-users/bulkRegistration


    Open folder git repository
    Open folder git repository

    This ensures that you have the necessary script in the correct location for further configuration and use.

  11. Run notepad configs.json and adjust the fields according to your requirements and environment. You will need the tenant, client_id, and client_secret from Entra, which were created in Step 1.

    An example of a completed configs.json file is shown below:

    Example configs.json Entra Authentication
    Example configs.json Entra Authentication

    Important: Replace the values for tenant, client_id, and client_secret with the details you obtained in Step 1 when creating the app registration in Entra.

    After updating the configuration, save the file.

  12. Run the script step1GetFIDO2Challenges.py.

    This will iterate through all users in your usersInScopeGroup and add them to the file usersToRegister.csv.

    step1 Get Users from Entra Security Group Script
    step1 Get Users from Entra Security Group Script

    To do this, run the following command in the command prompt (make sure your virtual environment is activated): python step1GetFIDO2Challenges.py After running this script, it will process the users you added to the usersInScopeGroup and save their details into usersToRegister.csv.

    If everything is set up correctly, you should now find the CSV file containing the users eligible for registration.

    Output Users.csv
    Output Users.csv

  13. Delete step2CreateAndActivateCredential.py from the folder and replace it with the version below. This fixes a bug in the script where it was unable to access the YubiKey due to a missing function.

  1. Remove .TXT so that it becomes a Python script. Make sure the security key (YubiKey) is connected to the device, then run the following: python step2CreateAndActivateCredential.py By running this script, the YubiKey will be configured and activated for the specified users in the usersToRegister.csv file.

    Make sure your YubiKey is properly connected to your device before running the script, so the process can proceed smoothly.

    Step 2 Register multiple Yubikeys to User(s)
    Step 2 Register multiple Yubikeys to User(s)

    This script will iterate through your usersToRegister and generate credentials based on the settings in configs.json.

    Follow the instructions below:

    • Follow all prompts that appear during the script execution and change the keys when requested.

    • Replace the security key (YubiKey) each time a new user needs to be registered or configured.

    This means that after each user, you need to swap the YubiKey for a new one so that every user gets their own unique credential.


Resources


Comments


bottom of page