Security

Nobody told me about ykman otp swap

Tony Mattke · 2026.10.15 · 8 min read

The 5C Nano sits flush in the side port of my laptop, which is the reason to buy a Nano in the first place. It also means my palm drags across it a few dozen times a day, and every pass fires forty-four characters of one-time password into whatever field has focus.

text
cccccbhgtrlvkkkfnhgfkdbvtlbhbdrbkjnvjvcktgcn

Mostly it lands in Teams, which kicks off a frantic dash to ninja edit the message before anybody calls out the Yubi Sneeze. Occasionally it lands in a sudo prompt, which at least fails quietly. Sound familiar? If you’ve got a Nano living in a side port, I’d put money on it.

I’d filed this under hardware design problem. The Nano needed a cover, a switch, or even a recessed contact… something to keep a stray hand brushing across it from setting the thing off. I was mid-complaint about that, venting at Claude instead of doing actual work, when it asked whether I’d ever looked at what was sitting in slot 1. The whole thing is fixable in software, in one command.

What’s firing, and from where

The string is a working Yubico OTP, and it comes out of slot 1 of the YubiKey’s OTP application.

The OTP application has exactly two slots, and they’re distinguished by how long you hold the contact. Yubico’s own SDK documentation puts the boundary at 1 to 2.5 seconds for slot 1 (the ShortPress slot) and 3 to 5 seconds for slot 2 (the LongPress slot). A palm brush is well inside that first window.

An off-the-shelf YubiKey ships with slot 1 already loaded with a Yubico OTP credential registered to YubiCloud, and slot 2 completely empty. So the factory default puts a hair trigger on the gesture you make by accident, and nothing on the one you make deliberately. Somebody shipped that on purpose… and if you’ve never touched YubiCloud, which there’s not much reason to have, that credential has been firing into your text fields for years for nothing.

In The Private Eyes, Tim Conway’s inventor rigs a pistol to a timer. It fires at the appointed hour with nobody’s finger near it, and the trigger does nothing the rest of the time. Slot 1 is a Time Gun with the hour set to whenever your palm passes by. Working as designed, start to finish.

Each slot can hold one of four things. A Yubico OTP, an OATH-HOTP credential, a static string, or a challenge-response secret.

Check what you have before you touch anything

Run this first. Seriously, first.

bash
ykman otp info

You’ll get back the state of both slots. If slot 1 is programmed and slot 2 says empty, you’re in the factory default and both fixes below are safe.

But if slot 2 already has something in it, stop and read the next section before you swap, because the swap is symmetric and whatever lives in slot 2 becomes your new hair trigger. I ran it before checking. It worked out, but only because slot 2 happened to be empty, and luck is a terrible configuration management strategy.

Fix one, move the OTP out of the way

If you do use Yubico OTP somewhere and want to keep it, swap the slots.

bash
ykman otp swap

Short touches now do nothing. A deliberate 3 second hold types the OTP. I wish someone had told me this in 2017.

Fix two, turn the whole thing off

Most people have never touched YubiCloud. If that’s you, the whole application can go away over USB and the spew stops for good.

bash
ykman config usb --disable OTP

The valid application names are OTP, U2F, FIDO2, OATH, PIV, OPENPGP, and HSMAUTH. Add -f to skip the confirmation prompt.

The challenge-response catch

Challenge-response (HMAC-SHA1) is one of those four, and it lives inside the same OTP application you just disabled.

That matters because challenge-response is what KeePassXC uses for database unlocking, and what a pile of LUKS and full-disk-encryption setups use too. Disabling OTP to stop the cccccc spew will take challenge-response down with it, and you’ll find out when your password manager stops opening. Which is a memorable way to learn where an application boundary sits.

So if ykman otp info shows a challenge-response secret in either slot, swap instead of disabling. Challenge-response doesn’t type anything on touch, so parking it in the short-press slot is harmless.

Why your other credentials don’t do this

The OTP application is a USB keyboard. It has no concept of a pending request and no way to know whether anything asked for input. Touch the contact, it types, and that’s the whole protocol. Clippy with a security budget, volunteering forty-four characters into your Teams thread because it looked like you might want them.

FIDO2, PIV, OpenPGP, and OATH work the other way around. Touch is a user presence check attached to an operation that something already initiated, so the key is waiting on a request before your touch means anything. Brush a YubiKey with no pending WebAuthn ceremony and nothing happens. PIV even has a cached touch policy where a touch stays valid for 15 seconds so you aren’t tapping repeatedly through a signing operation.

Your hardware-backed SSH keys, your passkeys, your PIV certificates. None of them are affected by either fix above. The only thing you’re turning off is the one component that was typing without being asked.

Getting ykman

The tool is YubiKey Manager CLI, and the binary is ykman. It’s separate from the Yubico Authenticator desktop app, though that app bundles a copy.

macOS

bash
brew install ykman

The Homebrew formula is ykman, which trips people up because every Linux distro calls it yubikey-manager. There’s also a .pkg installer on Yubico’s releases page if you’d rather not use Homebrew.

Debian and Ubuntu

bash
sudo apt install yubikey-manager

Fedora

bash
sudo dnf install yubikey-manager

Arch

bash
sudo pacman -S yubikey-manager

Windows

Grab the .msi from the releases page. Avoid any file with -qt in the name, those are the GUI build.

Any platform, via Python

bash
pipx install yubikey-manager

uv tool install yubikey-manager works too, as does plain pip install --user yubikey-manager. On macOS you may need brew install swig first.

On Linux, you need pcscd installed and running or the smart card interface won’t answer. On macOS, ykman otp commands fail with a permissions error until you grant Input Monitoring to the terminal application you’re running it from, which trips people up because the obvious move is to go looking for ykman in that list. You’ll find the toggle under System Settings, Privacy and Security, Input Monitoring. Apple classifies the YubiKey’s OTP interface as a keyboard, which, of course, is what it is.

The empty slot is a free keyboard

Once you’ve moved the OTP out of slot 1, you’ve got an empty slot that fires on a casual touch. Useful, as long as what you put in it is something you want typed constantly and don’t mind leaking.

My email address, for example.

bash
ykman otp static --keyboard-layout US 1 '[email protected]'

Now a short touch types my email. Expense portals, conference wifi captive portals, the shipping form on some vendor’s store that doesn’t autofill. One tap.

The default keyboard layout is MODHEX, and the MODHEX character set is only c b d e f g h i j k l n r t u v. No @, no ., no digits. If you skip --keyboard-layout US the command will reject your email address, and the reason won’t be obvious. MODHEX exists because those characters land on the same physical keys across most national keyboard layouts, so a MODHEX string types identically whether the host is set to US, German, or French. The moment you specify US, you’ve traded that portability for punctuation. Fine on a laptop you control, annoying at a conference on someone else’s machine. But I digress.

The limit is 38 characters, which fits most email addresses and rules out anything longer.

And the obvious caveat. A static slot types on a brush, which is the behavior you just spent this post eliminating. An email address in a Slack channel is a shrug. A password in one is an incident. Put the email in slot 1 if you like, keep real secrets in slot 2 behind the deliberate 3 second hold, or better yet keep them in a password manager where they belong.

If you’d rather see what’s there before overwriting anything, ykman otp info again, and ykman otp delete 1 clears a slot outright.

The short version

Run ykman otp info. If slot 2 is empty, run ykman otp swap and get on with your day. If you’ve got challenge-response anywhere, swap it and leave the application enabled. Your palm stops talking to your text fields and nothing else changes.

I’d been carrying one of these for years and never once ran ykman otp info to see what was in there. The default was doing something I didn’t ask for, and I blamed the hardware because the fix was never in front of me. Same shape as the one-line alias I wrote about a while back, or keeping netcat within reach.

Go look at your slots. It takes four seconds, and you might find the thing that’s been sneezing into your chat window all along. If you’ve got a better use for the free slot than an email address, I want to hear it.

More in Security

Related Posts

Networking · 12 min read

ARIN at CHI-NOG 13: The State of Routing Security

2026.06.09

I sat in Brad Gorman’s RPKI workshop at CHI-NOG 13 with the kind of attention you give a talk when somebody on stage just admitted the security model has known holes.