Commit f519e2e5991e

Vincent Demeester <vincent@sbr.pm>
2026-06-11 12:55:55
feat(aomi): add ssh-tpm-agent as front agent proxying FIDO2
Run ssh-tpm-agent socket-activated as the primary SSH_AUTH_SOCK, serving the machine-bound TPM SSH key and proxying the existing FIDO2 ssh-agent via -A so one socket exposes both the TPM key and the sk-keys.
1 parent 65ef4bc
Changed files (1)
home
common
home/common/shell/openssh.nix
@@ -22,16 +22,48 @@ in
     ]
     # aomi is Fedora (no NixOS programs.ssh.startAgent); provide a GTK askpass
     # so FIDO2 sk-key PIN prompts work with the home-manager ssh-agent.
-    ++ lib.optionals isAomi [ openssh-askpass ];
+    ++ lib.optionals isAomi [
+      openssh-askpass
+      ssh-tpm-agent
+    ];
 
   # NixOS hosts use programs.ssh.startAgent (proper SSH_ASKPASS for FIDO2).
   # aomi has no NixOS layer, so run a home-manager systemd user ssh-agent.
   services.ssh-agent.enable = isAomi;
 
+  # aomi: ssh-tpm-agent is the *front* agent. It serves the machine-bound TPM
+  # SSH key and proxies (-A) the FIDO2 ssh-agent above for fallback, so a single
+  # socket (SSH_AUTH_SOCK) exposes both the TPM key and all FIDO2 sk-keys.
+  systemd.user.sockets.ssh-tpm-agent = lib.mkIf isAomi {
+    Unit.Description = "SSH TPM agent socket";
+    Socket = {
+      ListenStream = "%t/ssh-tpm-agent.sock";
+      SocketMode = "0600";
+      Service = "ssh-tpm-agent.service";
+    };
+    Install.WantedBy = [ "sockets.target" ];
+  };
+  systemd.user.services.ssh-tpm-agent = lib.mkIf isAomi {
+    Unit = {
+      Description = "ssh-tpm-agent service";
+      Requires = [ "ssh-tpm-agent.socket" ];
+      After = [ "ssh-agent.service" ];
+    };
+    Service = {
+      Environment = "SSH_TPM_AUTH_SOCK=%t/ssh-tpm-agent.sock";
+      # Proxy the FIDO2 ssh-agent socket for key-lookup fallback.
+      ExecStart = "${pkgs.ssh-tpm-agent}/bin/ssh-tpm-agent -A %t/ssh-agent";
+      SuccessExitStatus = 2;
+      Type = "simple";
+    };
+  };
+
   # FIDO2 sk-keys spawn ssh-sk-helper which needs an askpass for the PIN.
   home.sessionVariables = lib.mkIf isAomi {
     SSH_ASKPASS = "${pkgs.openssh-askpass}/libexec/gtk-ssh-askpass";
     SSH_ASKPASS_REQUIRE = "prefer";
+    # Route ssh through the front ssh-tpm-agent (TPM key + proxied FIDO2 keys).
+    SSH_AUTH_SOCK = lib.mkForce "$XDG_RUNTIME_DIR/ssh-tpm-agent.sock";
   };
   programs.ssh = {
     enable = true;