AWS Summit『サーバーレス API のセキュリティ』参加して学んだこと
こんにちは~ 浮田です。
■ TL;DR
- サーバーレス API のセキュリティは「認証/認可」の前に、IAM を土台にした多層防御(Inspector / GuardDuty / 入力検証 / WAF)という土台がある
- 認可は OAuth 2.0 / OIDC が基本。トークンの役割(アクセス/リフレッシュ/ID)を押さえるのが第一歩
- コードに散らばる認可は Amazon Verified Permissions で外出しして集約できる
- これらの基礎は、そのまま AI エージェントの認可(AgentCore Identity の Inbound/Outbound) につながる
- 結論:認可とは「AI にどこまで任せるか」ではなく「任せる範囲を外から保証する」仕組み
AWS Summit のブレイクアウトセッション 「サーバーレス API のセキュリティ ─ API 認可の基本を押さえ、AI エージェント時代に備える ─ [CNS315]」 に参加してきました。本記事は、その参加レポートと、そこで得た学びのメモです。
■ はじめに:「とりあえず Cognito」から一歩踏み込みたくて
認証と認可は大事だ、とは思っています。思ってはいるんですが、正直なところ自作の Web アプリでは「とりあえず Cognito 入れとけばOK」くらいの感覚で来ていました。ログインできて、トークンが飛んできて、なんとなく動く。それで満足してました。
でも「で、結局どのユーザーが何にアクセスしてよくて、それをどこで止めてるの?」と聞かれると、うまく答えられないと思います。
認証と認可について、自分はちゃんと理解できていないな、という自覚がありました。
今回このセッションを選んだのは、認証と認可の理解を深めたかったからです。
■ セッションの全体像
題材はフィットネスアプリ。アジェンダは以下の流れでした。
- API セキュリティの基礎
- アイデンティティ(ID)を意識した API 認可
- AI エージェントの認可 ── はじめの一歩
- まとめ
題材アプリは、スマートウォッチの運動データを Activities API(API Gateway → Lambda → DynamoDB)に送る、という構成。このフィットネスアプリを例に話が進みました。
■ API セキュリティの基礎 ── 多層防御という考え方
認証と認可は別物
最初の整理はセキュリティの基本!認証と認可の違いからです。
- 認証(Authentication):あなたは誰か
- 認可(Authorization):あなたは何をしてよいか
この2つは別の枠組みで、 AI エージェントの世界でも「Inbound(誰が使うか)」と「Outbound(何にアクセスしてよいか)」が重要です。
■ IAM を土台にする
サーバーレスのセキュリティは IAM が土台になります。IAM のアクセス制御を、2つの面に分けて考えます。
- コントロールプレーン(リソースの管理): CreateFunction (Lambda)、UpdateTable (DynamoDB) など
- データプレーン(リソースの操作・実行): Invoke (Lambda)、PutItem (DynamoDB) など
「リソースを作る・変える権限」と「リソースを動かす権限」は別物として扱う、という整理です。言われてみれば当然なのに、自分はここを意識せず雑に権限を渡してました。
■ Lambda のセキュア化は2軸
Lambda 関数を守るときは、向きの違う2つのポリシーで考えます。
- リソースベースのポリシー:「誰がこの関数を呼び出せるか」を定義(例:「API Gateway A から Lambda 関数 B を呼び出す」)
- 実行ロール:「この関数がどの AWS リソースにアクセスできるか」を定義(例:「Lambda 関数 B は DynamoDB テーブル C に書き込み可能」)
「呼ばれる側の入口」と「自分が外に出ていく権限」を分けて考える。この2軸は後の AI エージェントの「インバウンド/アウトバウンド」にも同じことが言えます。
■ 最小権限の原則
そして最小権限。
「目的の作業に必要な最小限の権限の集合」で、しかも一度決めて終わりではなく、権限設定 → アクセス検証 → 権限調整のサイクルで時間とともに見直していくもの、という説明でした。
リソースごとに専用ロールを用意し、きめ細かく付与する。
データベースや外部 API 連携も同じ思想で、使えるなら IAM を優先、ダメなら Secrets Manager や Parameter Store でシークレットを管理し、ハードコードしない。
■ 開発スピードを止めない多層防御
「守りを固めると開発が遅くなる」というジレンマに対して、開発スピードを止めない多層防御として4つのサービスが、リクエストのライフサイクルに沿って紹介されました。
- Amazon Inspector デプロイ前のコードと依存関係を分析(脆弱なライブラリのバージョンや、ハードコードされた認証情報を検出)
- Amazon GuardDuty 実行中の Lambda 関数のランタイム異常を検出(VPC 接続の有無に関わらず、設定変更不要で使える)
- 入力検証 API Gateway 側ではスキーマ(モデル)でリクエストを受け付ける前に検証。Lambda 側では Powertools for AWS Lambda で処理前に検証
- AWS WAF API に届く前のリクエストを、IP ベースの制御やレートベースルール、AWS マネージドルールで保護
これでデプロイ前 → 実行中 → 入口、と層を重ねて守れます。
■ OAuth 2.0 = パスワードを渡さず「限定権限」を貸す
フィットネスアプリには Activities API、Routes API… と機能ごとに API が増えていきます。それぞれに認証認可が必要になり、それを標準的に担うのが OAuth2.0 です。
一言でいうと、パスワードを渡さずに、アプリに特定の権限だけを安全に貸し出す仕組みで、認可のための標準規格になります。
● ホテルのバレーキーのたとえ
係員に渡すのはバレーキーです。運転と駐車はできますが、トランクは開けられません。マスターキー(=パスワード)を渡す必要はないわけです。
OAuthの アクセストークンはこのバレーキーに相当します。限定された権限(スコープ)を持ち、いつでも無効化でき、有効期限もあります。
● 認可コードフロー
フィットネスアプリの例で、別アプリにワークアウトデータを読ませる流れです。

ポイントは、いきなりトークンを渡さず一度「認可コード」を挟むことです。
トークンが URL に露出するのを防ぎ、交換はサーバー側で安全に行えます。
■ OIDC は OAuth の「上」に乗る認証レイヤー
混同しがちですが、OAuth2.0と OIDC は別物で、親子関係にあります。
|
|
OAuth2.0 |
OIDC |
|
担うもの |
認可(Authorization) |
認証(Authentication) |
|
問いの形 |
何をしてよいか |
誰なのか |
|
発行されるもの |
アクセストークン |
ID トークン(+アクセストークン) |
|
用途 |
API へのアクセス権 |
ログイン・本人確認 |
OAuth2.0 単体には「このトークンを持っているのが誰か」を知る標準がありません。
そこで OIDC が認可コードフローの交換時に ID トークン(JWT) も一緒に返すようにしました。
「Google でログイン」のあの仕組みが OIDC です。
● 関連するトークン
そして3種類のトークン。OAuth2.0 と OIDC の境界です。
|
トークン |
役割 |
区分 |
|
アクセストークン |
短期間有効。保護されたリソースへのアクセス時に提示し、許可された操作範囲(スコープ)を定義 |
OAuth2.0 |
|
リフレッシュトークン |
長期間有効。再ログインなしに期限切れのアクセストークンを自動更新 |
OAuth2.0 |
|
ID トークン |
短期間有効。ユーザーの ID 情報(名前・メール等)を含み、リクエスターが「誰か」を示す認証の証明 |
OIDC |
アクセストークンとリフレッシュトークンが OAuth2.0、ID トークンが OIDC。
■ Verified Permissions = 認可をコードの外に出す
従来は「会員だけ」「自分のデータだけ」といった判定を Lambda の if 文に書き込んでいました。
これだとロジックが各所に散らばり、「結局、誰が何にアクセスできるのか?」に即答できなくなります。
そこでAmazon Verified Permissionsを使用して認可をコードの外で管理します。
● AVP(Amazon Verified Permissions)とは
アプリの「誰が何にアクセスしてよいか」という認可ルールを、コードの外で一元管理できる AWS のフルマネージドサービスです。ルールは Cedar というポリシー言語で書き、アプリは「このユーザー、この操作してOK?」と問い合わせるだけ。認可ロジックを if 文の山からポリシーに追い出せるので、見通しと監査性が上がります。
※Cedarは、AWS が開発した認可ルールを書くための専用言語です。普通のプログラミング言語と違って、認可だけに特化しているのが特徴です。
■ Cedar の基本:4つの要素(Principal / Action / Resource / Context)
Cedar は Principal(誰が)/ Action(何を)/ Resource(どれに)/ Context(どんな状況で) で「誰が何にアクセスできるか」を宣言的に書きます。
RBAC も ABAC も表現できます。
// 自分のワークアウトしか見られない
permit (
principal,
action == FitnessApp::Action::"getWorkout",
resource
)
when {
resource.owner == principal
};
● permit と forbid ──「原則OK、でもこの人だけNG」
permit(許可)だけでなく forbid(明示的な禁止)があり、Deny が一つでもあれば Allow より優先されます(deny-overrides)。
順番や重複で結果が変わらないので、安全側に倒れます。
// ① 会員はマイページを見られる
permit (
principal in FitnessApp::Group::"member",
action == FitnessApp::Action::"viewPage",
resource == FitnessApp::Page::"members"
);
// ② ただし特定ユーザーだけは除外
forbid (
principal == FitnessApp::User::"alice",
action,
resource == FitnessApp::Page::"members"
);
● PDP と PEP を分ける
AVP を理解する鍵は、判定する人(PDP)と、実際に通す/止める門番(PEP)を分けることです。

API Gateway が PEP(門番)、Verified Permissions が PDP(判定役)です。
AVP は ID ソースとして Cognito ユーザープールや OIDC プロバイダーをサポートし、前段で発行されたトークンをそのまま入力にします。トークン内の cognito:groups などのクレームを読んで RBAC を効かせられます。
AVP がやるのは「許可/拒否」の判定だけです。実際に止めるのはアプリ側(PEP)の責務になります。
そして UI でボタンを隠すだけでは防御になりません(API を直接叩かれてしまいます)。本丸の判定は必ずバックエンドで効かせる必要があります。
■ そして AI エージェント時代へ ── AgentCore Identity
AI エージェントには、ふつうの API と違って 方向の違う2つの認可が必要になります。

- Inbound Auth(入り口):誰がこのエージェントを使ってよいか。ここは従来の認証とほぼ同じ世界です。
- Outbound Auth(出口):エージェントが外部ツールにユーザー本人に代わってアクセスします。
Amazon Bedrock AgentCore Identity は、この面倒な認証・認可のやり取りをまるごと肩代わりしてくれます。
へぇ~と思ったのは、自分では認証認可の本体をやらないという割り切りです。
Cognito / Auth0 / Microsoft Entra ID といった既存プロバイダーとやり取りして Credential を取得するプロセスを代行し、取得したトークンを Token Vault に安全に保管して再利用します。一度同意すれば、毎回ユーザーに許可を求めずに済みます。
■ まとめ:「AI にどこまで任せるか」ではなく「任せる範囲を外から保証する」
セッションを聞き終えて、感じたこと。
認可の話というと「AI の判断をどこまで信用するか」に聞こえます。
でも認可がやっているのは逆向きで、AI が何を考え何を試みようが、技術的に触れる範囲をあらかじめ外側で区切っておくことです。AI の善意や賢さに頼りません。
そして境界が外でガチッと決まっているからこそ、むしろ安心して多くを任せられます。「暴走してもこの範囲だけ」とわかっていれば、思い切って自律的に動かせるわけです。
- AI がどこまで賢い/自律的か(能力の話)
- AI がどこまで触れてよいか(権限の話)
この2つを切り離せるのが認可の価値だと感じました。
AI がどんどん賢くなる時代だからこそ、「賢さ」と「権限」を分けて管理できる仕組みの重要度が上がっています。
いいタイミングで聞けたセッションでした。