Skip to content

feat(ssh): manage ~/.ssh/config as a mise template - #90

Merged
djgoku merged 1 commit into
mainfrom
feat/ssh-config-template
Aug 23, 2026
Merged

feat(ssh): manage ~/.ssh/config as a mise template#90
djgoku merged 1 commit into
mainfrom
feat/ssh-config-template

Conversation

@djgoku

@djgoku djgoku commented Aug 23, 2026

Copy link
Copy Markdown
Owner

The YubiKey ed25519-sk key needs ControlMaster multiplexing to be usable: without a live master every connection re-authenticates, and each of those is a physical touch. That block was being appended by a one-off task, which meant it existed only on machines where the task had been run.

Templates own the whole destination -- tera renders output and never reads the target, so there is no way to manage only a region of a file. Hand-added hosts therefore move to ~/.ssh/config.local, which the template pulls in with exec(). That file is unmanaged and survives re-renders; the tradeoff is that editing it needs mise bootstrap dotfiles apply '~/.ssh/config'. It is included first, since ssh takes the first value it sees for each option and a local entry should be able to override the managed one.

~/.ssh and ~/.ssh/cm are declared in [bootstrap.directories]: ssh will not create the ControlPath directory, and without it there is no multiplexing at all -- silently back to a touch per connection.

Also documents conda:openssh. Apple's /usr/bin/ssh is built without FIDO support and silently ignores sk keys ("no SecurityKeyProvider has been specified"), failing with "Permission denied (publickey)".

The post-tools hook now resolves gpgconf through mise exec. mise bootstrap --yes on a fresh machine died with "sh: line 2: gpgconf: command not found": that hook shell inherits the PATH computed before the tools stage installed conda:gnupg, the same ordering trap mise which hits at the dotfiles stage. Left unguarded by || true on purpose -- if gnupg is installed and gpgconf still fails, that should fail the stage. No YubiKey-presence check either: gpg-agent starts fine with no card inserted, and scdaemon only touches the card when an operation needs it.

The YubiKey ed25519-sk key needs ControlMaster multiplexing to be usable:
without a live master every connection re-authenticates, and each of those is
a physical touch. That block was being appended by a one-off task, which meant
it existed only on machines where the task had been run.

Templates own the whole destination -- tera renders output and never reads the
target, so there is no way to manage only a region of a file. Hand-added hosts
therefore move to ~/.ssh/config.local, which the template pulls in with
exec(). That file is unmanaged and survives re-renders; the tradeoff is that
editing it needs `mise bootstrap dotfiles apply '~/.ssh/config'`. It is
included first, since ssh takes the first value it sees for each option and a
local entry should be able to override the managed one.

~/.ssh and ~/.ssh/cm are declared in [bootstrap.directories]: ssh will not
create the ControlPath directory, and without it there is no multiplexing at
all -- silently back to a touch per connection.

Also documents conda:openssh. Apple's /usr/bin/ssh is built without FIDO
support and silently ignores sk keys ("no SecurityKeyProvider has been
specified"), failing with "Permission denied (publickey)".

The post-tools hook now resolves gpgconf through `mise exec`. `mise bootstrap
--yes` on a fresh machine died with "sh: line 2: gpgconf: command not found":
that hook shell inherits the PATH computed before the tools stage installed
conda:gnupg, the same ordering trap `mise which` hits at the dotfiles stage.
Left unguarded by `|| true` on purpose -- if gnupg is installed and gpgconf
still fails, that should fail the stage. No YubiKey-presence check either:
gpg-agent starts fine with no card inserted, and scdaemon only touches the
card when an operation needs it.
@djgoku
djgoku merged commit f16f1fe into main Aug 23, 2026
2 checks passed
@djgoku
djgoku deleted the feat/ssh-config-template branch August 23, 2026 05:32
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