<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:xml="http://www.w3.org/XML/1998/namespace" xml:lang="en"><id>https://blog.luescher.io/</id><title type="text">blog.luescher.io</title><subtitle>Stephan Lüscher — CCIE-certified Network &amp; Automation Engineer.
Specializing in building scalable automation solutions, network engineering,
and cloud-native networking.</subtitle><link href="https://blog.luescher.io/" rel="self" type="application/atom+xml"/><link href="https://blog.luescher.io/" rel="alternate" type="text/html"/><generator uri="https://gohugo.io/" version="0.162.1">Hugo</generator><author><name>Stephan Lüscher</name></author><updated>2026-06-04T14:35:00+02:00</updated><entry><id>https://blog.luescher.io/2026/06/using-proton-pass-as-your-ssh-agent-a-secure-workflow/</id><title type="text">Using Proton Pass as Your SSH Agent: A Secure Workflow</title><link href="https://blog.luescher.io/2026/06/using-proton-pass-as-your-ssh-agent-a-secure-workflow/" rel="alternate" type="text/html"/><published>2026-06-04T14:35:00+02:00</published><updated>2026-06-04T14:35:00+02:00</updated><summary type="html"><![CDATA[<p><a href="https://proton.me/pass"  target="_blank" rel="noreferrer">Proton Pass</a> is a secure password manager that allows you to store and manage passwords, credentials, and SSH keys.
With <a href="https://protonpass.github.io/pass-cli/"  target="_blank" rel="noreferrer">Proton Pass CLI</a>, you can access your encrypted vaults directly from the command line, enabling
a secure and convenient SSH agent workflow on Linux.</p>]]></summary><category term="ssh"/><category term="proton-pass"/><category term="security"/><category term="linux"/><content type="html"><![CDATA[<p><a href="https://proton.me/pass"  target="_blank" rel="noreferrer">Proton Pass</a> is a secure password manager that allows you to store and manage passwords, credentials, and SSH keys.
With <a href="https://protonpass.github.io/pass-cli/"  target="_blank" rel="noreferrer">Proton Pass CLI</a>, you can access your encrypted vaults directly from the command line, enabling
a secure and convenient SSH agent workflow on Linux.</p>

<h2 class="relative group">What is an SSH Agent?
    <div id="what-is-an-ssh-agent" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#what-is-an-ssh-agent" aria-label="Anchor">#</a>
    </span>
    
</h2>
<blockquote><p>ssh-agent is a program to hold private keys used for public key authentication. Through use of environment variables the agent can be located
and automatically used for authentication when logging in to other machines using ssh.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>
</blockquote><p>In practice, this means you can add your SSH private keys to the agent, which then handles authentication for you. This is convenient, but managing
SSH keys across multiple systems can become cumbersome.</p>
<p>You either end up copying private keys to every machine, risking exposure if one system is compromised, or generating unique keys for each host,
which complicates access control and creates management overhead.</p>

<h2 class="relative group">Why Use Proton Pass as Your SSH Agent?
    <div id="why-use-proton-pass-as-your-ssh-agent" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#why-use-proton-pass-as-your-ssh-agent" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>Proton Pass solves these problems by centralizing your SSH key management.
Storing SSH keys in Proton Pass addresses these challenges:</p>
<ul>
<li><strong>Centralizing access</strong>: Your keys are stored in an encrypted vault, accessible from any device with Proton Pass CLI installed.</li>
<li><strong>Maintaining security</strong>: Proton Pass uses end-to-end encryption, ensuring only you can decrypt and use your keys.</li>
<li><strong>Simplifying workflows</strong>: The Proton Pass CLI can act as an SSH agent or load your stored keys into your existing agent, eliminating the need for manual key management.</li>
</ul>
<p>As the Proton Pass CLI documentation states:</p>
<blockquote><p>The Proton Pass CLI integrates nicely with any existing SSH workflows. It can either act as a SSH agent, or load your Pass-stored SSH keys into
your already existing SSH agent.<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
</blockquote>
<h2 class="relative group">Prerequisites
    <div id="prerequisites" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#prerequisites" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>To manage your SSH keys with Proton Pass, you’ll need:</p>
<ul>
<li>A Proton Pass <a href="https://account.proton.me/pass/dashboard"  target="_blank" rel="noreferrer">account</a></li>
<li>The Proton Pass CLI <a href="https://protonpass.github.io/pass-cli/get-started/installation/"  target="_blank" rel="noreferrer">installed</a> on your system.</li>
</ul>

<h2 class="relative group">SSH Key Management
    <div id="ssh-key-management" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ssh-key-management" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>SSH keys can be added to Proton Pass using the <code>pass-cli</code> command-line tool. To get started, you need to log in to Proton Pass first:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pass-cli login</span></span></code></pre></div></div>
<p>This will start a <a href="https://protonpass.github.io/pass-cli/commands/login/#web-login"  target="_blank" rel="noreferrer">web login</a> process where you can enter your Proton Pass credentials.
Once authenticated, you can add existing SSH keys or create new ones.</p>

<h3 class="relative group">Creating a dedicated vault
    <div id="creating-a-dedicated-vault" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#creating-a-dedicated-vault" aria-label="Anchor">#</a>
    </span>
    
</h3>
<p>Depending on your needs, you may want to create a dedicated <a href="https://proton.me/support/pass-vault"  target="_blank" rel="noreferrer">vault</a> for your SSH keys.</p>
<blockquote><p>A vault is an encrypted digital container that holds your items.<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
</blockquote><p>Vaults can be shared with other users or simply serve as an organizational unit. I don’t recommend sharing your SSH keys vault with others.
SSH keys should always be kept private and not shared.</p>
<p>Creating a new vault with <a href="https://protonpass.github.io/pass-cli/commands/vault/#create"  target="_blank" rel="noreferrer">pass-cli</a> is easy:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli vault create --name SSH-Keys</span></span></code></pre></div></div>

<h3 class="relative group">Create or import SSH keys
    <div id="create-or-import-ssh-keys" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#create-or-import-ssh-keys" aria-label="Anchor">#</a>
    </span>
    
</h3>
<p>After creating the vault, you can add your SSH keys.</p>

<h4 class="relative group">Importing existing SSH keys
    <div id="importing-existing-ssh-keys" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#importing-existing-ssh-keys" aria-label="Anchor">#</a>
    </span>
    
</h4>
<p>To <a href="https://protonpass.github.io/pass-cli/commands/item/#create-ssh-key-import"  target="_blank" rel="noreferrer">import</a> existing SSH keys, you can use the following command:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli item create ssh-key import <span class="se">\
</span></span></span><span class="line"><span class="cl">    --from-private-key <span class="s2">&#34;~/.ssh/auth_codeberg&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --vault-name <span class="s2">&#34;SSH-Keys&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --title <span class="s2">&#34;auth_codeberg.org&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --password</span></span></code></pre></div></div>

<h4 class="relative group">Generating a new SSH key
    <div id="generating-a-new-ssh-key" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#generating-a-new-ssh-key" aria-label="Anchor">#</a>
    </span>
    
</h4>
<p>Instead of importing you can directly <a href="https://protonpass.github.io/pass-cli/commands/item/#create-ssh-key-generate"  target="_blank" rel="noreferrer">generate</a>
a new SSH key with the following command:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli item create ssh-key generate <span class="se">\
</span></span></span><span class="line"><span class="cl">    --vault-name <span class="s2">&#34;SSH-Keys&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    --title <span class="s2">&#34;auth_codeberg.org&#34;</span></span></span></code></pre></div></div>

<h2 class="relative group">Using the SSH Agent
    <div id="using-the-ssh-agent" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#using-the-ssh-agent" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>Now that your SSH keys are stored in Proton Pass, you can use the SSH agent to <a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/#ssh-agent-integration"  target="_blank" rel="noreferrer">integrate</a>
them.</p>

<h3 class="relative group">Load SSH keys into your existing SSH agent
    <div id="load-ssh-keys-into-your-existing-ssh-agent" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#load-ssh-keys-into-your-existing-ssh-agent" aria-label="Anchor">#</a>
    </span>
    
</h3>
<p>If you’re already using an ssh-agent, you can <a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/#ssh-agent-integration"  target="_blank" rel="noreferrer">load</a>
your Proton Pass SSH keys into it:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli ssh-agent load --vault-name <span class="s2">&#34;SSH-Keys&#34;</span></span></span></code></pre></div></div>

<h3 class="relative group">Use Proton Pass CLI as your SSH agent
    <div id="use-proton-pass-cli-as-your-ssh-agent" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#use-proton-pass-cli-as-your-ssh-agent" aria-label="Anchor">#</a>
    </span>
    
</h3>
<p>Alternatively, Proton Pass CLI can also <a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/#proton-pass-cli-as-your-ssh-agent"  target="_blank" rel="noreferrer">act as a SSH agent</a> itself.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli ssh-agent start --vault-name <span class="s2">&#34;SSH-Keys&#34;</span></span></span></code></pre></div></div>
<p>After it starts, you’ll see output similar to the following, with instructions on how to use the new agent:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">SSH agent started successfully!
</span></span><span class="line"><span class="cl">To use this agent, run:
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/Users/youruser/.ssh/proton-pass-agent.sock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Keys will refresh automatically every <span class="m">3600</span> seconds <span class="o">(</span><span class="m">1</span> hour<span class="o">)</span>.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Press Ctrl+C to stop the agent.</span></span></code></pre></div></div>

<h3 class="relative group">Running the SSH agent as a background daemon
    <div id="running-the-ssh-agent-as-a-background-daemon" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#running-the-ssh-agent-as-a-background-daemon" aria-label="Anchor">#</a>
    </span>
    
</h3>
<p>The Proton Pass SSH agent can also run in the <a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/#running-the-ssh-agent-as-a-background-daemon"  target="_blank" rel="noreferrer">background</a>
without keeping a terminal open.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli ssh-agent daemon start --vault-name <span class="s2">&#34;SSH-Keys&#34;</span></span></span></code></pre></div></div>
<p>Once it’s running, you can check the status with:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli ssh-agent daemon status</span></span></code></pre></div></div>
<p>Similar to <code>pass-cli ssh-agent start</code>, it will output information about the <code>SSH_AUTH_SOCK</code> environment variable, which you must set in your shell configuration to use the agent.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">Status:   running
</span></span><span class="line"><span class="cl">PID:      <span class="m">12345</span>
</span></span><span class="line"><span class="cl">Socket:   /home/youruser/.ssh/proton-pass-agent.sock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">To connect to the agent, <span class="nb">set</span> SSH_AUTH_SOCK:
</span></span><span class="line"><span class="cl">  <span class="nb">export</span> <span class="nv">SSH_AUTH_SOCK</span><span class="o">=</span>/home/youruser/.ssh/proton-pass-agent.sock
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">PID file: /home/youruser/.ssh/proton-pass-agent.pid</span></span></code></pre></div></div>
<p>The daemon does not modify your shell environment, so you need to <a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/#setting-ssh_auth_sock-automatically-on-login"  target="_blank" rel="noreferrer">set</a>
<code>SSH_AUTH_SOCK</code> yourself in <code>~/.bashrc</code> or <code>~/.zshrc</code>.</p>

<h2 class="relative group">SSH Config
    <div id="ssh-config" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#ssh-config" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>Now that your SSH agent is running, you can start using your SSH keys. However, you need to configure the SSH client.
Otherwise, you might need to use complicated commands like:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">ssh -o <span class="s2">&#34;IdentityAgent=</span><span class="si">${</span><span class="nv">SSH_AUTH_SOCK</span><span class="si">}</span><span class="s2">&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -o <span class="s2">&#34;IdentitiesOnly=yes&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    -i <span class="s2">&#34;~/.ssh/auth_codeberg.org.pub&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    git@codeberg.org</span></span></code></pre></div></div>
<p>To simplify this, add the following to your <code>~/.ssh/config</code> file<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>:</p>
<div class="highlight-wrapper"><pre tabindex="0"><code class="language-conf" data-lang="conf"># Proton pass-cli SSH agent integration
Host *
    User %u
    IdentityAgent &#34;${SSH_AUTH_SOCK}&#34;
    IdentitiesOnly yes
    IdentityFile ~/.ssh/auth_%h.pub</code></pre></div>
<p>This will set the following defaults for all SSH connections:</p>
<ul>
<li>
<p><code>User %u</code></p>
<p>Dynamically sets the remote username to match your current local system username unless explicitly overridden.</p>
</li>
<li>
<p><code>IdentityAgent ${SSH_AUTH_SOCK}</code></p>
<p>Forces the SSH client to route all authentication requests through the active Proton Pass CLI agent socket defined in your environment variables.</p>
</li>
<li>
<p><code>IdentitiesOnly yes</code></p>
<p>Restricts the client to only offer keys explicitly specified by the <code>IdentityFile</code> directive.
This prevents the server from rejecting your connection due to &ldquo;too many authentication failures&rdquo; caused by the agent trying unrelated keys.</p>
</li>
<li>
<p><code>IdentityFile ~/.ssh/auth_%h.pub</code></p>
<p>Points to a local copy of your public key. The SSH client reads this public key file, extracts its unique fingerprint, and asks the Proton Pass
agent to sign the challenge using the matching private key stored in your secure vault.
The <code>%h</code> placeholder will be replaced with the hostname of the remote server. For example: if you run <code>ssh git@codeberg.org</code>, the IdentityFile
will render to: <code>~/.ssh/auth_codeberg.org.pub</code></p>
</li>
</ul>
<p>You might wonder: since we have the SSH key in Proton Pass, how do we get the public keys to <code>~/.ssh/</code>?</p>
<p>We can export it with:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">pass-cli item view --vault-name <span class="s2">&#34;SSH-Keys&#34;</span> --item-title auth_codeberg --field <span class="s2">&#34;public_key&#34;</span> &gt;<span class="s2">&#34;~/.ssh/auth_codeberg.pub&#34;</span></span></span></code></pre></div></div>
<p>With all of this in place, you can now simply use:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">ssh git@codeberg.org</span></span></code></pre></div></div>

<h2 class="relative group">My Custom Proton Pass SSH Agent Integration
    <div id="my-custom-proton-pass-ssh-agent-integration" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#my-custom-proton-pass-ssh-agent-integration" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>By now, you might be thinking: <em>This involves a lot of configuration steps.</em> Manually starting the SSH agent from the CLI every time and ensuring all
public keys are exported to <code>~/.ssh/</code> is far from convenient.</p>
<p>To reduce friction and make this workflow smoother, I’ve created a script and systemd service to automate everything:
<a href="https://codeberg.org/tepene/proton-pass-ssh-agent"  target="_blank" rel="noreferrer">https://codeberg.org/tepene/proton-pass-ssh-agent</a></p>
<p>Once set up, you can:</p>
<ul>
<li>Start the Proton Pass CLI authentication process</li>
<li>Start the Proton Pass SSH Agent</li>
<li>Export all SSH public keys from your vault to <code>~/.ssh/</code></li>
</ul>
<p>Installation and usage are documented in the <a href="https://codeberg.org/tepene/proton-pass-ssh-agent/src/branch/main/README.md"  target="_blank" rel="noreferrer">README</a>.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://man7.org/linux/man-pages/man1/ssh-agent.1.html"  target="_blank" rel="noreferrer">ssh-agent - Linux man page</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a href="https://protonpass.github.io/pass-cli/commands/ssh-agent/"  target="_blank" rel="noreferrer">ssh-agent - pass-cli documentation</a>&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a href="https://proton.me/support/pass-vault"  target="_blank" rel="noreferrer">proton pass - what is a vault</a>&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p><a href="https://man7.org/linux/man-pages/man5/ssh_config.5.html"  target="_blank" rel="noreferrer">ssh_config - Linux man page</a>&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>]]></content></entry></feed>