Skip to content

Add support for ssh-agent if that is installed on the system - #48

Open
snaggen wants to merge 1 commit into
pop-os:masterfrom
snaggen:ssh_agent
Open

Add support for ssh-agent if that is installed on the system#48
snaggen wants to merge 1 commit into
pop-os:masterfrom
snaggen:ssh_agent

Conversation

@snaggen

@snaggen snaggen commented Apr 18, 2024

Copy link
Copy Markdown
Contributor

This patch ensures we run an ssh-agent if it is found on the system.
Note that $SSH_AGENT is deliberately unquoted to expand to nothing if no agent is found on the system

Note that $SSH_AGENT is deliberately unquoted to expand
to nothing if no agent is found on the system
@Drakulix

Copy link
Copy Markdown
Member

I don't think this should be handled by cosmic-session explicitly. Rather we need support for xdg-autostart.

@snaggen

snaggen commented Apr 18, 2024

Copy link
Copy Markdown
Contributor Author

But the ssh-agent service will only be provided to it's children. So, everything that should be able to access the ssh-agent must be below it in the process tree.

If you run the ssh_agent as an auto-started process, then you would need to do some weird hack to read out the enviroment variable SSH_AUTH_SOCK and then propate that in some other weird way to other processes...

So, I think cosmic-session it the place for it.

@snaggen

snaggen commented Apr 18, 2024

Copy link
Copy Markdown
Contributor Author

Well, actually, you have a point that just running ssh-agent like this is not optimal. If you look at how gnome does it, they are wrapping the ssh-agent process with their keyring. Then the ssh-agent is started and pointed to a specific unix socket, but they still have to initialize that from gnome session (not directly like here, but by communicating over a control socket to the gnome-keyring daemon, which will run the ssh-agent and send the environment back over that socket), to be able to set and propagate the SSH_AUTH_SOCK environment variable to the user environment.

The benefit they get from doing this, is that they then can add all the keys to the agent automatically as soon as the keyring gets unlocked, and unload the keys when the keyring is locked. Also, if the keyring needs the password to load a key, they can provide modal dialogs in the UI for authentication.

So there are quite a few things that can be won by a more advanced solution, but you will probably still run in cosmic-session one way or another. And this solution here, can be seen as a simple placeholder until a more advanced solution with a ssh aware keyring is put in place. This solution still requires a user to run ssh-add to add the keys manually, but it is better than no support at all.

@jokeyrhyme

Copy link
Copy Markdown
Contributor

The way I solve this on my own systems is to read the SSH_AUTH_SOCK variable from the user service manager ( e.g. systemctl --user show-environment ) in my shell settings so that it's available in every new terminal session, and to start the agent (which is not always ssh-agent for me) when necessary, storing that value back into the user service manager ( e.g. systemctl --user set-environment )

Hard-coding ssh-agent into cosmic-session like this would not be compatible with the workflow I have on my systems, I'd much rather wait until there's a comprehensive/opinionated solution like gnome-keyring-daemon but for COSMIC

@lingmann

Copy link
Copy Markdown

As a temporary solution, I added this function to my .bashrc. This is currently being used on CachyOS (Arch-based) Linux distribution, but will likely work on other distros.

# Initialize SSH agent if needed
init_ssh_agent() {
  # Skip on macOS
  [[ $(uname -s) == "Darwin" ]] && return 0

  # Use XDG cache dir if set, otherwise fallback to ~/.cache
  local cache_dir="${XDG_CACHE_HOME:-$HOME/.cache}/ssh"
  local ssh_env="$cache_dir/agent-environment"
  local quiet=$1
  local ret=0

  # Ensure cache directory exists
  if ! mkdir -p "$cache_dir" 2>/dev/null; then
    echo "Error: Failed to create cache directory: $cache_dir" >&2
    return 1
  fi

  # Function to echo status (if not quiet)
  status_echo() {
    [[ -n "$quiet" ]] || echo "$@"
  }

  # Test if agent is running and accessible
  if [[ -f "$ssh_env" ]]; then
    if source "$ssh_env" >/dev/null; then
      if kill -0 "$SSH_AGENT_PID" 2>/dev/null; then
        if ssh-add -l &>/dev/null || [[ $? -eq 1 ]]; then
          status_echo "✓ ssh-agent is running (PID: $SSH_AGENT_PID)"
          return 0
        fi
      fi
    fi
  fi

  status_echo "→ Starting new ssh-agent..."

  # Start new agent and store environment
  if ! (umask 077 && ssh-agent -s >"$ssh_env"); then
    echo "Error: Failed to start ssh-agent" >&2
    return 1
  fi

  # shellcheck disable=SC1090
  source "$ssh_env" >/dev/null || {
    echo "Error: Failed to source ssh-agent environment" >&2
    return 1
  }

  # Update systemd environment if available
  if command -v systemctl >/dev/null && systemctl --user show-environment >/dev/null 2>&1; then
    if ! systemctl --user set-environment "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >/dev/null 2>&1; then
      status_echo "! Warning: Failed to update systemd environment"
      ret=1
    fi
  fi

  status_echo "✓ New ssh-agent started (PID: $SSH_AGENT_PID)"

  # Check for keys
  if ! ssh-add -l &>/dev/null; then
    if [[ $? -eq 1 ]]; then
      status_echo "! No SSH keys loaded (use 'ssh-add' to add keys)"
    else
      status_echo "! Error checking SSH keys"
      ret=1
    fi
  fi

  return $ret
}

# Initialize agent on shell startup (pass --quiet to suppress output)
init_ssh_agent

@WhyNotHugo

WhyNotHugo commented Jul 31, 2026

Copy link
Copy Markdown

The start-cosmic script re-execs itself running the user's shell as a login shell, so ~/.profile (or its equivalent) is sourced. ssh-agent (and similar tools) should be configured as usual through that mechanism.

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.

5 participants