1Password AWS CLI Integration: Enhanced Security and Logging

## 概要

AWSのCLIツールを使用する際、セキュリティと可視性の向上は重要な課題です。本記事では、1PasswordのAWS CLIプラグインの制限を克服し、より安全で透明性の高い認証情報管理を実現する方法を紹介します。

## 課題

1PasswordのAWS CLIプラグインには、`~/.aws/config`のprofile別に認証情報を紐づける機能が欠けています。これにより、別AWS環境で誤って操作をするリスクが向上します。

## 解決策

1PasswordのAWS CLIプラグインを利用せずに、aws cliのcredential_processを活用して、1Passwordと連携させることで、以下の機能を実現します：

1. 認証情報へのアクセスを通知
2. アクセスログの記録
3. プロファイル別の認証情報管理

![認証情報アクセス通知](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/04b2fa7e-de6d-4088-a62e-4bb7463ee75d.png)

## 設定手順

### 1. カスタムスクリプトの作成

以下のスクリプトを`~/.aws/op-cred-helper.sh`として保存します：

```bash
#!/bin/bash
set -e
set -o pipefail

LOG_FILE="$HOME/.logs/onepassword_access.log"

log_access() {
    local vault="$1"
    local secret_id="$2"
    local current_user=$(whoami)
    local parent_process=$(ps -p $PPID -o comm= 2>/dev/null || ps -p $PPID -o command= 2>/dev/null || echo "Unknown")
    local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    local op_whoami=$(op whoami)
    local op_url=$(echo "$op_whoami" | grep "URL:" | awk '{print $2}')
    local op_email=$(echo "$op_whoami" | grep "Email:" | awk '{print $2}')
    local op_user_id=$(echo "$op_whoami" | grep "User ID:" | awk '{print $3}')

    local log_message=$(jq -n \
                      --arg timestamp "$timestamp" \
                      --arg user "$current_user" \
                      --arg parent_process "$parent_process" \
                      --arg vault "$vault" \
                      --arg secret_id "$secret_id" \
                      --arg op_url "$op_url" \
                      --arg op_email "$op_email" \
                      --arg op_user_id "$op_user_id" \
                      '{timestamp: $timestamp, user: $user, parent_process: $parent_process, vault: $vault, secret_id: $secret_id, op_info: {url: $op_url, email: $op_email, user_id: $op_user_id}}' | yq e - -P)

    echo "$log_message" >> "$LOG_FILE"
    echo "---" >> "$LOG_FILE"

    terminal-notifier -title "1Password Access" \
                      -subtitle "Vault: $vault" \
                      -message "Secret ID: $secret_id accessed by $parent_process" \
                      -sound default
}

main() {
    local vault="$1"
    local secret_id="$2"
    log_access "$vault" "$secret_id"
    cat <<END | op inject
    {
      "Version": 1,
      "AccessKeyId": "{{ op://${vault}/${secret_id}/aws_access_key_id }}",
      "SecretAccessKey": "{{ op://${vault}/${secret_id}/aws_secret_access_key }}"
    }
END
}

main "$1" "$2"
```

### 2. 依存関係のinstallとログディレクトリの作成と実行権限の付与

```sh
brew install jq yq terminal-notifier
mkdir $HOME/.logs
chmod +x ~/.aws/op-cred-helper.sh
```

### 3. AWS設定ファイルの更新

`~/.aws/config`ファイルを編集し、`credential_process`を設定します：

```
[profile test-profile]
region = ap-northeast-1
output = json
credential_process = "/Users/xxxx/.aws/op-cred-helper.sh" "Your-Vault-Name" "AWS-Access-Key-test-profile"
```

### 4. 1Passwordデーモンの起動設定

1Passwordの設定で「メニューバーに1Passwordを固定する」を有効化します。

![1Password設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/e74d2b8b-383b-e5d0-690c-8f3de0f6fef3.png)

### 5. macOS通知設定の調整

macOSの通知設定で`terminal-notifier`の通知を有効化し、PCを再起動します。

![通知設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141711/734b2279-8424-336e-ebc8-896c6c7ad320.png)

## メリット

1. **セキュリティの向上**: 認証情報へのアクセスが記録され、不正使用の検出が容易になります。
2. **透明性の確保**: どのプロセスがどの認証情報にアクセスしたかが可視化されます。
3. **柔軟な設定**: プロファイル別に異なる1Passwordエントリーを使用できます。

## 注意点

- 1Passwordのデーモンが常時起動している必要があります。
- 初回使用時にはmacOSの通知設定の調整が必要です。

## まとめ

この方法を使用することで、1PasswordとAWS CLIの統合をより安全かつ透明性の高いものにできます。セキュリティ意識の高い開発者やチームにとって、非常に有用なソリューションとなるでしょう。

## 参考資料

[How to Use 1Password to Securely Store Your AWS credentials - Ten Mile Square Technologies](https://tenmilesquare.com/resources/security/how-to-use-1password-to-securely-store-your-aws-credentials/)
[外部プロセスを使用して認証情報を作成する - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-sourcing-external.html)