# シークレットを安全に保存する

[シークレットスキャン](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/using-aikido-endpoint/secret-scanning) 資格情報がデバイス上の平文でどこに置かれているかを示します。ファイルの整理は対処の半分にすぎません。このページはもう半分、つまりそもそもそれらのファイルに秘密を入れないようにし、シークレットマネージャーに保存して必要なときに取得する方法です。

## シークレットが平文で残るまでの流れ

経路は3つあり、Aikido はその3つすべてを見つけます:

* **資格情報ファイル** - 一度設定ファイルに値を書き込んで、そのまま忘れてしまった場合。たとえば `~/.aws/credentials` または `.npmrc`.
* **入力したコマンド** - 次の場所に残ります `.zsh_history` または `.bash_history`に保存され、実行中は `ps`.
* **AIエージェントのセッション** - AI コーディングエージェントがそのコマンドを実行した場合、そのエージェントのセッショントランスクリプトにも値が残ります。

Aikido が検出する実際のパターンはこちらです:

```bash
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCY aws-vault add default
```

aws-vault はそのキーをキーチェーンに入れます。まさにあるべき場所です。問題はそこに至るまでの過程です。キーがキーチェーンに届く頃には、すでにシェル履歴、プロセス一覧、そしてエージェントが実行していればそのトランスクリプトにも残っています。入り口で漏らしてしまうなら、秘密を正しく保存しても意味がありません。

## そもそも長期有効な資格情報は必要ですか？

最高のシークレットは、存在しないものです。短命な資格情報は自動的に期限切れになるので、ディスク上に漏れるものも、ローテーションするものもありません。ボールトを使う前に、プロバイダが提供しているか確認してください:

* **AWS** - IAM Identity Center を使います。 [`aws configure sso`](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sso.html) を一度実行し、その後は `aws sso login` セッションの期限が切れたときに実行します。
* **Google Cloud** - 実行します `gcloud auth application-default login` サービスアカウントキーをダウンロードする代わりに。
* **GitHub** - 実行します `gh auth login`。これにより、個人アクセストークンを `.npmrc` または `.git-credentials`.

## シークレットマネージャーにシークレットを保存する

長期有効な資格情報が本当に必要な場合は、マネージャーに入れて、実行時に読み出してください。下の各タブには必要な2つのコマンドだけを載せています。残りはリンク先のガイドに従ってください。

{% hint style="warning" %}
値を環境変数に取り込むか、stdin にパイプします。たとえば `mytool --key "$(op read ...)"`のように引数として渡すと、シェル履歴とプロセス一覧にそのまま戻ってしまいます。
{% endhint %}

{% tabs %}
{% tab title="macOS キーチェーン" %}
macOS に組み込みで、追加ツールは不要です。値を `-w` フラグなしにすると `security` 入力を促されるため、シークレットがコマンドに表示されません。

```bash
security add-generic-password -a "$USER" -s stripe-api-key -w
```

必要なときに読み戻します:

```bash
export STRIPE_API_KEY=$(security find-generic-password -a "$USER" -s stripe-api-key -w)
```

参照 [Apple の Keychain Access ガイド](https://support.apple.com/guide/keychain-access/welcome/mac) UI で項目を管理する方法。
{% endtab %}

{% tab title="1Password" %}
CLI 引数ではなく、1Password アプリで項目を作成します。すると各フィールドには次の形式のシークレット参照が付きます `op://vault/item/field`。そこ自体にはシークレット値は含まれません。

```bash
export STRIPE_API_KEY=$(op read "op://Private/Stripe/credential")
```

複数の変数セットについては、参照を env ファイルに入れて `op run` に解決させます。値はそのサブプロセス内にだけ、コマンドが実行されている間だけ存在します:

```bash
op run --env-file=./aws.env -- terraform plan
```

AWS に特化して言うと、 `op plugin init aws` を使うと、AWS CLI は生体認証で 1Password 経由で認証できるため、ホームディレクトリには何も保存されません。

参照 [シークレット参照の構文](https://www.1password.dev/cli/secret-reference-syntax/), [シークレットを環境に読み込む](https://www.1password.dev/cli/secrets-environment-variables/)、および [AWS シェルプラグイン](https://www.1password.dev/cli/shell-plugins/aws/).
{% endtab %}

{% tab title="Bitwarden" %}
Bitwarden アプリで項目を追加し、次にボールトを解除して値を読み戻します:

```bash
export BW_SESSION=$(bw unlock --raw)
export STRIPE_API_KEY=$(bw get password "Stripe API key")
```

チームやマシンで共有するシークレットには、Bitwarden Secrets Manager が `bws run -- terraform plan`.

{% hint style="warning" %}
`BWS_ACCESS_TOKEN` 自体がシークレットです。OS キーチェーンに保存して実行時に読み出し、 `.zshrc`.
{% endhint %}

以下を参照してください [に貼り付けないでください。](https://bitwarden.com/help/cli/) と [Secrets Manager CLI](https://bitwarden.com/help/secrets-manager-cli/) ガイド。
{% endtab %}

{% tab title="aws-vault" %}
`aws-vault` AWS キーを OS キーチェーンに保存し、代わりに一時的な資格情報を渡します。値なしで実行すると両方の入力を求められるため、シェル履歴には何も残りません:

```bash
aws-vault add prod
```

その後、何でもこれ経由で実行できます:

```bash
aws-vault exec prod -- aws s3 ls
```

毎回入力するのをやめるには `aws-vault exec` を AWS CLI に指定し、 `~/.aws/config` を `~/.aws/credentials` 空にしておきます:

```ini
[profile prod]
credential_process = aws-vault export --format=json prod
```

{% hint style="warning" %}
1回 `credential_process` がプロファイルに設定されている場合は、手動で `aws-vault exec` も実行しないでください。AWS SDK が aws-vault を呼び出します。
{% endhint %}

以下を参照してください [aws-vault の使い方ガイド](https://github.com/99designs/aws-vault/blob/master/USAGE.md).
{% endtab %}
{% endtabs %}

## シークレットを移した後は

資格情報をマネージャーへ移しても、露出が取り消されるわけではありません。最後までやり切ってください:

1. 元の場所で古い値をローテーションしてください。誰がファイルや履歴を読んだかわからないため、漏えいしたものとして扱います。
2. 平文のコピーを削除してください。 **Secrets** タブをデスクトップクライアントで使ってシェル履歴と AI エージェントのセッションを確認し、資格情報ファイルは自分で編集します。
3. 検出結果が **Secrets** タブを選択します。

{% content-ref url="secret-scanning.md" %}
[シークレットスキャン](https://help.aikidogov.us/docs/docs-ja/aikido-device-protection/using-aikido-endpoint/secret-scanning)
{% endcontent-ref %}

Aikido がデバイス上ではなくコード内で見つけたシークレットについては、こちらを参照してください [マルウェアと漏えいしたシークレットの問題を解決する](https://help.aikidogov.us/docs/docs-ja/getting-started/core-functionalities/resolving-malware-and-leaked-secret-issues).
