{ config, lib, pkgs, ... }: with lib; let cfg = config.programs.onepassword; generateAgentConfig = keys: let keyToToml = key: let lines = [ "[[ssh-keys]]" ] ++ optional (key.item != null) ''item = "${key.item}"'' ++ optional (key.vault != null) ''vault = "${key.vault}"'' ++ [ ''account = "${key.account}"'' ]; in concatStringsSep "\n" lines; in concatStringsSep "\n\n" (map keyToToml keys); home = config.home.homeDirectory; darwinSockPath = "${home}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"; defaultSockPath = ".1password/agent.sock"; in { options.programs.onepassword = { enable = mkEnableOption "1Password CLI and SSH agent integration"; package = mkOption { type = types.package; default = pkgs._1password-cli; description = "The 1Password CLI package to use."; }; socketPath = mkOption { type = types.str; default = defaultSockPath; description = "Relative path from home directory for the SSH agent socket."; example = ".1password/agent.sock"; }; darwinSocketPath = mkOption { type = types.str; default = darwinSockPath; description = "Full path to the 1Password agent socket on macOS."; }; setSshAuthSock = mkOption { type = types.bool; default = true; description = "Whether to set the SSH_AUTH_SOCK environment variable."; }; configureSshClient = mkOption { type = types.bool; default = true; description = "Whether to configure the SSH client to use 1Password agent."; }; fishIntegration = mkOption { type = types.bool; default = false; description = "Enable fish shell completion for 1Password CLI."; }; sshKeys = mkOption { type = with types; listOf (submodule { options = { item = mkOption { type = nullOr str; default = null; description = "The name of the SSH key item in 1Password."; example = "Git Signing Key"; }; vault = mkOption { type = nullOr str; default = null; description = "The vault name where the SSH key is stored (optional)."; example = "Private"; }; account = mkOption { type = str; default = "my.1password.com"; description = "The 1Password account identifier."; example = "my.1password.com"; }; }; }); default = [ ]; description = "SSH keys configuration for 1Password agent. Lists from multiple configurations will be merged."; example = [ { account = "my.1password.com"; } { item = "Git Signing Key"; vault = "Work"; account = "ACME, Inc."; } { item = "Personal SSH Key"; account = "my.1password.com"; } ]; }; }; config = mkIf cfg.enable { home.packages = [ cfg.package ]; home.sessionVariables = mkIf cfg.setSshAuthSock { SSH_AUTH_SOCK = "${home}/${cfg.socketPath}"; }; # Create symlink to Darwin socket (macOS specific) home.file."${cfg.socketPath}" = mkIf pkgs.stdenv.isDarwin { source = config.lib.file.mkOutOfStoreSymlink cfg.darwinSocketPath; }; # Configure SSH client programs.ssh = mkIf cfg.configureSshClient { extraConfig = "IdentityAgent ~/${cfg.socketPath}"; }; # Fish shell integration programs.fish = mkIf cfg.fishIntegration { interactiveShellInit = '' op completion fish | source ''; }; # Generate SSH agent configuration home.file.".config/1Password/ssh/agent.toml" = mkIf (cfg.sshKeys != [ ]) { text = generateAgentConfig cfg.sshKeys; }; }; }