Securely define QMK firmware macros on macOS

One of the best features of the QMK keyboard firmware is its support for macros. QMK also supports a dynamic macro form, but it’s less useful since the macro keycodes are stored in RAM and go away if you reset the keyboard, which highly likely happens if you restart your computer as it reinitialises the USB controllers.

So the static macros defined and baked in when you build the firmware are much more useful, since the keyboard doesn’t forget them, and they can be longer since they’re not stored in the limited RAM that most keyboard controllers have.

What if you want the keyboard to use that functionality to type a password, then? First, think long and hard about whether that’s what you actually want to do! It’s a significantly compromised threat model since the password is not stored in any kind of secure element inside the keyboard controller.

That means if a determined attacker takes possession of your keyboard, even if they don’t know what key activates the macro, retrieving the firmware and dumping the password is an involved process but ultimately something they could do. The password will be baked into the string data section in the firmware preamble, in the clear.

QMK doesn’t use a standard keyboard scancode for any static macros you define — at least if you implement them the way the documentation asks you — therefore it’s not possible for a webpage or app to randomly guess it. Therefore the only way to generate the QMK-specific keycode is pressing it physically.

Knowing all of that, and assuming you’re still interested in using that functionality, you’ll want to do the best possible job of securely delivering the string from your keyboard to the firmware compiler.

On macOS, remember that you can save and retrieve secure strings using the security utility. Using the command line you can put the password into the keychain, while leaving no trace of it in your shell history or pasteboard, and then have QMK’s firmware make system retrieve it for you at compile time.

So you feed the keychain the password securely — in my example you type security add-generic-password -a qmk -s tada68 -w, which prompts you securely for the string — then have QMK’s build system retrieve it and bake it into your firmware, flash that to your keyboard, then run make clean to wipe the firmware from disk so someone can’t run strings on it later.

That way you can check that firmware modification into source control, and even push it somewhere public, without giving away the password you’re feeding to the macro and then flashing to your keyboard. I did just that!

So if you are interested in having your keyboard type certain strings on your behalf, and where you’re as safe as possible feeding the string to the firmware when you build it, the security based method on macOS works.

Just be very aware of the threat model for someone retrieving it, if they have physical access to your QMK-running keyboard you use this functionality with and are determined enough.