2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DevContainerから1Password SSH Agentを使う方法

Posted at

先に結論だけ

DevContainer内から1Password SSH Agentを使うには、以下の3つの設定をdevcontainer.jsonに追加します。

{
  "name": "Node.js DevContainer",
  "image": "mcr.microsoft.com/devcontainers/typescript-node:latest",

  "runArgs": [
    "-v",
    "${localEnv:HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock:/tmp/1password-agent.sock"
  ],

  "remoteEnv": {
    "SSH_AUTH_SOCK": "/tmp/1password-agent.sock"
  },

  "postStartCommand": "sudo chown node:node /tmp/1password-agent.sock && sudo chmod 600 /tmp/1password-agent.sock"
}

ポイント

  1. runArgsで1PasswordのUnixソケットをコンテナー内にマウント
  2. remoteEnvで環境変数SSH_AUTH_SOCKを設定
  3. postStartCommandで権限を調整(所有者をnodeユーザーに、パーミッションを600に)

はじめに

DevContainer内でGitリポジトリにSSH接続する際、秘密鍵の管理が課題になります。秘密鍵をコンテナー内にコピーするのはセキュリティ上好ましくありません。

1Password SSH Agentを使えば、秘密鍵をコンテナー外(ホストOS上の1Password)で安全に管理しながら、DevContainer内からSSH認証を行うことができます。

この記事では、macOS + VS Code Dev Containersの環境で1Password SSH Agentを使う方法を、実際にハマったポイントも含めて紹介します。

対象読者

  • Docker/DevContainerを使い始めた方
  • DevContainer内でGit署名付きコミットやSSH接続を行いたい方
  • 1Passwordで秘密鍵を安全に管理したい方

対象環境

この記事は以下の環境で動作確認しています:

  • macOS 15.7.2
  • VS Code 1.106.0
  • Docker Desktop for Mac 4.51.0
  • 1Password for Mac 8.11.18(SSH Agent機能有効化済み)

この記事ではmacOS固有のSSH Agentパス(~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock)を使用しています。LinuxやWindowsなど他のプラットフォームを利用する場合は、お使いのOSに応じたパスに読み替えてください。

前提条件

以下の環境が整っていることを前提とします。

  • 1Password(SSH Agent機能が有効: 有効化手順
  • Visual Studio Code(Dev Containers拡張機能)
  • Docker Desktop

セットアップ手順

ステップ1: devcontainer.jsonの作成/編集

プロジェクトルートの.devcontainer/devcontainer.jsonを編集します(まだ存在しない場合は作成)。

ステップ2: 3つの設定項目を追加

2-1. runArgs: Unixソケットのマウント

"runArgs": [
  "-v",
  "${localEnv:HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock:/tmp/1password-agent.sock"
]
解説
  • Dockerの-vオプションを使って、ホストの1Password SSH Agentソケットをコンテナーにマウントします
  • macOSでは1Passwordのソケットは~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sockに配置されています
  • コンテナー内では/tmp/1password-agent.sockとしてアクセスできるようになります
Unixソケットとは

Unixソケット(UNIXドメインソケット)は、同一マシン上のプロセス間通信に使われる仕組みです。ファイルシステム上のパスで識別され、ネットワーク通信と同じソケットAPIを使いながら、ローカル通信を実現します。

1Password SSH Agentは、このUnixソケットを通じてSSH鍵へのアクセスを提供しています。

参考: 付録 A UNIX ドメインソケット - Oracle Solaris 10ドキュメント

なぜrunArgsを使うのか

後述の「ハマったポイント」で詳しく説明しますが、UnixソケットファイルのマウントにはmountsプロパティではなくrunArgs-vオプションを使う必要があります。

2-2. remoteEnv: 環境変数の設定

"remoteEnv": {
  "SSH_AUTH_SOCK": "/tmp/1password-agent.sock"
}
解説
  • コンテナー内のSSH_AUTH_SOCK環境変数に、マウントしたソケットファイルのパスを指定します
  • この環境変数により、gitやsshコマンドがSSH Agentの場所を認識できます

2-3. postStartCommand: 権限の調整

"postStartCommand": "sudo chown node:node /tmp/1password-agent.sock && sudo chmod 600 /tmp/1password-agent.sock"
解説
  • コンテナー起動時、マウントされたソケットファイルの所有者はroot:root、パーミッションは660になっています
  • nodeユーザー(このDevContainerのデフォルトユーザー)がアクセスできるように、所有者を変更します
  • パーミッションを600(所有者のみ読み書き可能)に設定することで、セキュリティを強化します

ステップ3: DevContainerのリビルド

VS Codeのコマンドパレット(Cmd+Shift+P)から「Dev Containers: Rebuild Container」を実行し、コンテナーをリビルドします。

動作確認

DevContainer内のターミナルで以下のコマンドを実行し、正しく動作しているか確認します。

ssh-add -l

期待される出力

1Passwordに保存されているSSH鍵の一覧が表示されれば成功です。

256 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (ED25519)

SSH Agentを共有すると何ができるか

SSH Agentが正しく動作することで、以下のような用途にSSH鍵を利用できるようになります:

  • Gitコミットの署名:SSH鍵を使った署名付きコミットが可能になります
  • GitHubへのSSHアクセス:SSH認証を設定している場合、git clonegit pushなどのGit操作が可能になります
  • その他のSSH接続:リモートサーバーへの接続など、SSH鍵を必要とする操作が可能になります

1Password SSH Agentを使う利点

  • 秘密鍵のコピー不要:秘密鍵はコンテナー内に存在せず、1Passwordで安全に管理されます
  • ユーザーによる認証と使用許可:SSH鍵を使う操作を実行すると、ホストOS上で1Passwordの認証プロンプトが表示されます(TouchID、Face IDやパスワード認証など)。ここで署名を拒否すると処理が中断され、コマンドが失敗します。これにより、マルウェアなどが鍵データを悪用しようとしても、ユーザーが処理を中断できます
  • 一時的なアクセス:コンテナー停止時は自動的にアクセスが切断されます

ハマったポイント

DevContainer内で1Password SSH Agentを使う際、mountsプロパティを使ったアプローチも試しましたが、Unixソケットのマウントでは問題が発生しました。

実験1: mountstype=bindを使った場合

"mounts": [
  "source=${localEnv:HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock,target=/tmp/1password-agent.sock,type=bind"
]

結果: ❌ 失敗
ソケットファイルではなく、ディレクトリが作られてしまう問題が発生しました。

$ ls -la /tmp/1password-agent.sock
drwxr-xr-x  2 root root  40 Nov 16 10:00 1password-agent.sock/

実験2: mountstype=volumeを使った場合

"mounts": [
  "source=${localEnv:HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock,target=/tmp/1password-agent.sock,type=volume"
]

結果: ❌ 失敗
コンテナーのビルド自体が失敗しました。volumeタイプはホストファイルシステムのパスをサポートしていません。

結論: runArgs+-vが正解

Unixソケットファイルのマウントには、runArgsdocker run-vオプションを直接指定する方法が正しく動作します。

"runArgs": [
  "-v",
  "${localEnv:HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock:/tmp/1password-agent.sock"
]

補足: Docker Desktop公式方式との比較

Docker Desktop for Mac 2.2.0.0以降には、SSH Agent転送の公式機能があります(公式ドキュメント)。

Docker Desktop公式方式

{
  "mounts": [
    "source=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-auth.sock,type=bind"
  ],
  "containerEnv": {
    "SSH_AUTH_SOCK": "/run/host-services/ssh-auth.sock"
  }
}

この方式では、Docker Desktopがホストの$SSH_AUTH_SOCK環境変数が指すソケットをコンテナーに転送します。

どちらを選ぶべきか

一般的には、Docker Desktop公式方式($SSH_AUTH_SOCKを使う方式)を推奨します。

この方式では、ホスト側で以下の設定を行います:

## .zshrcなどに追加
export SSH_AUTH_SOCK="$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"

これでホスト側の環境変数$SSH_AUTH_SOCKが、1Password SSH Agentのソケットを指すようになります。

参考: 1Password SSH Agent - SSH_AUTH_SOCK

Docker Desktop公式方式の利点

  • プラットフォーム非依存(macOS/Linux対応)
  • 複数のSSH Agent実装を切り替えやすい
  • postStartCommandでの権限設定が不要
  • チームで共有しやすい

なぜこの記事では直接マウント方式を使うのか

この記事では、実験的に直接マウント方式を採用しています。その理由は:

  • macOSのデフォルト$SSH_AUTH_SOCK(システムキーチェーン)との違いを明確にするため
  • 1Passwordソケットの場所を明示的に指定することで、設定内容がより理解しやすくなるため

トラブルシューティング

Error connecting to agent: Permission denied

原因

ソケットファイルの権限が正しく設定されていない

対処法

  1. postStartCommandが正しく実行されているか確認
  2. ソケットファイルのパーミッションを確認:
    ls -la /tmp/1password-agent.sock
    
  3. コンテナーをリビルド: "Dev Containers: Rebuild Container"

The agent has no identities

原因

ホスト上の1Passwordが起動していない、またはSSH Agent機能が無効

対処法

  1. ホストOS上で1Passwordアプリが起動しているか確認
  2. 1PasswordのSSH Agent機能が有効になっているか確認(Settings → Developer → SSH Agent)
  3. ホストで1Passwordソケットをテスト:
    SSH_AUTH_SOCK="$HOME/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock" ssh-add -l
    

Gitコミット時にCouldn't find key in agent?

原因

環境変数が正しく設定されていない、または鍵が1Passwordに登録されていない

対処法

  1. コンテナー内のSSH_AUTH_SOCK環境変数が正しく設定されているか確認:
    echo $SSH_AUTH_SOCK
    
    /tmp/1password-agent.sockと表示されるはず
  2. 1Passwordに署名用のSSH鍵が登録されているか確認
  3. .gitconfiguser.signingkeyが1Passwordの鍵と一致しているか確認

ソケットがマウントされない

原因

ソケットパスが間違っている、またはDocker Desktopの問題

対処法

  1. ホストOSのソケットパスが正しいか確認
    ls -la ~/Library/Group\ Containers/2BUA8C4S2C.com.1password/t/agent.sock
    
  2. Docker Desktopを再起動
  3. コンテナーをリビルド

まとめ

DevContainer内から1Password SSH Agentを使うには、以下の3つの設定が必要です:

  1. runArgs: Unixソケットを-vオプションでマウント(mountsではなくrunArgsを使う)
  2. remoteEnv: SSH_AUTH_SOCK環境変数を設定
  3. postStartCommand: ソケットファイルの権限を調整

この設定により、秘密鍵をコンテナー内に置くことなく、安全にSSH認証を行えます。

参考リンク

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?