What's Actually Happening

You've set up SSH certificate authentication to eliminate individual key management, but authentication fails. The server has a trusted CA key configured, you have a signed user certificate, but the connection is rejected. Certificate authentication is powerful but complex, and failures can occur at multiple points.

The Error You'll See

Connection attempts fail with:

bash
user@server: Permission denied (publickey).

In verbose mode:

bash
ssh -v user@server

You might see:

bash
debug1: Offering public key: /home/user/.ssh/id_rsa-cert RSA-CERT SHA256:xxx
debug1: Server accepts key: pkalg rsa-sha2-512-cert blen 1234
debug1: Certificate invalid: not a valid principal

Or:

bash
debug1: Offering public key: /home/user/.ssh/id_rsa-cert RSA-CERT SHA256:xxx
debug1: Server refuses key: signature unverified

Or certificate expiration:

bash
debug1: certificate invalid: certificate has expired

Why This Happens

SSH certificate authentication requires everything to align:

  1. 1.The server must trust the CA public key that signed your certificate
  2. 2.Your certificate must not be expired
  3. 3.Your username must be in the certificate's principals list
  4. 4.The certificate must be signed correctly
  5. 5.The certificate file must be in the correct location

A failure at any point causes authentication rejection.

Step 1: Verify Certificate File Location

SSH automatically looks for a certificate file next to your private key:

bash
ls -la ~/.ssh/id_rsa*

You should see:

bash
-rw-------  1 user user 1766 Apr  3 10:00 id_rsa
-rw-r--r--  1 user user  400 Apr  3 10:00 id_rsa.pub
-rw-r--r--  1 user user 1456 Apr  3 10:00 id_rsa-cert.pub

The certificate must be named id_rsa-cert.pub (matching your key name with -cert.pub appended).

Step 2: Inspect Your Certificate

Check certificate validity and contents:

bash
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub

Output shows:

bash
Type: ssh-rsa-cert-v01@openssh.com user certificate
Public key: RSA-CERT SHA256:xxx
Signing CA: RSA SHA256:yyy
Key ID: "user@host"
Serial: 1234567890
Valid: from 2026-04-01T00:00:00 to 2026-04-08T00:00:00
Principals:
    user
    admin
Critical Options: (none)
Extensions:
    permit-X11-forwarding
    permit-agent-forwarding
    permit-port-forwarding
    permit-pty
    permit-user-rc

Check these critical items:

  • Valid: Certificate hasn't expired
  • Principals: Your username is listed
  • Key ID: Identifies this certificate

Step 3: Check Certificate Expiration

If the certificate has expired:

bash
date
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub | grep Valid

Compare the current date with the validity period. You'll need to request a new certificate if expired.

When generating certificates, use appropriate validity:

bash
# On the CA host - sign with longer validity
ssh-keygen -s ca_key -I user@host -n user -V +1w id_rsa.pub

Step 4: Verify Principal Mapping

Your local username must match a principal in the certificate:

bash
whoami
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub | grep -A5 Principals

If your username doesn't match any principal, you can either:

  1. 1.Connect as a principal that exists:
bash
ssh principal-user@server
  1. 1.Request a new certificate with your username added

Step 5: Check Server Trust Configuration

On the server, verify the CA is trusted:

bash
grep TrustedUserCAKeys /etc/ssh/sshd_config

Should show:

bash
TrustedUserCAKeys /etc/ssh/user_ca.pub

Check that the CA public key exists:

bash
ls -la /etc/ssh/user_ca.pub
cat /etc/ssh/user_ca.pub

Compare this to the signing CA in your certificate:

bash
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub | grep "Signing CA"

The fingerprints must match.

Step 6: Verify Certificate Signature

The certificate must be signed by the CA whose public key is on the server:

```bash # Get CA public key fingerprint from server ssh-keygen -l -f /etc/ssh/user_ca.pub

# Get signing CA fingerprint from certificate ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub | grep "Signing CA" ```

These fingerprints should match.

Step 7: Check Certificate Type

Ensure you have a user certificate, not a host certificate:

bash
ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub | head -1

Should show:

bash
Type: ssh-rsa-cert-v01@openssh.com user certificate

Not "host certificate".

Step 8: Test with Debug Mode

Run with maximum verbosity to see the failure point:

bash
ssh -vvv -o IdentitiesOnly=yes -i ~/.ssh/id_rsa user@server 2>&1 | grep -i cert

Look for:

  • Offering public key: ...-cert - Certificate is being offered
  • Server accepts key or Server refuses key - Server's response
  • Certificate invalid: - Specific rejection reason

Step 9: Regenerate Certificate if Needed

If the certificate has issues, request a new one from your CA administrator:

```bash # User sends public key to CA scp ~/.ssh/id_rsa.pub ca-admin@ca-server:/tmp/

# CA signs the certificate ssh-keygen -s ~/.ssh/ca_key \ -I "user@workstation" \ -n "username,admin" \ -V +52w \ /tmp/id_rsa.pub

# CA returns certificate to user scp ca-admin@ca-server:/tmp/id_rsa-cert.pub ~/.ssh/ ```

Step 10: Check for Conflicting Keys

If you have both a certificate and regular keys, SSH might offer the wrong one:

bash
ssh-add -L

If the agent has regular keys loaded, SSH might prefer them. Clear and reload:

bash
ssh-add -D  # Clear all keys
ssh-add ~/.ssh/id_rsa  # Load key with certificate

Verify the Fix

Certificate authentication works when:

  1. 1.ssh-keygen -L shows a valid, unexpired certificate
  2. 2.Your username appears in the principals list
  3. 3.The server's TrustedUserCAKeys matches your certificate's signing CA
  4. 4.ssh -v shows the certificate being accepted

Test with a clean connection:

bash
ssh -o IdentityAgent=none -i ~/.ssh/id_rsa -v user@server 'echo "Certificate auth works"'