> ## Documentation Index
> Fetch the complete documentation index at: https://www.1password.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SSH agent forwarding with 1Password

export const CodeResult = ({children, resultLang, wrap, expandable}) => {
  const parseChildren = () => {
    let language = "text";
    let codeContent = "";
    const extractText = node => {
      if (typeof node === "string") {
        return node;
      }
      if (Array.isArray(node)) {
        return node.map(extractText).join("");
      }
      if (node?.props?.children) {
        return extractText(node.props.children);
      }
      return "";
    };
    const extractLanguage = node => {
      if (!node) return null;
      if (node.props?.className) {
        const className = node.props.className;
        const langMatch = className.match(/language-(\w+)/);
        if (langMatch) {
          return langMatch[1];
        }
      }
      if (node.props?.["data-language"]) {
        return node.props["data-language"];
      }
      if (node.props?.language) {
        return node.props.language;
      }
      return null;
    };
    if (typeof children === "string") {
      codeContent = children;
    } else if (Array.isArray(children)) {
      codeContent = extractText(children);
      for (const child of children) {
        const detectedLang = extractLanguage(child);
        if (detectedLang) {
          language = detectedLang;
          break;
        }
      }
    } else if (children?.props) {
      const detectedLang = extractLanguage(children);
      if (detectedLang) {
        language = detectedLang;
      }
      codeContent = extractText(children);
    }
    const parts = codeContent.split("#code-result");
    if (parts.length < 2) {
      return {
        command: codeContent.trim(),
        result: null,
        language,
        defaultOpen: false
      };
    }
    const resultText = parts[1].trim();
    const defaultOpen = resultText.startsWith("open");
    const cleanResult = defaultOpen ? resultText.slice(4).trim() : resultText;
    return {
      command: parts[0].trim(),
      result: cleanResult,
      language,
      defaultOpen
    };
  };
  const {command, result, language, defaultOpen} = parseChildren();
  const [isOpen, setIsOpen] = useState(defaultOpen);
  if (!result) {
    return children;
  }
  return <div className="codeblock_accordion not-prose mb-4">
      {}
      <div className="[&>*]:!mb-0 [&>*]:!rounded-b-none">
        <CodeBlock language={language} children={command} wrap={wrap} expandable={expandable} />
      </div>

      {}
      <div className="see_results_container border-t-0 bg-gray-100/80 dark:bg-gray-800/80 overflow-hidden" style={{
    marginTop: "-0.25rem"
  }}>
        <button onClick={() => setIsOpen(!isOpen)} className="w-full px-4 py-2.5 flex items-center gap-1 text-left text-[14px] font-medium text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 hover:bg-gray-200/60 dark:hover:bg-gray-700/60 transition-all duration-150" aria-expanded={isOpen}>
          {isOpen ? <Icon icon="caret-down" size="14" iconType="solid" /> : <Icon icon="caret-right" size="14" iconType="solid" />}

          <span>See result...</span>
        </button>

        {isOpen && <div className="[&>*]:!mt-0 [&>*]:!rounded-t-none border-t border-[var(--op-border-ui)] dark:border-[var(--op-border-ui-dark)]">
            <CodeBlock language={resultLang || language} children={result} wrap={wrap} expandable={expandable} />
          </div>}
      </div>
    </div>;
};

export const CodeWrapper = ({variant, children}) => {
  const variantStyles = {
    bad: "[&_.code-block-background]:!mint-bg-red-100 [&_.code-block-background]:dark:!mint-bg-red-950/50",
    good: "[&_.code-block-background]:!mint-bg-green-100 [&_.code-block-background]:dark:!mint-bg-green-950/50"
  };
  const appliedStyles = variant ? variantStyles[variant] : "";
  return <div className={`coloredCodeWrapper ${appliedStyles}`}>{children}</div>;
};

SSH agent forwarding lets you make SSH requests within a remote environment as if it were your local machine, like running Git commands and signing commits from a [cloud development environment](#cde) or [remote workstation](#remote-workstation).

Instead of storing your private keys on the remote host, you can use SSH agent forwarding to forward your requests to your local 1Password SSH Agent. Then authorize the request with biometrics without your private keys ever leaving the local 1Password process.

## Requirements

1. [Sign up for 1Password.](https://1password.com/pricing/password-manager)
2. Install and sign in to 1Password for [Mac](https://1password.com/downloads/mac) or [Linux](https://1password.com/downloads/linux).
3. [Import or generate SSH keys in 1Password.](/ssh/manage-keys/)
4. [Set up the 1Password SSH Agent](/ssh/get-started/#step-3-turn-on-the-1password-ssh-agent) and make sure it's running on your local machine.

<Tip>
  **If you use Windows**

  If you use a Windows computer, you can [set up the 1Password WSL integration](/ssh/integrations/wsl) to authenticate SSH requests in your WSL instance from your Windows host.
</Tip>

## About SSH agent forwarding

When you enable agent forwarding for a remote host, every SSH request you make within the remote environment gets forwarded to the local 1Password process over the 1Password SSH Agent socket.

You can authorize SSH requests locally using options you've set up in 1Password, like your fingerprint. Then your authorization gets forwarded back to the remote host without ever needing to provide your private key to the remote server.

<Warning>
  Make sure you only use SSH agent forwarding with trusted hosts. [Learn how to use SSH agent forwarding more securely.](#security)
</Warning>

## Set up SSH agent forwarding

SSH agent forwarding is turned off in OpenSSH by default. You can choose to turn it on for a [single session](#for-a-single-session) or for a [specific host](#for-a-specific-host).

### For a single session

To turn on agent forwarding for a single session only, use the `-A` flag with the `ssh` command:

```shell theme={null}
ssh -A user@example.com
```

When you're connected to the remote host with agent forwarding turned on, the `SSH_AUTH_SOCK` environment variable on the remote host is automatically set. Data sent over this socket gets forwarded to the local 1Password socket.

<CodeResult>
  ```text theme={null}
  user@example.com:~$ echo $SSH_AUTH_SOCK
  #code-result
  /tmp/ssh-XXXXNpdlnL/agent.151
  ```
</CodeResult>

To check if agent forwarding is working, run the following command view a list of the SSH keys forwarded from 1Password to the remote host:

<CodeResult>
  ```text theme={null}
  user@example.com:~$ ssh-add -l
  #code-result
  256 SHA256:2zmxMpLy5MeIx18pBUkumptKkKinlghygOvV6URe8QI SSH Key from 1Password (ED25519)
  ```
</CodeResult>

If you see your SSH key listed, try to run an SSH request from within the remote server:

```text theme={null}
user@example.com:~$ ssh -T git@github.com
```

The 1Password app on your local machine should prompt you to authorize the request.

### For a specific host

If you want to set up SSH agent forwarding for a specific host all the time so you don't need to use the `-A` flag for each session, edit your `~/.ssh/config` file to include that host:

```text theme={null}
Host example.com
  ForwardAgent yes
```

<h2 id="security">
  SSH agent forwarding security
</h2>

### Security considerations

When you authorize your local terminal, IDE, or other SSH client to use an SSH key in an agent forwarding session, any new connection made within the remote environment using the same key is also authorized. If someone else were to gain access to the remote environment as the same OS user, they'd be able to use the SSH key to authenticate connections from the remote host for the duration of the session.

However, any other SSH keys available in the remote environment still require your approval before they can be used. Unlike the standard OpenSSH agent, where every key in the agent can be used in the remote environment without additional authorization, the 1Password SSH Agent requires your approval for each SSH key before it can be used. An attempt to use one of those keys from the remote environment triggers a 1Password authorization prompt that needs to be authenticated, making agent forwarding more secure with 1Password than with the OpenSSH agent.

### Use agent forwarding more securely

We recommend the following:

* Only use agent forwarding when you need it and in environments that you trust are secure.

* Set up agent forwarding on a [per-command basis](#for-a-single-session) or configure your `~/.ssh/config` file to allow agent forwarding [only with specific hosts](#for-a-specific-host). **Do not turn on SSH agent forwarding for all hosts by default.**

  <CodeWrapper variant="bad">
    ```text ~/.ssh/config (bad 👎) theme={null}
    Host *
      ForwardAgent yes
    ```
  </CodeWrapper>

  We recommend that you always scope the `ForwardAgent yes` directive down to a specific host or domain you trust for agent forwarding. For example, to turn on agent forwarding for [Gitpod <Icon icon="arrow-up-right-from-square" />](https://www.gitpod.io/):

  <CodeWrapper variant="good">
    ```text ~/.ssh/config (good 👍) theme={null}
    Host *.gitpod.io
      ForwardAgent yes
    ```
  </CodeWrapper>

<h2 id="cde">
  Use case: Cloud Development Environment
</h2>

If you use a local integrated development environment (IDE) to connect to a cloud development environment (CDE) and you want to pull, push, and sign remote Git commits, you can authenticate those commands through the local 1Password SSH Agent.

For example, you might have an IDE desktop app on your local workstation that you use to authenticate into a cloud-based development environment. You want to use the the CDE workspace to access remote Git repositories and you need to be able to authenticate Git requests and sign commits. With SSH agent forwarding, you can authenticate SSH and Git commands from your CDE workspace in your IDE desktop app through the 1Password SSH Agent running on your local workstation.

### Set up SSH agent forwarding

To set up SSH agent forwarding so you can authorize Git requests from your cloud development environment, [edit your SSH config file to add your CDE host](#for-a-specific-host). The remote development integration in your IDE should recognize this automatically.

To check if agent forwarding is correctly set up, open a remote shell in your IDE then run the following command:

<CodeResult>
  ```shell theme={null}
  ssh-add -l
  #code-result
  256 SHA256:2zmxMpLy5MeIx18pBUkumptKkKinlghygOvV6URe8QI SSH Key from 1Password (ED25519)
  ```
</CodeResult>

You should see a list of the SSH keys the agent can use for SSH requests.

### Use SSH for Git authentication

If your CDE is set up to use HTTPS to authenticate with Git and you want to use SSH instead, run the following command to modify the remote Git configuration for the CDE:

```shell theme={null}
git config --global url."ssh://git@".insteadOf "https://"
```

Alternatively, you can add the command to your cloud development initialization (cloud-init) script or dotfiles.

The next time you make a Git request from your CDE, 1Password should prompt you to authorize the request. For example:

```shell theme={null}
git fetch
```

If you only want to use SSH authentication going forward, you may want to revoke HTTPS write access to your repository.

### Set up Git commit signing

Your local `.gitconfig` file isn't automatically forwarded to your cloud development environment, so you'll need to modify the Git configuration in your CDE to set up remote Git commit signing.

1. Configure Git to use SSH for commit signing:

   ```shell theme={null}
   git config --global gpg.format ssh
   ```

2. Tell Git to always sign commits:

   ```shell theme={null}
   git config --global commit.gpgsign true
   ```

3. Set the SSH key you want to use to sign commits:

   ```shell theme={null}
   git config --global user.signingkey <your SSH public key>
   ```

### Authorization model

When you run an SSH or Git request in your cloud development environment that requires authorization, 1Password will prompt you to approve SSH key usage for the IDE that's connected to your CDE. If you approve the request, the entire IDE will be authorized to use that key. Any process running on the cloud development environment under the same OS user will also be authorized, which is a [security consideration](#security) to keep in mind.

<h2 id="remote-workstation">
  Use case: Remote workstation
</h2>

If you have a remote workstation that you connect to over SSH, and you want to run SSH and Git requests from that workstation, you can authenticate those requests through the 1Password agents that runs on your local host.

For example, you might have a desktop workstation at home that contains all your Git repositories. You want to work on the go, so you use your laptop to connect to your remote workstation over SSH so you can work in your Git repos. With SSH agent forwarding, you can authenticate SSH and Git commands from your remote workstation through the 1Password SSH Agent running on your local laptop.

### Set up SSH agent forwarding

To set up SSH agent forwarding so you can authorize SSH and Git requests from your remote workstation, [edit the SSH config file](#for-a-specific-host) on your local host to allow agent forwarding with your remote workstation.

To check if agent forwarding is correctly set up, connect to your remote workstation then run the following command:

<CodeResult>
  ```shell theme={null}
  ssh-add -l
  #code-result
  256 SHA256:2zmxMpLy5MeIx18pBUkumptKkKinlghygOvV6URe8QI SSH Key from 1Password (ED25519)
  ```
</CodeResult>

You should see a list of the SSH keys the agent can use for SSH requests.

### Modify the `IdentityAgent` configuration on the remote workstation

If your remote workstation also has the 1Password SSH Agent installed, you'll want to make sure that Git and SSH use the forwarded socket from your local host instead of the agent socket for the 1Password app installed on the remote workstation.

The `IdentityAgent` takes precedence over the `SSH_AUTH_SOCK` environment variable, so you may want to modify the `~/.ssh/config` file for your remote workstation so the `IdentityAgent` setting is only applied if you're not in an SSH shell.

```text theme={null}
Match host * exec "test -z $SSH_TTY"
  IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
```

Then any Git or SSH command executed from an SSH shell on the remote workstation will use the forwarded `SSH_AUTH_SOCK` for authentication and 1Password should prompt you to authorize SSH requests from your local host.

This change won't affect how the 1Password SSH Agent runs when you use the workstation locally instead of accessing it remotely. The `IdentityAgent` setting will be applied as usual to use the SSH agent running on the workstation.

### Set up Git commit signing

Your local `.gitconfig` file isn't automatically forwarded to your remote workstation, so the remote Git configuration will be used by default.

If you've configured [Git commit signing with 1Password](/ssh/git-commit-signing) on the remote workstation using the same SSH key you use on your local host, you shouldn't need make any changes to your setup.

If the `op-ssh-sign` signing program finds that both the `SSH_AUTH_SOCK` and the `SSH_TTY` environment variables are set, it will automatically adapt to use the forwarded socket from your local host instead of the 1Password socket from your remote workstation.

### Authorization model

When you run an SSH or Git request from a remote shell or remotely connected IDE that requires authorization, 1Password will prompt you to approve SSH key usage for the terminal or IDE you use to connect to the remote workstation.

If you approve the request, the entire app will be authorized to use this key. Any process running on the remote workstation under the same OS user will also be authorized, which is a [security consideration](#security) to keep in mind.

## Troubleshooting

If you're having trouble using agent forwarding with the 1Password SSH Agent, there are a few things you should check.

### Check if the `SSH_AUTH_SOCK` environment variable is set

Run `echo $SSH_AUTH_SOCK` in the terminal to make sure the environment variable is set on your server.

<CodeResult>
  ```text theme={null}
  user@example.com:~$ echo $SSH_AUTH_SOCK
  #code-result
  /tmp/ssh-XXXXNpdlnL/agent.151
  ```
</CodeResult>

If the variable isn't set, SSH agent forwarding won't work. Make sure [the 1Password SSH Agent is turned on](/ssh/get-started#step-3-turn-on-the-1password-ssh-agent) and that you've [configured your SSH client to use the agent for authentication](/ssh/get-started#step-4-configure-your-ssh-or-git-client).

### Check if the SSH agent can access the correct SSH key

Run `ssh-add -l` in the terminal to see a list of the SSH keys forwarded from 1Password to the remote host:

<CodeResult>
  ```text theme={null}
  user@example.com:~$ ssh-add -l
  #code-result
  256 SHA256:2zmxMpLy5MeIx18pBUkumptKkKinlghygOvV6URe8QI SSH Key from 1Password (ED25519)
  ```
</CodeResult>

If you don't see your SSH key listed, make sure the key is [eligible to use with the 1Password SSH Agent](/ssh/agent/#eligible-keys) and that it's [saved in a vault the SSH agent is configured to use](/ssh/agent/#configuration).

### Check if agent forwarding is allowed on the server

To use agent forwarding with a remote server, the `AllowAgentForwarding` option must be set to `Yes` in the [`sshd_config` file](https://man.openbsd.org/sshd_config) for the server.

## Learn more

* [Autofill public keys](/ssh/public-key-autofill/)
* [Manage SSH keys](/ssh/manage-keys/#generate-an-ssh-key)
* [Sign Git commits](/ssh/git-commit-signing)
* [Workflow: Secure your SSH & Git workflows](/get-started/secure-ssh-git-workflows)
