Repository: 99designs/aws-vault (language: go)

Issue:
Support for multiple yubikeys
As a user who has multiple Yubikeys plugged in at all times, I would like the ability to specify the serial of which Yubikey I want to use when executing the `ykman` prompt. 

By adding `--device 1234567` as arguments to the `ykman` command **prior** to the `oath` specific arguments, this works great for me, e.g.

`cmd := exec.Command("ykman", "--device", "1234567", "oath", "code", "--single", yubikeyOathCredName)`

I have very little Go experience and wouldn't even know where to begin to contribute such a feature back to this project, so I thought I would at least raise it here to see if the community sees value, and even better, someone could implement it into the code base!


Discussion / hints:

Fix patch:
diff --git a/prompt/ykman.go b/prompt/ykman.go
index 3538bbbc6..a9ce9463e 100644
--- a/prompt/ykman.go
+++ b/prompt/ykman.go
@@ -11,13 +11,25 @@ import (
 // YkmanProvider runs ykman to generate a OATH-TOTP token from the Yubikey device
 // To set up ykman, first run `ykman oath add`
 func YkmanMfaProvider(mfaSerial string) (string, error) {
+	args := []string{}
+
 	yubikeyOathCredName := os.Getenv("YKMAN_OATH_CREDENTIAL_NAME")
 	if yubikeyOathCredName == "" {
 		yubikeyOathCredName = mfaSerial
 	}
 
-	log.Printf("Fetching MFA code using `ykman oath code --single %s`", yubikeyOathCredName)
-	cmd := exec.Command("ykman", "oath", "code", "--single", yubikeyOathCredName)
+	// Get the serial number of the yubikey device to use.
+	yubikeyDeviceSerial := os.Getenv("YKMAN_OATH_DEVICE_SERIAL")
+	if yubikeyDeviceSerial != "" {
+		// If the env var was set, extend args to support passing the serial.
+		args = append(args, "--device", yubikeyDeviceSerial)
+	}
+
+	// Add the rest of the args as usual.
+	args = append(args, "oath", "code", "--single", yubikeyOathCredName)
+
+	log.Printf("Fetching MFA code using `ykman %s`", strings.Join(args, " "))
+	cmd := exec.Command("ykman", args...)
 	cmd.Stderr = os.Stderr
 
 	out, err := cmd.Output()


Test patch: