Securing cargo publishing credentials

I'd suggest using PIV instead of U2F. It's supported by SoloKeys, as well as Yubikeys if you use this crate:

1 Like

Do you have links to some info on SoloKeys support for PIV? I have one but my understanding was that they were stateless FIDO2/U2F only, if they actually support other stateful protocols I'd be very interested in exploring storing certificates on it.

EDIT: Ok, tracked it down, it's supposed to be coming in v2, so that's still a few months away.

(I presume by PIV you are referring to FIPS-201 PIV? but just somehow using the primitives compatible devices expose rather than actual Federal Identification?)

Yep, sorry, should've mentioned SoloKeys support is forthcoming.

When it happens, SoloKeys and YubiKeys will share a few least-common-denominator algorithms, namely ECDSA/NIST P-256 for signatures. The Secure Enclave Processor on iOS and recent MacBook devices also supports ECDSA/NIST P-256 signatures via the iOS/macOS Keychain.

"Personal Identity Verification" (PIV) may sound prescriptive for identifying humans, but really it's a general purpose standard for storing things like asymmetric secret keys on "SmartCards" and other hardware tokens for the purposes of signing and encryption.

2 Likes

After reading this, I'll do cargo logout and only store my bearer token in my password manager. The token can be given to cargo publish with the --token option.

As I've explained above, it protects the token from being trivially stolen. This is thanks to macOS kernel establishing a chain of trust between a signed executable and the Keychain. Unlike cargo, which does not establish a chain of trust between itself and the helper.

Neither method protects against malicious program running cargo publish. So if you think protecting the token is pointless given that cargo publish is unprotected, why use the helper programs at all? They exist solely to protect the token, which they don't do well.

Stealing the token is easier and faster than abusing cargo publish, e.g. you can exfiltrate the token via a DNS request, even when publishing via TCP is firewalled. You need just a couple lines of Rust code to use unprotected credential helpers, which is easier to hide than more complex code that builds and publishes infected packages. Still, crates-io 2FA support would be great to protect publish too.

2 Likes

For what it's worth, I've contacted Apple about this in the past, specifically if it was possible to support delegated access to the macOS keychain, as it seems like establishing an X.509 codesigning certificate hierarchy for this (with usage constraints on the delegation) would be possible. That would allow a parent app the user is actually interacting with to sign a delegated codesigning certificate for a "helper" which could share keychain access for certain items.

One of their engineers suggested it would be a nice feature, but probably not something they'll work on any time soon. So unfortunately it seems if you want to use e.g. Keychain items (including SEP-backed ones which support neat stuff like biometric auth via TouchID) it seems that everything you need to do that must be linked into the parent executable (i.e. cargo in this case) for the foreseeable future.

2 Likes

See https://github.com/rust-lang/rfcs/pull/2947 for ongoing work in this area.