Skip to content

feat(yubikey): yk-status health checks; pubkey per-serial; remove yk-ssh-load#303

Merged
DevSecNinja merged 1 commit into
mainfrom
feat/yubikey-status-health-and-cleanup
May 4, 2026
Merged

feat(yubikey): yk-status health checks; pubkey per-serial; remove yk-ssh-load#303
DevSecNinja merged 1 commit into
mainfrom
feat/yubikey-status-health-and-cleanup

Conversation

@DevSecNinja

Copy link
Copy Markdown
Owner

Three follow-ups from continued macOS dogfooding plus a hard-removal.

1. yk-status: device-type heading + health checks

Output now leads with the device type (the most recognisable thing) and shows a per-device health checklist:

YubiKey 5C NFC FIPS  ·  serial 35984479  ·  fw 5.7.4  ·  FIPS
  Form factor:   Keychain (USB-C), NFC
  FIDO2 PIN:     [OK] set
  SSH key:       [OK] /Users/.../.ssh/id_ed25519_sk_35984479.pub

YubiKey 5C  ·  serial 30205443  ·  fw 5.4.3
  Form factor:   Keychain (USB-C)
  FIDO2 PIN:     [WARN] not set    (run `yk-enroll`)
  SSH key:       [WARN] not enrolled  (run `yk-enroll`)
  Note:          firmware <5.7 — some features (e.g. PIV ed25519) unavailable

PIN check uses the same robust regex as yk-enroll (handles legacy PIN is set and modern PIN: N attempt(s) remaining). SSH key check stats ~/.ssh/id_<type>_sk_<serial> + .pub. --json output gains pin_set and ssh_key fields. The fish version was missing device_type entirely — fully rewritten.

2. pubkey: discover per-serial key files

$ pubkey
No SSH public key found in ~/.ssh   ← even on a freshly-enrolled YubiKey

Was matching only the legacy un-suffixed id_<type>_sk.pub. yk-enroll writes id_<type>_sk_<serial>.pub. Now globs the per-serial pattern first, then legacy, then non-FIDO2. Bash + fish.

3. yk-ssh-load: hard-removed

Made obsolete by per-serial files being discovered via the SSH config glob (#298) — every key is IdentityFile-listed automatically. The old workflow (ssh-add -K to pull resident creds into the agent) is also actively incompatible with the new IdentitiesOnly yes posture from #302 (no agent caching for FIDO2 keys, since ssh-agent can't re-prompt for the FIDO2 PIN).

No deprecation period — per request:

  • home/dot_config/shell/functions/yk-ssh-load.sh — deleted
  • home/dot_config/fish/functions/yk_ssh_load.fish — deleted
  • tests/bash/yk-ssh-load.bats — deleted
  • References removed from home/private_dot_ssh/config.tmpl (comment) and docs/yubikey.md (Quick start, helpers table)

Verify

./tests/bash/run-tests.sh --test yk-status.bats --test yk-enroll.bats --test yk-ssh-new.bats

12 yk-status cases (fully rewritten), 18 yk-enroll, all yk-ssh-new — green. Full-suite failures are pre-existing and unrelated (sandbox has chezmoi 2.70.1 vs source state requiring 2.70.2).

Files

  • home/dot_config/shell/functions/yk-status.sh — health checks, device-type heading
  • home/dot_config/fish/functions/yk_status.fish — full rewrite (was missing device_type and health checks)
  • home/dot_config/shell/aliases.sh (pubkey) — globs per-serial files
  • home/dot_config/fish/conf.d/aliases.fish (pubkey) — same
  • home/dot_config/{shell,fish}/functions/yk{-,_}ssh{-,_}load.{sh,fish}deleted
  • tests/bash/yk-ssh-load.batsdeleted
  • tests/bash/yk-status.bats — fully rewritten (12 cases)
  • home/private_dot_ssh/config.tmplyk-ssh-load references removed
  • docs/yubikey.md — Quick start + helpers table updated, pubkey doc note refreshed

…ssh-load

Three follow-ups from continued macOS dogfooding plus a hard-removal:

1. yk-status: device-type heading + health checks.

   Output now leads with the device type (the most recognisable thing)

   and shows a per-device health checklist:

       YubiKey 5C NFC FIPS  ·  serial 35984479  ·  fw 5.7.4  ·  FIPS

         Form factor:   Keychain (USB-C), NFC

         FIDO2 PIN:     [OK] set

         SSH key:       [OK] ~/.ssh/id_ed25519_sk_35984479.pub

   PIN check uses the same robust regex as yk-enroll (handles legacy

   'PIN is set' and modern 'PIN: N attempt(s) remaining'). SSH key

   check stats ~/.ssh/id_<type>_sk_<serial> + .pub. JSON output gains

   pin_set and ssh_key fields. Fish version was missing device_type

   entirely \u2014 fully rewritten.

2. pubkey: discover per-serial key files.

   Was matching only the legacy un-suffixed id_<type>_sk.pub. yk-enroll

   writes id_<type>_sk_<serial>.pub, so 'pubkey' returned 'No SSH

   public key found in ~/.ssh' even on a freshly-enrolled YubiKey.

   Now globs the per-serial pattern first, then legacy, then non-FIDO2.

   Bash + fish.

3. yk-ssh-load: hard-removed.

   Made obsolete by per-serial files being discovered via the SSH

   config glob. The old workflow (ssh-add -K to pull resident creds

   into the agent) is incompatible with our new IdentitiesOnly-yes

   posture (no agent caching for FIDO2 keys). No deprecation period:

   helper deleted, bats deleted, references removed from SSH config

   template + docs.

Tests: yk-status.bats fully rewritten (12 cases), all green. yk-enroll

and yk-ssh-new tests untouched and still pass. Full suite has the

usual unrelated pre-existing failures (chezmoi 2.70.2 required, dev-

container has 2.70.1).
@DevSecNinja DevSecNinja marked this pull request as ready for review May 4, 2026 11:24
@DevSecNinja DevSecNinja merged commit 8c5dc13 into main May 4, 2026
19 checks passed
@DevSecNinja DevSecNinja deleted the feat/yubikey-status-health-and-cleanup branch May 4, 2026 11:24
DevSecNinja added a commit that referenced this pull request May 4, 2026
…I link, drop yk-ssh-load files

Four user-reported papercuts:

1. yk-status: switch to vertical layout.

   Heading was a horizontal dot-separated string (device type + serial

   + fw + FIPS marker), which was hard to scan. Now the device type

   is the heading and Serial / Firmware / FIPS / Form factor / FIDO2

   PIN / SSH key are vertical rows, one fact per line. Backticks in

   the warning messages dropped (showed as literal '\\`' in fish).

2. pubkey: fix zsh NOMATCH error.

   In zsh 'for x in ~/.ssh/id_ecdsa_sk_*.pub' aborts the function

   with 'no matches found' the moment one pattern doesn't match. Use

   find(1) for glob expansion so unmatched patterns just return empty.

3. GitHub Settings URL printed alongside every gh ssh-key add.

   Not everyone has gh installed and configured. Every nudge in

   yk-enroll, yk-ssh-new, yk-git-sign-setup and work-checklist now

   also points at https://github.com/settings/keys for the GUI flow.

   yk-git-sign-setup also got a missing --type authentication line.

4. .chezmoiremove for yk-ssh-load.

   When PR #303 deleted the yk-ssh-load source files, chezmoi did not

   remove the destination copies on apply (chezmoi only manages files

   in the source state; removed sources don't cascade to destination

   deletions). Add home/.chezmoiremove.tmpl listing both files so a

   plain 'chezmoi apply' cleans them up.

Tests: yk-status.bats updated for the vertical output (5 assertion

blocks). New pubkey.bats with 5 cases including a zsh NOMATCH

regression. yk-enroll.bats + work-checklist.bats now also assert

the GitHub Settings URL is printed. 51 cases green.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant