Skip to main content

duo-hotp-auth

Duo Mobile HOTP code generator based on Duo activation links.

This is an unofficial Python library that allows you to activate Duo Mobile devices from Duo activation codes (or QR URLs) and generate HOTP codes using the stored device secrets.

Features

  • ✅ Activate Duo Mobile devices from activation codes or QR URLs
  • ✅ Store device information securely on disk (per-user appdata directory)
  • ✅ Generate HOTP codes using RFC 4226 (HMAC-SHA1)
  • ✅ Automatic counter management
  • ✅ Cross-platform storage (Windows, macOS, Linux)
  • ✅ Command-line interface
  • ✅ Clean Python API

Installation

pip install duo-hotp-auth

Getting Your Duo Activation Code

Before you can activate a device, you need to obtain the Duo activation code or QR URL from your Duo account:

  1. Log in to your Duo account on web (or wherever your duo 2FA is managed)
  2. Add a new device:
    • Navigate to your account settings
    • Select "Add a new device" or "Add another device"
    • Choose device type: Tablet or iOS (iPhone/iPad)
  3. Get the activation code/URL:
    • When the QR code appears on screen, right-click (or Control+click on macOS) on the QR code image
    • Select "Copy image address" or "Copy image URL" from the context menu
    • This will copy a URL like: https://api-xxxx.duosecurity.com/frame/qr?value=duo%3A%2F%2F...
  4. Use the copied URL with the activation command (see Usage below)

Alternative: If you can see the raw activation code (a string like test123...-YXBp...), you can use that directly instead of the QR URL.

Usage

Python API

Activate a device

from duo_hotp_auth import DuoDevice

# From a QR URL
device = DuoDevice.activate(
    "https://api-xxxx.duosecurity.com/frame/qr?value=duo%3A%2F%2F...",
    name="my-phone"
)

# Or from a raw activation code
device = DuoDevice.activate("test123...-YXBp...", name="my-phone")

Generate HOTP codes

# Load an existing device
device = DuoDevice.load(name="my-phone")

# Generate the next HOTP code (counter increments automatically)
code = device.next_code()
print(code)  # e.g., "123456"

# Generate with custom digit count
code = device.next_code(digits=8)

# Generate without persisting counter (for testing)
code = device.next_code(persist=False)

Command-Line Interface

Activate a device

duo-hotp activate "https://api-xxxx.duosecurity.com/frame/qr?value=duo%3A%2F%2F..." --name my-phone

Or using a raw activation code:

duo-hotp activate "test123...-YXBp..." -n my-phone

Generate a code

duo-hotp code --name my-phone

Or with custom digits:

duo-hotp code -n my-phone -d 8

List all devices

duo-hotp list

Storage

Device information is stored in a cross-platform appdata directory:

  • Windows: %APPDATA%\duo-hotp-auth\duo-hotp-auth\
  • macOS: ~/Library/Application Support/duo-hotp-auth/
  • Linux: ~/.local/share/duo-hotp-auth/

Each device is stored as a JSON file (e.g., default.json, my-phone.json).

Security Notes

⚠️ Important: This library stores device keys and HOTP secrets on disk. You are responsible for:

  • Securing the device files (file permissions, encryption at rest, etc.)
  • Complying with Duo's terms of service
  • Using this library in accordance with your organization's security policies

This is an unofficial library and is not affiliated with or endorsed by Duo Security.

Development

# Clone the repository
git clone https://github.com/christianobora/duo-hotp-auth.git
cd duo-hotp-auth

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

License

MIT License - see LICENSE file for details.

Disclaimer

This library is provided as-is for educational and legitimate use cases. The authors are not responsible for any misuse or security issues that may arise from using this software. Always ensure you have proper authorization before activating devices and generating codes.

Metadata

Release files for duo-hotp-auth 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for duo-hotp-auth 0.1.0
File Size Uploaded
duo_hotp_auth-0.1.0.tar.gz 12.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for duo-hotp-auth 0.1.0
File Interpreter ABI Platform
duo_hotp_auth-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.7 kB

Release files / duo_hotp_auth-0.1.0.tar.gz

Download URL duo_hotp_auth-0.1.0.tar.gz
Size 12.6 kB
Tags Source
SHA-256 checksum
How to use checksums
ee1cc4d9a50bec85530b322057d868b7eea1337c380f396851c2135abb2eb964
BLAKE2b-256 checksum
How to use checksums
7ffe6aaf306e50c172c9f2d6b542a1be2f91249fc83d1f16e277fdf46eda0671
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release files / duo_hotp_auth-0.1.0-py3-none-any.whl

Download URL duo_hotp_auth-0.1.0-py3-none-any.whl
Size 11.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2208edbf4186957b012ea4c33558656a5fb208aca512260b57ce793d90fe2b35
BLAKE2b-256 checksum
How to use checksums
48024c1a9731849cdf0eed0774b3d6623423a058d3e2010fea2709b47389704e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page