コンテンツにスキップ

AWS Secrets Manager 運用ガイド

本プロジェクトにおける、AWS Secrets Manager の取得・更新・注入手順をまとめた実務ガイドです。

1. 基本仕様

  • SecretString: {"KEY":"VALUE", ...} の JSON object
  • 既定リージョン: ap-northeast-1
  • 推奨プロファイル: RITSUBI_AWS_PROFILE=ritsubi
  • 実行入口: scripts/ops/with-env.sh / scripts/ops/secrets.mjs
  • 実行時の環境変数は SECRETS_* 系へ統一する
  • Storefront の canonical URL / public alias URL など公開 topology は scripts/ops/deploy-targets.sh を正本にする。Secrets Manager 側の STOREFRONT_URL / STOREFRONT_PUBLIC_URL は、Vendure / WordPress runtime が URL を生成するための環境別ミラー値として扱い、公開 topology の主正本にはしない。 Secrets Manager は credential、token、SBPS、CMS token などの機密値を主に管理する。

2. クイックスタート

AWS SSO または IAM 認証が有効であることを確認してください。

# プロファイルが有効か確認
aws sts get-caller-identity --profile "$RITSUBI_AWS_PROFILE"

3. config と Secrets prefix の対応

SECRETS_CONFIG は次のように secret 名へ解決されます。

SECRETS_CONFIG prefix
dev b2b-ecommerce/dev/shared
ci / ci_shared / dev_ci b2b-ecommerce/ci/shared
dev_storefront b2b-ecommerce/dev/storefront
dev_vendure b2b-ecommerce/dev/vendure
dev_wp b2b-ecommerce/dev/wp
staging / staging_shared b2b-ecommerce/staging/shared
staging_storefront b2b-ecommerce/staging/storefront
staging_vendure b2b-ecommerce/staging/vendure
staging_wp b2b-ecommerce/staging/wp
prod / production / prod_shared / production_shared b2b-ecommerce/prod/shared
prod_storefront / production_storefront b2b-ecommerce/prod/storefront
prod_vendure / production_vendure b2b-ecommerce/prod/vendure
prod_wp / production_wp b2b-ecommerce/prod/wp
prod_infra / production_infra b2b-ecommerce/prod/infra

3.1 キー配置ルール(shared 正本)

意図: 共通キーの二重管理を防ぎ、更新先を一意にするため。

  • shared へ置くもの: 複数サービスで使い回すキー。
  • 例: AWS_*, CLOUDFLARE_*, SENTRY_DSN, VITE_PUBLIC_VENDURE_BASE_URL 等。
  • CMS_REVALIDATE_SECRET は Storefront / Vendure / WordPress が同じ値を読むため shared 固定。Vendure の商品 / collection 更新時の Storefront data cache invalidation でも使う。
  • 各 service へ置くもの: そのサービス固有のキー。
  • 例: DATABASE_URL, COOKIE_SECRET, WP_AUTH_KEY 等。

3.2 配置判断チェックリスト

新しい key を追加・移動する前に、次を順に確認してください。

  1. 同一 env 内で複数サービスが同じ値を読むか
    はい → b2b-ecommerce/{env}/shared を正本にする。
  2. そのサービス専用の接続先・認証情報・運用値か
    はい → b2b-ecommerce/{env}/{service} を正本にする。
  3. worktree / localhost / portless の補助値か
    はい → Secrets Manager へは置かず、起動コマンドで一時指定する。
  4. Storefront の canonical URL / public alias URL など公開 topology か
    はい → 主正本は scripts/ops/deploy-targets.sh。ただし runtime が URL を返す STOREFRONT_URL / STOREFRONT_PUBLIC_URL は service secret へミラーしてよい。 例: production Vendure の商品プレビューは b2b-ecommerce/prod/vendureSTOREFRONT_PUBLIC_URL=https://medical.ritsubi.co.jp を使う。
  5. 同名 key がすでに別 source にないか
node scripts/ops/secrets.mjs --env staging --services shared,storefront --audit --fail-on-duplicates

この監査で重複が出た場合は、shared を正本に寄せて service 側の重複 key を削除してください。

4. 取得方法(用途別)

4.1 コマンドに注入して実行(推奨)

# 任意 script を secret 注入付きで実行
SECRETS_CONFIG=staging_storefront ./scripts/ops/with-env.sh -- pnpm run some-command
  • アプリ起動・ビルド・テストはこの方式を優先してください。
  • SECRETS_CONFIG=*_storefront|*_vendure|*_wp で起動した場合、with-env.shshared + service を自動で合成して注入します(SECRETS_INCLUDE_SHARED=0 で無効化可能)。
  • shared と service の同名キーが重複する場合、通常は取得を失敗させます。例外対応でどうしても上書きが必要なときだけ scripts/ops/secrets.mjs--allow-overrides を付け、後勝ちでマージします。

4.2 scripts/ops/secrets.mjs を直接使う(CI/スクリプト向け)

# prefix 指定で JSON 取得
node scripts/ops/secrets.mjs --path b2b-ecommerce/staging/storefront --format json

# env/service 指定でコマンド実行
node scripts/ops/secrets.mjs --env dev --service vendure -- pnpm exec nx run ritsubi-vendure-server:dev

# shared + service を合成して取得
node scripts/ops/secrets.mjs --env staging --services shared,storefront --format json

# shared / service の key 所有状況を監査
node scripts/ops/secrets.mjs --env staging --services shared,storefront --audit

# CI で重複を fail-fast したい場合
node scripts/ops/secrets.mjs --env prod --services shared,vendure --audit --fail-on-duplicates

# 例外対応: 重複キーを許容して後勝ちでマージ
node scripts/ops/secrets.mjs --env staging --services shared,storefront --allow-overrides --format json

# GitHub Actions の GITHUB_ENV に書き込み
node scripts/ops/secrets.mjs --env staging --service storefront --write-github-env

補足:

  • --write-github-env は標準出力に secret を出さず、$GITHUB_ENV に書き込みます。
  • --allow-overrides は緊急避難用です。恒久運用では重複キーを解消してください。
  • --audit は source ごとの key 一覧と重複 key を表示します。--format json を付けると CI で機械的に扱えます。

4.3 Storefront real E2E principal の同期

Storefront real E2E では storefront secret に置く E2E_* と、Vendure 側で実在する test customer principal を同時に揃えてください。

# dev / staging の storefront E2E credential key を同期
just storefront-e2e-credentials-sync dev,staging true

# dev は local Vendure、staging は Fly 上の DB に対して test customer を同期
just storefront-e2e-prepare dev,staging

運用ルール:

  • E2E_* の正本は b2b-ecommerce/{env}/storefront
  • 対応する Vendure principal は TEST_*(未設定時は apps/vendure-server/src/data/fixtures/test-customers.ts の既定値)から作成・更新する
  • staging / production の顧客同期は fly proxy 経由で remote DB へ非破壊に適用する
  • just storefront-e2e-credentials-sync <envs> false は dry-run 監査として使える。changed=0 は storefront secret 側の E2E_* key が同期済みであることを意味する
  • credential が同期済みでも real E2E が成功するとは限らない。just storefront-e2e-real は別途 target の PLAYWRIGHT_BASE_URL / VENDURE_BASE_URL 到達性と deploy 済み画面の整合性に依存する

4.4 Storefront real E2E の実行入口

Secrets Manager 正本から E2E_* を注入して real E2E を叩くときは、原則として just storefront-e2e-real を使ってください。

# staging の単体 spec を実行
just storefront-e2e-real staging 'tests/e2e/account-gift.real.spec.ts --project=chromium'

# local code に secret を注入して自動起動つきで実行
just storefront-e2e-real-local 'tests/e2e/account-gift.real.spec.ts --project=chromium'

切り分けの指針:

  • global-setup依存サービスに接続できません: secret ではなく target URL / server 起動の問題
  • Authentication state saved ... まで進む: E2E_LOGIN_* の注入とログイン自体は成功
  • その後に spec が失敗する: deploy 差分、DOM 変更、または実データ前提のずれを疑う
  • local 検証と staging 検証で入口を混ぜない: local code は just storefront-e2e-real-local、既存環境は just storefront-e2e-real <env> を使い分ける

4.5 SB Payment endpoint policy の監査

SB Payment は shared + vendure を合成して読みますが、staging/prod の live 決済では endpoint の暗黙 fallback を禁止します。

# staging の SB Payment secret 配置と live endpoint 要件を監査
just vendure-sb-payment-audit staging

# prod も同様
just vendure-sb-payment-audit prod

監査ルール:

  • sharedvendure に同名 SB_PAYMENT_* key が重複していたら fail
  • dev/local は endpoint 未設定でも fail しない
  • 理由: local 起動では import/startup resilience のため fallback を許容する
  • staging/prodSB_PAYMENT_SIMULATOR_MODE=true明示していない場合、 SB_PAYMENT_FEP_BASE_URL が必須
  • staging/prodSB_PAYMENT_SIMULATOR_MODE=true を明示した場合のみ、live endpoint 未設定での起動を許容する
  • endpoint が存在しても、live 実行には別途 merchantId / serviceId / hashKey / callback URL 群が必要であり、これらは plugin runtime が fail-closed で検証する

just を使わずに機械監査したい場合は、次を直接実行します。

node scripts/ops/audit-sb-payment-secrets.mjs --env staging

5. 更新方法

# 現在値を取得
payload="$(aws secretsmanager get-secret-value \
  --region ap-northeast-1 \
  --secret-id b2b-ecommerce/dev/storefront \
  --query SecretString \
  --output text)"

# key を追加・更新
updated="$(printf '%s' "$payload" | jq -c --arg key VITE_PUBLIC_SITE_URL --arg value https://example.com '.[$key] = $value')"
aws secretsmanager update-secret \
  --region ap-northeast-1 \
  --secret-id b2b-ecommerce/dev/storefront \
  --secret-string "$updated"

# key を削除(最後の 1 key でも {} を残す)
deleted="$(printf '%s' "$payload" | jq -c 'del(.VITE_PUBLIC_SITE_URL)')"
aws secretsmanager update-secret \
  --region ap-northeast-1 \
  --secret-id b2b-ecommerce/dev/storefront \
  --secret-string "${deleted:-\{\}}"

更新時の運用ルール:

  • config=*shared へ書くときに同名キーが service 側に存在する場合は失敗
  • config=*_{service} へ書くときに同名キーが shared に存在する場合は失敗
  • 最後の 1 key を削除する場合も secret 自体は消さず、空の JSON object ({}) として残す
  • 更新前に shared / service のどちらへ置くべきかを確認し、重複キーを作らない
  • ローカル作業では aws --profile ritsubi または AWS_PROFILE=ritsubi を明示する
  • CI 共通 secret の config 名は ci / ci_shared を推奨し、dev_ci は互換 alias としてのみ扱う

運用ルール:

  • SSOT: Secrets Manager が正本。ローカルの .env は使い捨て。
  • 共有先: shared シークレットは全サービスで共有されるため、不用意なキー追加・削除に注意する。

6. トラブルシューティング

6.1 Unknown config: XXX

  • 指定値が scripts/ops/with-env.sh のマッピングにない状態です。
  • 対応:
  • scripts/ops/secrets-config.shresolve_secrets_config() を確認
  • 必要なら SECRETS_ENVSECRETS_SERVICE を明示して実行
SECRETS_ENV=dev SECRETS_SERVICE=storefront ./scripts/ops/with-env.sh -- pnpm dev

6.2 Credentials not found

  • AWS の認証が切れているか、プロファイルが正しくありません。
  • 対応:
  • aws sso login --profile ritsubi を実行。
  • export AWS_PROFILE=ritsubi を設定。

6.3 Duplicate secret key 'XXX' across sources

  • shared と各サービス(storefront 等)で同じキー名が定義されています。
  • 対応:
  • どちらか一方のキーを削除して一意にします。
  • 再発防止のため、次を実行して shared / service の所有状況を確認します。
node scripts/ops/secrets.mjs --env staging --services shared,storefront --audit --fail-on-duplicates
  • 共有キーは shared へ寄せ、service 側の重複定義を削除します。
  • 暫定的に上書きを許可する場合は ./scripts/ops/with-env.sh 内の secrets.mjs 呼び出しに --allow-overrides を追加します。

7. ローテーションと露出対策

CI ログに Secret の露出が疑われる場合は、以下を同一インシデント内で実施します。

  1. AWS 管理コンソールで対象の Secret(例:b2b-ecommerce/staging/storefront/XXX)の値を新しい値へ更新する。
aws secretsmanager update-secret --secret-id <SECRET_ID> --secret-string '<UPDATED_JSON>'
  1. GitHub Secrets 更新
  2. サービス再デプロイ