Open-source project
TheMaxMur/RS-Key avatar
TheMaxMur/RS-Key

RS-Key flashes onto an RP2350 in one file, and warns it has had no audit

Turn a $5 Raspberry Pi RP2350 board into an open-source hardware passkey: WebAuthn/FIDO2 logins, ssh & git signing, OpenPGP, PIV, TOTP. Rust firmware, no_std.

555 stars54 forksRustAGPL-3.0

At a glance

What is it?
AGPL-3.0 Rust firmware that turns a five dollar Raspberry Pi RP2350 board into a USB authenticator covering FIDO2, OpenPGP card, PIV, OATH and Yubico-style OTP, with an experimental post-quantum FIDO2 mode. The threat model is written down as plainly as the feature list, which is the right way to ship something like this.
Who is it for?
RS-Key suits someone who wants a hardware authenticator to experiment with, to learn the applet protocols on, or to keep as a second key, since flashing is a file copy and the firmware speaks protocols their existing tooling already handles. It is not a replacement for a certified security key, and the project's own text says as much: no external audit, no secure element, and at-rest protection that only means anything once you fuse the OTP master key.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One file, one button, and no toolchain

The pitch is unusually concrete for a firmware project. What this is: firmware, a `.uf2` file you drop onto a board, and nothing here is for sale. What you need: any RP2350 board from about five dollars and a USB cable, with no soldering, no programmer and no toolchain. What you get: a USB authenticator that your browser, `ssh`, `gpg` and `ykman` already know how to talk to. The manual install is four steps. Download `rs-key-<version>-default.uf2` from the releases page, hold the board's BOOT button while plugging it in so a drive named `RP2350` appears, copy the file onto that drive, and the board reboots as a security key. Then register a passkey at webauthn.io, where the browser walks you through setting a PIN the first time and afterwards asks for a physical touch on the BOOT button. There is also a web flasher at rskey.fob.wtf that can download, verify, sign and flash the firmware, though it needs a desktop Chromium browser.

Four images by flash size, ten more by behaviour

The release set is bigger than one file, and the table explains how to choose. The four board-matched images are selected by flash size: `default` for most RP2350 boards with 4 MB, `2mb` for the Seeed XIAO RP2350 and the Waveshare RP2350-Zero-CM, `16mb` for the TenStar RP2350-USB, and `display` for the Waveshare RP2350-Touch-LCD-2.8. Getting this wrong is not subtle, since the firmware has to fit the flash you actually have. Beyond those, ten more images are behaviour variants covering post-quantum algorithms, the FIPS profile, `alwaysUv` and PIN hardening, and the full table sits in the release documentation alongside how to verify the cosign signature and how to reproduce the build. That last point is the one that matters for trust in a security project: you are not asked to take a binary on faith, because there is a documented path to check it. Capacities are flash-bound and generous, with up to 256 resident passkeys, 255 OATH accounts, 24 PIV slots and 4 OTP slots named as examples.

The README leads with the fact that nobody has audited it

The warning block is the first substantive thing in the file and it is not boilerplate. The project is described as experimental, it has had no external security audit, the RP2350 is not a secure element, and a stolen board is only as strong as the optional OTP and secure-boot hardening you have applied. The instruction is to read the threat model and the limitations documents before trusting it with anything real. The section on what it does not protect against is equally specific. Physical and lab attacks are out of scope: decapping, microprobing, fault injection beyond the on-chip glitch detectors, power and electromagnetic side channels, and flash-emulation time-of-check-to-time-of-use. A compromised host with the device unlocked is also out of scope, because like any security key the device performs operations you authorised while plugged in and unlocked. And at-rest protection only becomes meaningful after you fuse the OTP master key, which is documented separately as a production setup step.

Five applets over one composite USB device

The architecture is a single composite USB device with three interfaces feeding a set of applets, which is what lets ordinary host software work unmodified. The host side is a browser, `ssh`, `gpg`, `ykman` and the project's own `rsk` and `rsk-tui` tools. Over USB the device presents a FIDO human interface device, a CCID smart-card interface, and a keyboard interface used only for typing OTP codes. Those feed applets for FIDO2 and U2F, OpenPGP, PIV, OATH, Yubico-style OTP and device management, which in turn sit on a core holding the master seed, a true random number generator and the flash store, all on an RP2350 with no secure element. What each applet is good for is spelled out: FIDO2 covers passkeys, two-factor logins and `ssh ed25519-sk`; OpenPGP card 3.4 covers `gpg` signing, decryption and authentication over both EC and RSA; PIV covers X.509 smart-card work through PKCS#11; OATH covers TOTP and HOTP; and the OTP applet has four slots plus the keyboard interface.

Post-quantum FIDO2 is implemented and advertised off

The experimental entry is the most interesting engineering in the list. All three ML-DSA schemes are implemented: ML-DSA-44 mapped to COSE algorithm id minus 48, ML-DSA-65 to minus 49, and ML-DSA-87 to minus 50, on an in-tree, stack-optimised implementation of the FIPS 204 standard. The specific problem it solves is memory, and the solution is that the implementation streams matrix A rather than holding it, which is what lets even the largest category-5 parameter set fit on an RP2350. Two caveats are stated. Advertising the algorithms in getInfo is off by default, because some shipped browsers reject an unknown algorithm id outright, so enabling it is a deliberate act rather than the out-of-the-box state. And the text is careful that this is not a FIPS-validated module. Alongside it sit two features with a security flavour that are on: a seed backup that exports the FIDO master seed as BIP-39 or SLIP-39 words, and an at-rest soft-lock that keeps the seed in flash encrypted to a key only you hold.

Thirty workspace crates, with Embassy pinned to a branch

The Cargo workspace lists thirty members, and the names describe the decomposition: `firmware` and `rsk-wipe`, then crates for the SDK, filesystem, USB, crypto, FIDO, OpenPGP, RSA, EC, SHA-512, device configuration, management, OATH, OTP, PIV, rescue, vendor, the device itself, display, storage, LED, physical layer, UI, BIP-39, SLIP-39, ML-DSA and benchmarking. The dependency comment is the part worth reading, because it explains an unusual choice. The Embassy crates are all pinned to the same git source on the main branch rather than a published release, because embassy-rp's RP2350 support for the thumbv8m target has historically landed on main well ahead of any crates.io version. The comment then pre-empts the obvious objection: the exact commit is frozen in Cargo.lock and re-pinned by content hash for the Nix build, so tracking a branch names the source rather than creating a moving target, and nothing changes until someone deliberately runs a lockfile update.

formal/, fuzz/, supply-chain/ and deny.toml sit at the root

The repository layout is the clearest signal about how the project is run. Beyond the expected `firmware/`, `crates/`, `tests/`, `docs/` and `tools/` there are four directories that most firmware projects do not have: `formal/` for formal methods, `fuzz/` for fuzzing, `assurance/` for assurance work, and `supply-chain/` for supply chain material. Alongside them sit `deny.toml` for dependency and advisory checking, a `.gitleaks.toml` for secret scanning, a `flake.nix` with a matching `flake.lock` for a Nix build, `metadata/` for device metadata, `third_party/` for vendored code, and `book.toml` for an mdBook documentation site published at themaxmur.github.io/RS-Key. Governance is written down too, in `GOVERNANCE.md`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `COMPLIANCE.md` and `SECURITY.md`, and there are separate agent instruction files in `AGENTS.md`, `CLAUDE.md` and `CODEX.md`. Two CI workflows are advertised through badges, a standard one and one named deep-checks.

Editorial conclusion

RS-Key suits someone who wants a hardware authenticator to experiment with, to learn the applet protocols on, or to keep as a second key, since flashing is a file copy and the firmware speaks protocols their existing tooling already handles. It is not a replacement for a certified security key, and the project's own text says as much: no external audit, no secure element, and at-rest protection that only means anything once you fuse the OTP master key. Before you enrol anything real, read `docs/threat-model.md` and `docs/limitations.md` as the README instructs, then decide whether your threat model includes a funded lab, because the documented answer in that case is to buy a certified key. Also pick your image deliberately rather than grabbing the default, since the flash size determines which build fits.

Frequently asked questions

How do I flash RS-Key onto a Raspberry Pi RP2350?

Download the matching rs-key-<version>-default.uf2 from the releases page, hold the BOOT button while plugging the board in so a drive named RP2350 appears, and copy the file onto it. The board reboots as a security key. There is also a web flasher that can download, verify, sign and flash the firmware, but it requires a desktop Chromium-based browser.

Which RS-Key firmware image should I choose?

By flash size. Most 4 MB boards take default, 2 MB boards such as the Seeed XIAO RP2350 and Waveshare RP2350-Zero-CM take 2mb, 16 MB boards such as the TenStar RP2350-USB take 16mb, and the Waveshare RP2350-Touch-LCD-2.8 takes display. Ten further images are behaviour variants covering post-quantum algorithms, the FIPS profile, alwaysUv and PIN hardening.

Is RS-Key safe for real credentials?

The project describes itself as experimental and states it has had no external security audit, that the RP2350 is not a secure element, and that a stolen board is only as strong as the OTP and secure-boot hardening applied. The README says to read the threat model and limitations documents first, and that if your threat model includes a funded lab you should buy a certified key.

What does RS-Key support besides passkeys?

OpenPGP card 3.4 for gpg signing, decryption and authentication over EC and RSA; PIV for X.509 smart-card work through PKCS#11; OATH for TOTP and HOTP; and Yubico-style OTP with four slots plus a USB keyboard interface that types the code. It also exports the FIDO master seed as BIP-39 or SLIP-39 words and offers an at-rest soft-lock encrypting the seed to a key only you hold.

Official sources

  1. License: AGPL-3.0
  2. Project website
  3. README
  4. Releases
  5. TheMaxMur/RS-Key on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/themaxmur-rs-key.svg)](https://hysenlabs.com/projects/themaxmur-rs-key)