【アドベントカレンダー2025】Secrets Manager vs Parameter Store:社内APIのキー管理、どっちがいい?

はじめに

どうも、開発部の加藤です。社内では「なるみん」て呼ばれてたりします。

普段はぐるなびの店舗ページやインバウンド向けのぐるなび外国語版のサーバーサイドの開発を担当しています。

APIキー認証を入れるとき、地味に悩むのが「キーをどこに置くか」です。 AWSなら候補はだいたいこの2つかなと思います。

この記事では社内APIのAPIキー認証を設計する中で行った2つのサービスの「比較」と「選定」について記載します。

(注)料金・上限は変更されることがあるため、最終判断は公式価格表/制限値も確認してください。

目次

背景

仮想化基盤のコスト見直しにより、API基盤の刷新を行うことになりました。

前提(なぜAPIキー認証?)

認証方式は、Basic認証 / APIキー認証 / トークン認証 など選択肢がいろいろありますが、今回は以下の選定理由からシンプルなAPIキー認証を採用しています。

  • 「どのサービス or システムからのリクエストか」を識別する必要がある
  • 外部からのアクセスは考慮不要なため、セキュリティ強度より 実装・管理のしやすさ を優先

参考までに、それぞれの違いを簡単にマトリクスでまとめます。

方式 主な用途 実装難易度 セキュリティ強度 良いところ 注意点(ありがち)
Basic認証 手軽な保護(管理画面/社内ツール等) 低〜中 実装が最短・対応クライアントが多い 資格情報がそのままなので漏洩影響が大きい。TLS前提。ユーザ管理/権限設計は別途必要になりがち
APIキー認証 システム間連携・呼び出し元識別 シンプルで運用しやすい(「誰の呼び出し」かを区別しやすい) キー配布/失効/ローテの運用が必要。都度直接アクセスせず キャッシュやレート制限も検討
トークン認証(JWT等の独自発行) ユーザ/サービスの属性情報をトークン化 中〜高 署名検証で改ざん検知しやすい。クレームで情報を持てる 失効(ログアウト)や鍵管理、トークン期限設計が難しい。発行基盤が必要
トークン認証(OAuth 2.0) 外部連携・統合認可基盤の利用 標準化された委任モデルで拡張性が高い。Client Credentials等でシステム間も可 システムの構成が複雑になる(認可サーバ/クライアント登録/フロー理解)。社内の単純用途には過剰なことも

比較の前提(今回の要件)

今回の比較は、次のような“現実的にコストが効いてくる”前提で考えました。

  • アクセス規模:秒間数千〜1万リクエスト(高負荷)
  • 認証情報:ID/APIキーの組が最大200件(参照元のシステムの数)
  • 参照形態:APIが稼働するAWSアカウントと認証情報を管理するAWSアカウントが異なる(クロスアカウント参照が必要)
  • ねらい:セキュリティ強度「だけ」ではなく、コストと運用のしやすさも重視

(補足)APIはSREが提供しているEKSのプラットフォームが存在するAWSアカウントで稼働し、認証情報はサービス側のAWSアカウントで管理する必要があるため、クロスアカウント参照を前提としています。

先に結論(ざっくり)

  • Secrets Manager が向いてるパターン
    • 自動ローテーション(自動更新)を使いたい
    • 監査・運用を“シークレット管理専用サービス”に寄せたい
    • シークレット数が少ない/固定費が問題になりにくい
  • Parameter Store(Standard) が向いてるパターン
    • 高頻度Readがある(=アプリ側キャッシュ前提)
    • ID/APIキーの組が増えやすい(最大200件など)
    • できるだけ安く・シンプルに運用したい(クロスアカウント参照も含めて設計する)

(補足)この記事での「ローテーション」は、APIキーなどの秘密情報を定期的に更新し、古いキーを失効させて利用側も新しいキーへ切り替える運用のこと。

今回の前提(社内向け、IDが増える、秒間1万、クロスアカウント参照)だと、Parameter Store + キャッシュから始めるのがバランス良いです。

比較:Secrets Manager と Parameter Store

ざっくり比較表です。

観点 Secrets Manager Parameter Store(Standard)
主用途 “シークレット管理”特化 設定/パラメータ管理(秘密情報も可)
料金感 シークレット数の固定費が出やすい 低コストに寄せやすい
ローテーション 仕組みとして用意されている 自前運用になりやすい
高頻度Read キャッシュしないと辛い キャッシュしないと辛い(+デフォルトスループット注意)
スループット API呼び出し回数が増えると課金/制限が気になる Standardはデフォルト40TPS。高スループット設定やキャッシュが前提
クロスアカウント IAMで可能 IAMで可能(StandardでもAssumeRoleで対応可)

比較で見た観点

まず大前提として、どちらを選んでも都度直接呼び出すこと(直叩き)は避けてキャッシュするのが現実解です。

認証のたびにAPIを呼ぶと、コストもレイテンシも上がります。

また、IDが200件のように増える場合は、Secrets Managerで「IDごとにシークレットを分ける」と固定費が見えやすい一方で、「全部を1つのシークレット(JSON)にまとめる」などで運用を寄せる選択もあります(更新頻度・権限分離とトレードオフ)。

1) コストは「固定費」と「呼び出し回数」で分けて考える

高トラフィック環境では、呼び出し回数課金がすぐ効きます。一方で、Secrets Managerは設計次第で固定費(シークレット数)も効きます。

  • Secrets Manager:シークレット数が増えると固定費が積み上がりやすい(例:IDごとに分ける)
  • Parameter Store(Standard):大量のパラメータを持っても保管コストが出にくい設計に寄せやすい

ここは「200件をどう持つか」が分岐です。

  • 分割管理(IDごと):権限分離しやすい/運用ルールが明確/ただし固定費が見えやすい
  • 集約管理(1つにJSON等):固定費を抑えやすい/ただし更新・権限分離・監査の粒度が落ちがち

2) 「読みに行く回数」を見積もって、最初にキャッシュ戦略を決める

秒間数千〜1万アクセスを、もし毎回Secrets Manager/Parameter Storeへ読みに行くとこうなります。

ざっくり、

  • 10,000 回/秒 × 86,400 秒/日 ≒ 864,000,000 回/日(約8.6億回/日)

のイメージです。ここまで来ると、どちらのサービスでも「料金」以前に「スロットリング・レイテンシ・障害耐性」が問題になります。

現実的には、認証情報はそう頻繁に変わらないはずなので、先にキャッシュ前提で設計します。

  • Redis / メモリ等にキャッシュして「外部取得」は極小化
  • TTLは「漏洩時の影響」「更新頻度」「コスト」を天秤に

3) Parameter Store Standard の“40 TPSの罠”に気をつける

Parameter Store Standard はデフォルトのスループット上限が小さく(一般に40 TPSと言われます)、高負荷時にそのまま当たるとスロットリングします。

この対策は2段構えです。

  • 根本対策:キャッシュで読みに行く回数を減らす
  • 保険:高スループット設定(必要なら)+ SDK標準リトライ(指数バックオフ)の前提

高スループット設定は、Standardのままでも追加課金が発生する場合があります(単価は変更されるので要確認)。

「キャッシュしてるから大丈夫」と思っても、

  • キャッシュ消失(Redis等の障害)
  • 再起動直後のコールドスタート

などで一気にバックエンドへ集中します。例えばこの規模(数千〜1万 rps)だと、Redis等が飛んだ瞬間にParameter Store(Standard)のデフォルト40 TPSへリクエストが雪崩れ込み、ほぼ確実にスロットリングします。

そのため、「保険のスループット設定」に加えて、次のどちらか(または両方)をあわせて検討しておくと安心かもしれません。

  • 多段キャッシュ:Redisが落ちても一定は耐えられるよう、アプリ内メモリ(ローカルキャッシュ)も併用する
  • 古いキーの許容(フェイルオープン寄り):キャッシュ取得に失敗した場合は直ちにエラーにせず、短時間だけ古いキーを許容して回復を待つ(許容範囲は要件で決める)

4) Secrets Manager は“便利機能”の分だけ設計の自由度も増える

Secrets Managerは、ローテーションや監査など「運用の型」が強いのが魅力です。 一方で高頻度Readの世界では、結局キャッシュ前提になるため、

  • どの単位でシークレットを切るか(1つ/200個)
  • ローテーション時にアプリ側のキャッシュをどう追随させるか

を先に決めないと、便利機能が逆に“運用コスト”になることがあります。

5) クロスアカウント参照は「IAMだけ」では終わらない

どちらの方式でも、クロスアカウント参照はだいたい以下がセットです。

  • 参照元アカウント:AssumeRole できる権限
  • 参照先アカウント:対象リソースへの Get* 権限
  • 暗号化している場合:KMSの Decrypt を許可(キー/ポリシーの両面)

特にParameter StoreのSecureString(KMS暗号化)を使う場合は、 ssm:GetParameter だけでなく KMS側の許可漏れ でハマりやすいです。

6) コストを下げるコツは「取得回数を下げる」か「取得対象をまとめる」

  • キャッシュ(起動時ロード/定期ポーリング等)で取得回数を抑える
  • 必要な情報だけを保管し、取得対象を小さくする(分割しすぎない・持ちすぎない)

結論:どちらを選ぶべきか(選定のポイント)

今回のような「社内向けAPIキー」「IDが増えやすい」「なるべくシンプルに運用したい」だと、

  • 保存先は Parameter Store(Standard, KMS暗号化)
  • 認証処理は キャッシュ前提

がバランス良いと判断しました。

一方で、外部提供や厳密なローテーション要件が出たら、Secrets Manager(やAPI Gateway/Cognito)へ寄せる判断も自然です。

運用の注意点(ハマりどころ)

  • TTL: 長くすると取得API負荷は下がるが、漏洩時の影響が伸びる(要件で決める)
  • キャッシュ戦略: “全リクエストでAPIキーを呼ぶ”は避ける(コスト/レイテンシ/スロットリング)
  • SSMスループット: Parameter Store Standard はデフォルト 40 TPS。高負荷なら設定/設計で吸収する
  • クロスアカウント参照: AssumeRole 前提で最小権限に寄せる
  • ローテーション: Secrets Managerは仕組みがある/Parameter Storeは運用設計が重要

おまけ(Parameter StoreのAPIキーの運用例)

ヘッダー

  • id: 利用コンテンツ(呼び出し元)を識別するID
  • key: そのIDに紐づく秘密鍵

作成ルール

  • ID: コンテンツを表す文字列を kebab-case(例: sample-page
  • キー: 英数字を含む 32文字(例: EXAMPLE_KEY_1234567890_DUMMY

※両方ともサンプルデータです

Parameter Store の命名(例)

以下の形式で保存します。

/api-name/api-key/{各参照元のid}

値(ParameterのValue)に key を入れ、KMSキーで暗号化しておきます。

パラメータ作成(コンソール例)

  • Systems Manager > Parameter Store の作成画面から登録
  • パラメータ名は /api-name/api-key/{id}
  • 種別は暗号化(KMSキーを使用)

まとめ

Secrets Manager と Parameter Store の比較で一番大事なのは、「どっちが優秀か」より 自分の要件(ローテ/固定費/スループット/運用)に合うか でした。

  • ローテーションや“シークレット管理”に寄せたい → Secrets Manager
  • IDが増える・安くシンプルに始めたい(キャッシュ前提) → Parameter Store

そして、どちらを選んでも キャッシュ前提 、で設計することで性能もコストも一気に安定するかなと思います。


2018年新卒入社。主にサーバーサイドのエンジニアやってます。
プライベートはアニメ観てるか寝てます。