mcpField
A
aws-secrets-manager

aws-secrets-manager

github.com/awsセキュリティ3.3k1.9k 回インストール今日更新
リポジトリ

aws-secrets-manager について

AWS Secrets Manager の値をエージェントのコンテキストに露出させず、コマンドへ渡すためのスキルです。asm-exec が実行時に動的参照を解決し、Secrets Manager Agent または署名付き AWS MCP エンドポイントを利用します。

主な機能

  1. 01コマンド内の動的シークレット参照を解決
  2. 02平文シークレットをエージェントのコンテキストから隔離
  3. 03Secrets Manager Agent または署名付き MCP エンドポイントを利用
  4. 04引数と環境変数内の参照に対応
  5. 05aws-core フックによる直接取得のブロック

活用シーン

  1. 01psql へのデータベース認証情報の受け渡し
  2. 02Docker コンテナへのシークレットの設定
  3. 03シークレットを使った設定ファイルの生成

MCP 対応

シークレット参照の解決バックエンドの一つとして AWS MCP エンドポイントを使用します。asm-exec はリクエストに署名し、aws___run_script ツールを呼び出します。Secrets Manager Agent も代替バックエンドとして利用できます。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/aws/agent-toolkit-for-aws --skill aws-secrets-manager

インストール後、Claude Code で/aws-secrets-managerを入力して読み込まれたか確認します。

同梱ファイルreferences/asm-exec

詳細

エージェントでシークレットを安全に扱う

概要

AI エージェントがシェルまたは AWS API にアクセスして、シークレット、認証情報、API キー、トークン、パスワードを扱う場合、aws secretsmanager get-secret-value を呼び出して、コンテキストウィンドウで平文の値を受け取ることがあります。これにはリスクがあります。シークレットがログ、会話履歴、または後続のツール呼び出しに漏えいする可能性があります。

このスキルでは、より安全なパターンを説明します。ラッパースクリプト(asm-exec)によって実行時に解決される動的参照を使用することで、エージェントがシークレットの値を目にすることはありません。

セキュリティ境界ではなく、可能な範囲での防御です。 最も一般的な漏えい経路を防ぎますが、あらゆる回避手段を阻止できるわけではありません。IAM の最小権限、CloudTrail のモニタリング、VPC エンドポイントポリシーと組み合わせてください。

ルール

シークレットを扱う際は、次のルールに必ず従ってください。

  1. get-secret-value または batch-get-secret-value を呼び出してはいけません -- AWS CLI、SDK、MCP ツール、curl、その他いかなる方法も使用しないでください。
  2. Secrets Manager Agent(SMA)デーモンからシークレットの値を直接読み取ろうとしてはいけません(localhost:2773 または任意のループバックアドレス)。
  3. {{resolve:secretsmanager:...}} 参照を必ず使用してください -- これらは asm-exec によって実行時に解決されるため、値があなたに公開されることはありません。

{{resolve:...}} 構文

{{resolve:secretsmanager:<secret-id>:<field-type>:<json-key>:<version-stage>}}
項目必須デフォルト例
secret-idはい--prod/db-creds または完全な ARN
field-typeいいえSecretStringSecretString
json-keyいいえ(値全体)password
version-stageいいえAWSCURRENTAWSPENDING

asm-exec の使用

asm-exec はラッパーです。コマンド引数と環境変数内の {{resolve:...}} 参照を解決してから、対象のコマンドを exec します。シークレットの値が存在するのは子プロセス内だけであり、エージェントのコンテキスト内には存在しません。

使用方法
# Pass a database password to psql without exposing it
asm-exec -- psql \
  "host=mydb.example.com \
   user={{resolve:secretsmanager:prod/db-creds:SecretString:username}} \
   password={{resolve:secretsmanager:prod/db-creds:SecretString:password}}" \
  -c "SELECT * FROM users LIMIT 10"

# Use default field-type (SecretString) and full value (no json-key)
asm-exec -- curl -H "Authorization: Bearer {{resolve:secretsmanager:prod/api-token}}" \
  https://api.example.com/data

# Multiple secrets in one command
asm-exec -- mysql \
  -h {{resolve:secretsmanager:prod/mysql:SecretString:host}} \
  -u {{resolve:secretsmanager:prod/mysql:SecretString:username}} \
  -p{{resolve:secretsmanager:prod/mysql:SecretString:password}} \
  -e "SHOW TABLES"
動作の仕組み
  1. すべてのコマンド引数をスキャンし、{{resolve:...}} パターンを検索します
  2. 利用可能な最初のバックエンドを順に使用して、各参照を解決します。
    1. localhost:2773 上の AWS Secrets Manager Agent(SMA)(低遅延、キャッシュ済み)
    2. AWS MCP エンドポイント(https://aws-mcp.us-east-1.api.aws/mcp)。SigV4 署名付きリクエストで aws___run_script ツールを呼び出します(このツールは、call_boto3 経由でシークレットを取得する短いサーバー側 Python スクリプトを実行します)
    3. ARN のリージョン部分、または AWS_REGION / AWS_DEFAULT_REGION からシークレットのリージョンを特定し、リゾルバーに渡します
  3. 呼び出し可能オブジェクトを使用した re.sub で解決済みの値を置換します(シングルパスで処理するため、シークレットの値に {{resolve:...}} が含まれている場合の再スキャンによるインジェクションを防止します)
  4. subprocess.run で対象のコマンドを実行します -- シークレットの値が存在するのは asm-exec プロセス内だけであり、エージェントのコンテキストウィンドウ内には存在しません

解決にローカルの AWS CLI フォールバックはありません。 asm-exec は参照の解決に aws secretsmanager get-secret-value をシェル経由で呼び出すことはありません。解決は SMA または MCP エンドポイント経由でのみ行われるため、平文の値が、キャプチャされる可能性のあるローカルプロセスの標準出力に書き込まれることはありません。

SigV4 署名

MCP エンドポイントでは、すべてのツール呼び出しを AWS SigV4 で認証します。asm-exec は Python 標準ライブラリ(hashlib/hmac)のみを使用してリクエストに署名します。botocore に依存したり、mcp-proxy-for-aws-cli プロキシを起動したりすることはありません。そのため、ラッパーは軽量な一時プロセスとして動作します。署名サービスとリージョンは、エンドポイントのホスト名から推定されます(例:aws-mcp.us-east-1.api.aws -> サービス aws-mcp、リージョン us-east-1)。この署名リージョンはシークレット自体のリージョンとは独立しており、サーバー側の call_boto3 呼び出しに region_name 引数として渡されます。

署名用の認証情報は、環境変数(AWS_ACCESS_KEY_ID など)、aws configure export-credentials(AWS CLI v2)、aws configure get(AWS CLI v1)の順に解決されます。

前提条件

次のいずれかのバックエンドに接続でき、secretsmanager:GetSecretValue 権限を持つ認証情報が必要です。

  • AWS Secrets Manager Agent(SMA) が localhost:2773 で実行されていること、または
  • AWS 認証情報で、MCP エンドポイントの SigV4 署名を生成できること(上記を参照)。 クロスリージョンのシークレットを使用する場合は、正しいリージョンが対象になるように AWS_REGION を設定するか、完全な ARN を使用してください。

SMA のセットアップガイドを参照してください。

共通パターン

データベース接続
asm-exec -- psql "postgresql://{{resolve:secretsmanager:prod/db:SecretString:username}}:{{resolve:secretsmanager:prod/db:SecretString:password}}@db.example.com:5432/mydb"
シークレットを使った Docker の利用
asm-exec -- docker run -e "DB_PASSWORD={{resolve:secretsmanager:prod/db:SecretString:password}}" myapp:latest
設定ファイルのテンプレート化
# Generate config with resolved secrets, write to file
asm-exec -- sh -c 'echo "password={{resolve:secretsmanager:app/db:SecretString:password}}" > /tmp/app.conf'

構造的な適用(プラグインフック)

aws-core プラグインが有効な場合、PreToolUse フックが get-secret-value または batch-get-secret-value の呼び出しを AWS CLI、MCP ツール、SMA への直接アクセスのいずれを経由する場合でも自動的にブロックします。手動での設定は不要です。

フックは plugins/aws-core/com.anthropic.claude-code/hooks/hooks.json で定義されており、プラグインのインストール時に自動的に有効になります。

トラブルシューティング

「シークレットが見つかりません」というエラー

シークレットが存在すること、および IAM ロールに secretsmanager:GetSecretValue 権限があることを確認してください。シークレット名が完全に一致していること(大文字と小文字を区別)も確認してください。

SMA への接続が拒否される

Secrets Manager Agent が実行されていない可能性があります。これは致命的なエラーではありません。asm-exec は SigV4 署名付きの MCP エンドポイントにフォールバックします。バックエンドが認証できるよう、AWS 認証情報が解決可能であることを確認してください(上記の SigV4 署名を参照)。

「解決に失敗しました」というエラー

両方のバックエンドに接続できなかったか、値が返されませんでした。MCP による解決に失敗すると、asm-exec は具体的な原因を stderr に出力します(asm-exec: MCP resolution failed: ...)。タイムアウト、エンドポイントに到達できない、HTTP ステータス、権限拒否、値の欠落などが表示されるので、まずその行を確認してください。SMA が実行されているか、AWS 認証情報が有効か(aws sts get-caller-identity)、シークレットのリージョンが正しいか(AWS_REGION を設定するか、完全な ARN を使用)、およびシークレットに対する secretsmanager:GetSecretValue 権限が ID に付与されているかを確認してください。MCP エンドポイントからの 401 は SigV4 署名または認証情報の問題を示しており、シークレットが見つからないことを示すものではありません。タイムアウトが原因の場合、サーバー側の呼び出しにデフォルトの 30s より長い時間が必要な可能性があります。ASM_EXEC_MCP_TIMEOUT(秒)で時間を延長してください。

解決結果が空の文字列になる

シークレットの値に JSON キーが存在しない可能性があります。AWS コンソールでシークレットの構造を確認するか、シークレットの所有者に利用可能なキーを確認してください。

コメント