macOSで1PasswordにSSHキーを登録しSSHコマンド時に使用する方法

## 実現したいこと

* 1PasswordにSSHキーを登録し、SSH時にそのSSHキーを指定したい
* セキュリティ向上のため、ローカルのストレージ上から秘密鍵を削除したい
* SSH時にTouch IDで認証できるようにしたい

## 手順

基本的には以下の1Password公式ドキュメントを参考に設定を行っていきます。

https://developer.1password.com/docs/ssh/agent/

https://developer.1password.com/docs/ssh/agent/advanced

https://developer.1password.com/docs/ssh/agent/config

### 1. SSHキー(秘密鍵/公開鍵)の生成

ターミナルで、以下のコマンドを実行しSSHキーを生成します。
ファイル名(`-f`)やコメント(`-C`)の部分は環境に合わせて変更してください。

```sh
# SSHキー生成(RSA形式)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/example_id_rsa -C "xxxxxx@example.com"

# ED25519形式にする場合
# ssh-keygen -t ed25519 -f ~/.ssh/example_id_ed25519 -C "xxxxxx@example.com"
```

生成されたファイルを確認します。

```sh
$ ls ~/.ssh/
example_id_rsa
example_id_rsa.pub
```

### 2. リモートマシンにSSH公開鍵を登録

SSHキーを使ってアクセスしたいリモートマシンに公開鍵を登録します。
すでにSSHでリモートアクセスが可能な場合は、 `ssh-copy-id` コマンドを使うと簡単に登録できます。

```sh
# (ローカル)
ssh-copy-id -i ~/.ssh/example_id_rsa example.com
```

まだSSHが使用できない環境の場合は、手動で authorized_keys に公開鍵の登録をしてください。

```
1. (ローカル) 公開鍵の内容をコピー
2. (リモート) ~/.ssh/authorized_keys に1の内容を追記
```

### 3. SSH接続確認

1Passwordを使用する前に、1のSSHキーを使用してSSHリモートアクセスできるか確認します。

```sh
# (ローカル)
ssh -i ~/.ssh/example_id_rsa xxxxxx@example.com

# (リモート)
uname -a
exit
```

SSHリモートアクセスが確認できたら次に進みます。

### 4. 1PasswordにSSHキー(秘密鍵)を登録

1Password.appを起動して、「新規アイテム」→「SSHキー」を選択して1で作成した秘密鍵(`~/.ssh/example_id_rsa`)を登録します。

![スクリーンショット 2023-10-29 15.24.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24450/e5f48361-44c9-ebaa-2e49-68d6be77ed8d.png)
![スクリーンショット 2023-10-29 15.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24450/9cecd9f0-d983-82c2-c695-73113f121fc6.png)

### 5. 1PasswordのSSHエージェント有効化

1Password.appの「1Password」メニュー→「設定...」を開き、「開発者」サイドメニューを選択し、「**SSHエージェントを使用**」にチェックを入れます。

![スクリーンショット 2023-10-29 15.27.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24450/09f873b8-e380-0ffb-f4d4-6eabdb0b9b49.png)


### 5. ~/.ssh/config の修正

`~/.ssh/config` で1PasswordのSSHエージェントを使用する設定を書いていきます。

```ssh:~/.ssh/config
Host example.com
  Hostname example.com
  User xxxxxx
  #IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
  IdentityAgent ~/.1password/agent.sock
  IdentityFile ~/.ssh/example_id_rsa.pub
  IdentitiesOnly yes
```

重要ポイントとして、`IdentityFile` には1で作成したSSHキーの公開鍵(`~/.ssh/example_id_rsa.pub`)を記載します。

こうすることで、1PasswordのSSHエージェントが対応する秘密鍵の情報を読み込んでくれます。

また、 `IdentityAgent`には1PasswordのSSHエージェントを指定します。
ただし、パスが複雑でわかりにくいので、簡単に指定できるように以下のコマンドを実行して `~/.1password/agent.sock` にシンボリックリンクを作成しておくのをオススメします。

```sh
mkdir -p ~/.1password
ln -s ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock ~/.1password/agent.sock
```

これで設定完了です。

### 6. SSH接続確認 with 1Password SSHエージェント

あとは、sshコマンドでリモートアクセスを実行します。

```sh
# (ローカル)
ssh example.com
```

すると、1Passwordのアクセスリクエスト画面が表示されるので、Touch IDで認証を行います。

![スクリーンショット 2023-10-29 15.40.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24450/9075588e-7900-29a6-846e-0321a4c168aa.png)

1Passwordの認証を行い、SSHリモートアクセスが確認できたら成功です。

```sh
# (リモート)
uname -a
exit
```

あとは必要に応じてローカルのSSH秘密鍵を削除しておきます。

```sh
rm -i ~/.ssh/example_id_rsa
```

## トラブルシューティング

### 「Load key "/Users/xxxxxx/.ssh/id_rsa.pub": invalid format」というエラーが発生する

1Password SSHエージェント使用時に、SSHを実行すると以下のエラーに遭遇。

```sh
$ ssh example.com
Load key "/Users/xxxxxx/.ssh/id_rsa.pub": invalid format
xxxxxx@example.com: Permission denied (publickey).
```

原因は `~/.config/1Password/ssh/agent.toml` で、たとえ設定が空だったとしてもこのファイルが存在しているとエラーが発生模様です。
（この原因をつかむのに半日かかった、、、）

**対策**

`~/.config/1Password/ssh/agent.toml` 設定ファイルを使用していない場合は、削除するかリネームします。

```sh
mv ~/.config/1Password/ssh/agent.toml ~/.config/1Password/ssh/agent.bak.toml
```

その後、sshコマンドを再度試してください。

## 参考

* https://developer.1password.com/docs/ssh/agent/
* https://developer.1password.com/docs/ssh/agent/advanced
* https://developer.1password.com/docs/ssh/agent/config