What's Actually Happening

You're trying to use a FIDO2 hardware security key (like a YubiKey) for SSH authentication, but the connection fails despite the key being properly configured. The key might not be detected, PIN prompts don't appear, or the server rejects the authentication attempt.

The Error You'll See

When attempting to connect:

bash
Enter PIN for 'YubiKey':
sign_and_send_pubkey: signing failed for ED25519-SK key from agent
user@server: Permission denied (publickey).

Or without agent:

bash
debug1: Offering public key: /home/user/.ssh/id_ed25519_sk ED25519-SK SHA256:xxx...
debug1: Server accepts key: pkalg ed25519-sk blen 64
debug1: sign hook for ED25519-SK key returned error -7
user@server: Permission denied (publickey).

Or the key simply isn't offered:

bash
debug1: Trying private key: /home/user/.ssh/id_ed25519_sk
debug1: no such identity: /home/user/.ssh/id_ed25519_sk: No such file or directory

Why This Happens

FIDO2 SSH keys require:

  1. 1.OpenSSH 8.2 or later on both client and server
  2. 2.Proper key type (ed25519-sk or ecdsa-sk)
  3. 3.Hardware key present and accessible
  4. 4.Correct permissions and configuration
  5. 5.For resident keys: the key must be loaded on the local machine

Error -7 typically indicates the hardware key isn't present or accessible. Other failures stem from version mismatches, incorrect key handling, or PIN verification issues.

Step 1: Verify OpenSSH Version

Check both client and server versions:

```bash # Client ssh -V

# Server ssh -V # when logged into the server ```

You need OpenSSH 8.2+ for FIDO2 support:

bash
OpenSSH_8.9p1 Ubuntu-3ubuntu0.1, OpenSSL 3.0.2 15 Mar 2022

On the server, also verify it accepts the key type:

bash
ssh -Q key-sig | grep sk

Should show:

bash
sk-ecdsa-sha2-nistp256@openssh.com
sk-ssh-ed25519@openssh.com

Step 2: Check Hardware Key Detection

Verify your FIDO2 key is detected:

bash
lsusb | grep -i yubi

Or for any FIDO device:

bash
ls -la /dev/hidraw*

Test with fido2-token:

bash
fido2-token -L

You should see your device listed. If not, check USB connection or try a different port.

Step 3: Verify Key Files Exist

FIDO2 keys have specific file extensions:

bash
ls -la ~/.ssh/id_*_sk*

You should see:

bash
-rw-------  1 user user  502 Apr  3 10:00 id_ed25519_sk
-rw-r--r--  1 user user  178 Apr  3 10:00 id_ed25519_sk.pub

If missing, you need to generate the key:

bash
ssh-keygen -t ed25519-sk -O resident -O verify-required -f ~/.ssh/id_ed25519_sk

The -O resident flag stores part of the key on the hardware device.

Step 4: Test Key Authentication Directly

Test the key without any agent:

bash
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_sk -v user@server

Watch for the PIN prompt. If it doesn't appear, the key may not be properly associated.

Step 5: Handle PIN Issues

If PIN prompts don't work in your environment, you may need to set SSH_ASKPASS:

bash
export SSH_ASKPASS=/usr/bin/ssh-askpass
ssh -i ~/.ssh/id_ed25519_sk user@server

For headless environments, you can use a helper:

```bash # Create a simple PIN entry script cat > ~/pin-helper.sh << 'EOF' #!/bin/bash echo "PIN: " >&2 read -s PIN echo "$PIN" EOF chmod +x ~/pin-helper.sh

SSH_ASKPASS=~/pin-helper.sh ssh -i ~/.ssh/id_ed25519_sk user@server ```

Step 6: Fix Agent Key Loading

If using SSH agent, load the FIDO2 key properly:

bash
ssh-add -K

The -K flag loads resident keys from your hardware device. Check loaded keys:

bash
ssh-add -L

You should see keys with ED25519-SK or ECDSA-SK types.

Step 7: Handle Resident Key Migration

If you generated a resident key on another machine, load it:

bash
# Download key handle from hardware token
ssh-keygen -K

This creates key files from the resident key stored on your FIDO2 device.

Step 8: Server-Side Configuration

Ensure the server accepts FIDO2 keys. Check sshd_config:

bash
grep PubkeyAcceptedAlgorithms /etc/ssh/sshd_config

It should include (or default to including):

bash
PubkeyAcceptedAlgorithms +sk-ecdsa-sha2-nistp256@openssh.com,sk-ssh-ed25519@openssh.com

Step 9: Test with Minimal Options

Isolate the issue by testing with minimal configuration:

bash
ssh -F /dev/null -i ~/.ssh/id_ed25519_sk -o IdentitiesOnly=yes -v user@server

This bypasses your regular config and uses only the specified key.

Verify the Fix

Your FIDO2 key is working when:

  1. 1.ssh-add -L shows your key with ED25519-SK or ECDSA-SK type
  2. 2.ssh -v user@server shows "Offering public key: ...sk..."
  3. 3.PIN prompt appears when connecting
  4. 4.Authentication succeeds after entering PIN

Create a test script to verify end-to-end:

bash
#!/bin/bash
echo "Testing FIDO2 SSH key authentication..."
ssh -o BatchMode=no -i ~/.ssh/id_ed25519_sk -v user@server 'echo "FIDO2 authentication successful!"'

The -o BatchMode=no ensures interactive prompts are allowed for PIN entry.