My YubiKey Kept Spamming OTPs — So I Built a macOS Menu Bar Fix
If you use a YubiKey on macOS, you probably know this moment.
You plug it in.
Your cursor happens to be in Slack.
And suddenly:
cccccccbhtnlrnhjkgljuhv...
Your YubiKey just typed an OTP into the wrong window.
It’s not dangerous.
It’s just… annoying.
After the third time this happened to me mid-conversation, I went looking for a clean way to quickly disable the OTP interface — without digging into CLI commands every time.
That’s how YubiToggle was born.
The Problem
YubiKeys expose multiple USB interfaces (OTP, FIDO, CCID, etc.).
When OTP is enabled, pressing the YubiKey sends a one-time password as keyboard input. That’s great when you intend it.
It’s less great when:
- Your cursor is in Slack
- Or in a terminal
- Or in a production shell 😅
Yes, you can disable OTP using ykman:
ykman config usb --disable OTP --force
But that’s not something I wanted to do manually every time.
What About YubiSwitch?
There’s already a macOS utility called YubiSwitch that solves this problem.
But for me:
- It felt outdated
- Development activity seemed minimal
- The UX wasn’t very “macOS-native”
Instead of forking it, I decided to build something small, modern, and focused.
🔐 YubiToggle
YubiToggle is a minimal macOS menu bar app that lets you toggle your YubiKey’s OTP interface on and off with a single click.
It lives quietly in your menu bar:
- No Dock icon
- No background daemon
- No unnecessary features
Features
- One-click OTP enable/disable
- Clear visual state:
- 🟢 OTP enabled
- ⚪ OTP disabled
- 🔵 Syncing
- 🟠 Error
- Auto-syncs with hardware every 10 seconds
- Optional launch at login
- Optional system notifications
- Universal binary (Apple Silicon + Intel)
Built With
- Swift 6
- SwiftUI
-
MenuBarExtra(no Dock presence) -
ykmanCLI under the hood
The app is intentionally a thin wrapper around a well-maintained CLI, paired with a clean native UI.
How It Works
YubiToggle checks the current device state using:
ykman info
And toggles OTP via:
ykman config usb --disable OTP --force
ykman config usb --enable OTP --force
All CLI calls are wrapped in async Swift code so the UI stays responsive.
To avoid UI drift (for example, if the device is modified externally), the app refreshes the hardware state every 10 seconds.
Project Structure
The project is intentionally simple:
YubiToggle/
├── Package.swift
└── Sources/YubiToggle/
├── YubiToggleApp.swift
├── CLI/YubiCLI.swift
├── Models/YubiKeyDevice.swift
├── ViewModels/YubiKeyViewModel.swift
└── Views/
├── MenuBarView.swift
└── SettingsView.swift
No over-engineering — just enough separation to keep things clean and readable.
A Few Design Decisions
macOS 13+ only
I chose modern SwiftUI APIs over backward compatibility.Use
ykmaninstead of raw HID access
Let Yubico handle device complexity; I focus on UX.Not notarized (yet)
macOS will ask you to “Open Anyway” on first launch. This is a one-time step.
Installation
Homebrew
brew tap sudheendrachari/tap
brew install --cask yubitoggle
Manual
Download the DMG from GitHub releases and drag the app to Applications.
Repository:
https://github.com/sudheendrachari/yubi-toggle
Why Open Source?
This is the kind of tool that:
- Solves a small but real annoyance
- Doesn’t need to be commercial
- Can benefit from community feedback
If you use a YubiKey on macOS and have ever wished you could quickly disable OTP without touching Terminal, this might be useful.
What I Learned
Even tiny utilities benefit from:
- A clear, narrow scope
- Native UX
- Minimal features done well
- Treating CLI tools as first-class building blocks
Sometimes the best apps are just good interfaces over solid existing tools.
If you build macOS utilities or work with hardware-backed security tools, I’d love to hear what you’ve built — or what’s annoyed you enough to consider building something yourself.
Top comments (0)