概要
アプリケーションを開発する際、「誰が」「何に対して」「どの操作を」実行できるかを制御する認可(Authorization)の仕組みは欠かせません。認可ロジックをアプリケーションコード内にハードコードすると、ポリシーの変更や監査が困難になり、セキュリティリスクが増大します。
Amazon Verified Permissions は、アプリケーションの認可ポリシーを一元的に管理・評価するサービスです。Cedar ポリシー言語を使用してきめ細かいアクセス制御ルールを定義し、アプリケーションから API を呼び出して認可判定を行います。
本記事では、Verified Permissions の基本概念を理解し、ポリシーストアの作成からポリシーの定義、認可リクエストのテストまでを体験します。

この記事のメリット
- アプリケーション認可の基本概念(認証と認可の違い、ポリシーベースのアクセス制御)を理解できる
- Cedar ポリシー言語の基本構文を習得できる
- ポリシーストアの作成とスキーマの定義方法を体験できる
- ポリシーの作成と認可リクエストのテスト方法を把握できる
- コードから認可ロジックを分離するアーキテクチャパターンを理解できる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

クラウドおさる
クラウドおさるはじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
Amazon Verified Permissions とは



とひさん、Amazon Verified Permissions とはどんなサービスでござるか?
アプリケーション向けのスケーラブルな認可サービスだよ。認可ロジックをアプリケーションコードから分離して、Cedar ポリシー言語で定義されたポリシーに基づいてアクセス制御を行うんだ。



認可ロジックをコードから分離する……具体的には、どんな場面で使われるのでござる?
主なユースケースは以下のようなものだね。
- Web アプリケーションやモバイルアプリケーションのきめ細かいアクセス制御
- マルチテナントアプリケーションのテナント間分離
- ロールベースアクセス制御(RBAC)の実装
- 属性ベースアクセス制御(ABAC)の実装



アプリの認可を、まるごと外で管理できるのでござるな!
主要コンポーネント



Verified Permissions を構成するコンポーネントには、どんなものがあるのでござるか?
主要なコンポーネントは以下の 4 つだよ。
| コンポーネント | 説明 |
|---|---|
| ポリシーストア | ポリシーとスキーマを格納するコンテナ |
| スキーマ | アプリケーションのエンティティタイプとアクションを定義する構造情報 |
| ポリシー | 「誰が」「何に対して」「何をできるか」を Cedar 言語で記述したルール |
| テンプレート | パラメータ化されたポリシーのひな形 |





ポリシーストアが全体の入れ物になっていて、その中にスキーマとポリシーが入るイメージでござるな。
Cedar ポリシー言語



Cedar ポリシー言語とは何でござるか? 弊猿、初めて聞いたでござる。
Cedar は Amazon が開発した認可ポリシー記述用の言語なんだ。人間が読みやすく、機械的な解析にも適した構文を持っているよ。基本構造はこんな感じだね。
permit (
principal == <プリンシパル>,
action == <アクション>,
resource == <リソース>
) when {
<条件>
};



permit で許可するルールを書くのでござるな。各要素は、どういう意味でござるか?
主要な要素をまとめるとこうなるよ。
| 要素 | 説明 | 例 |
|---|---|---|
permit / forbid | 許可または拒否のエフェクト | permit(...) |
principal | 操作を実行するエンティティ | User::"alice" |
action | 実行する操作 | Action::"viewDocument" |
resource | 操作対象のエンティティ | Document::"report.pdf" |
when / unless | 追加条件 | when { principal.role == "admin" } |



「誰が」「何をして」「何に対して」という構造がはっきりしていて、読みやすいでござる!
認可の判定ロジック



複数のポリシーがある場合、どうやって最終的な判定が決まるのでござる?
Verified Permissions の認可判定は以下のルールに従うんだ。
- デフォルトは 暗黙の拒否 である(明示的な
permitがなければアクセスは拒否される) - 1 つでも
forbidポリシーに該当すると、permitポリシーに関係なく 明示的な拒否 となる permitポリシーに該当し、forbidに該当しない場合のみ 許可 される



forbid があると、permit があっても拒否されるのでござるか……なかなか厳しいでござるな。
この判定ロジックは IAM ポリシーの評価ロジックと類似しているんだ。セキュリティ的には「明示的な拒否が最優先」という考え方が大事だからね。



なるほど、IAM と同じ考え方なら理解しやすいでござる! 猿山でも、長老会の「入るべからず」はどんな許可より強いのでござる。
スキーマの役割



スキーマには、どういう役割があるのでござるか?
スキーマはアプリケーションのデータモデルを定義するもので、以下の情報を含むよ。
- エンティティタイプ: プリンシパルやリソースの種類(例:
User、Document) - アクション: 実行可能な操作(例:
viewDocument、editDocument) - 属性: 各エンティティタイプが持つプロパティ(例:
Userのrole属性)



スキーマがなくても、ポリシーは書けるのでござるか?
スキーマを定義することで、ポリシー作成時のバリデーションが有効になり、誤ったポリシーの作成を防止できるんだ。型チェックみたいなものだと思えばいいよ。



開発のときにミスを早めに見つけられるのは、助かるでござる!
実践
前提条件
- リージョン:
ap-northeast-1(東京) - IAM ユーザーまたはロールに Amazon Verified Permissions の操作権限があること
作成するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| ポリシーストア | PhotoFlash(サンプルから作成。説明・名前空間はサンプル名で自動設定) | ポリシーとスキーマの格納先 |
| ポリシー | (複数作成) | 認可ルールの定義 |
ステップ1: ポリシーストアの作成
AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。
上部の検索バーに Verified Permissions と入力し、表示された「Amazon Verified Permissions」を選択します。
「ポリシーストアを作成」をクリックします。
「開始オプション」で「サンプルポリシーストアから開始」を選択します(ほかに「ガイド付きセットアップに従う」「API ゲートウェイと ID プロバイダーによるセットアップ」「空のポリシーストアを作成する」があります)。
表示されるサンプルの一覧から「PhotoFlash」を選択します。これは写真共有アプリケーションを想定したサンプルで、ユーザー、グループ、アルバム、写真といったエンティティとアクションが事前定義されています。
「ポリシーストアの詳細」の「ポリシーストアの説明」と「名前空間」にはサンプル名 PhotoFlash が自動で入り、変更できません。「保存時の暗号化」「タグ」はデフォルトのままにします。


「ポリシーストアを作成」をクリックします。
作成が完了すると、ポリシーストアの詳細画面が表示されます。


ステップ2: スキーマの確認
左側ナビゲーションの「スキーマ」を選択します。
スキーマは「ビジュアルモード」と「JSON モード」で表示を切り替えられます。ビジュアルモードには「アクション図」「エンティティタイプ図」のタブと、下部に「エンティティタイプ」「アクション」の一覧があります。
PhotoFlash サンプルには以下のエンティティタイプとアクションが定義されています(名前空間は PhotoFlash)。
- エンティティタイプ(5 件):
User、Account、Album、FriendGroup、Photo。UserはFriendGroupのメンバーになれます - アクション(13 件):
ViewPhoto、CreatePhoto、DeletePhoto、CommentPhoto、SharePhoto、SetPrivacyFlag、UpdateAlbum、UpdateFriendGroup、BlockAccountAccess、CloseAccountと、アクショングループFullPhotoAccess、LimitedPhotoAccess、ManageAccount
「アクション」の一覧では、各アクションがどのプリンシパルタイプ(User)とリソースタイプ(Photo や Account)に適用できるかを確認できます。


ステップ3: ポリシーの確認
左側ナビゲーションの「ポリシー」を選択します。
サンプルとして作成された静的ポリシー「Users have full control over their own accounts」が一覧に表示されます。行のラジオボタンを選択すると、画面下部のパネルに「ポリシーの内容」として Cedar 言語で記述されたポリシーが表示されます。
このポリシーは以下の内容です。
permit (principal, action, resource)
when { resource in principal.Account };
「すべてのプリンシパルに対して、自分のアカウントに属するリソースへのあらゆる操作を許可する」という意味です。なお、サンプルには「ポリシーテンプレート」も 3 つ作成されており、左側ナビゲーションの「ポリシーテンプレート」で確認できます。


ステップ4: 新しいポリシーの作成
「ポリシーの作成」→「静的ポリシーを作成」を選択します。ポリシーの作成は「ポリシーの範囲」「詳細」の 2 ステップです。
ステップ 1: ポリシーの範囲
「フレンドグループ admins に属するユーザーに対して、すべてのアクションを許可する」というポリシーになるよう、以下を設定します。
- ポリシーの効果:
許可 - プリンシパルの範囲:
プリンシパルのグループを選択し、エンティティタイプPhotoFlash::FriendGroup、エンティティ識別子adminsを指定 - リソースの範囲:
すべてのリソース - アクションの範囲:
すべてのアクション


「次へ」をクリックします。
ステップ 2: 詳細
「ポリシー」に、範囲の設定から生成された以下の Cedar ポリシーが表示されます。ここで直接編集することもできます(エンティティタイプは名前空間 PhotoFlash:: を付けて書きます)。
permit(principal in PhotoFlash::FriendGroup::"admins", action, resource);
- ポリシーの説明 – オプション:
admins グループに全権限を付与


「ポリシーを作成」をクリックします。一覧に 2 つ目のポリシーが追加されます。
ステップ5: 認可リクエストのテスト
左側ナビゲーションの「テストベンチ」を選択します。
テストベンチでは、認可リクエストをシミュレートして、ポリシーの評価結果を確認できます。「ビジュアルモード」のまま、以下のリクエストを設定します。
- プリンシパル: エンティティタイプ
PhotoFlash::Userを選択し、エンティティ識別子にaliceと入力します - 「親」の「親を追加」をクリックし、エンティティタイプ
PhotoFlash::FriendGroup、エンティティ識別子adminsを指定します(alice が admins グループに属していることを表します) - 「属性」の
Accountには、エンティティ識別子acct1を入力します(スキーマで必須の属性なので何か値が必要です) - リソース: エンティティタイプ
PhotoFlash::Photoを選択し、エンティティ識別子にphoto123と入力します - アクション: プリンシパルとリソースを指定すると選べるようになるので、
PhotoFlash::Action::"ViewPhoto"を選択します


画面上部の「承認リクエストを実行」をクリックします。
結果として「決定: 許可」(ALLOW)または「決定: 拒否」(DENY)が表示されます。「満たされたポリシー」に、判定に使われたポリシーの ID(ここでは admins グループに全権限を付与したポリシー)が表示されます。


ステップ6: 拒否ポリシーの追加と動作確認
forbid ポリシーの動作を確認するため、新しいポリシーを作成します。
「ポリシー」に戻り、「ポリシーの作成」→「静的ポリシーを作成」を選択します。
「ポリシーの範囲」で以下を設定し、「次へ」をクリックします。
- ポリシーの効果:
禁止 - プリンシパルの範囲:
すべてのプリンシパル - リソースの範囲:
すべてのリソース - アクションの範囲:
特定のアクションセットを選択し、PhotoFlash::Action::"DeletePhoto"にチェック
「詳細」に以下の Cedar ポリシーが生成されます。
forbid(principal, action in [PhotoFlash::Action::"DeletePhoto"], resource);
- ポリシーの説明 – オプション:
すべてのユーザーの写真削除を禁止


「ポリシーを作成」をクリックします。
テストベンチに戻り、ステップ5 の設定のままアクションだけを変更してテストします。
- プリンシパル:
PhotoFlash::FriendGroup::"admins"に属するPhotoFlash::User::"alice"(ステップ5 と同じ) - リソース:
PhotoFlash::Photo::"photo123"(ステップ5 と同じ) - アクション:
PhotoFlash::Action::"DeletePhoto"に変更
admins グループには全権限を付与する permit ポリシーがありますが、forbid ポリシーが優先されるため、結果は「DENY」となることを確認します。


まとめ
- Amazon Verified Permissions はアプリケーションの認可ロジックをコードから分離し、Cedar ポリシー言語で一元管理するサービスである
- ポリシーストアにスキーマとポリシーを定義し、API 経由で認可判定を行う
- Cedar ポリシーは
permit(許可)とforbid(拒否)の 2 種類があり、forbidは常にpermitに優先する - スキーマを定義することで、エンティティタイプやアクションのバリデーションが有効になり、誤ったポリシーを防止できる
- テストベンチを使用して、認可リクエストのシミュレーションとポリシーの検証が可能である
- RBAC と ABAC の両方のアクセス制御パターンを実装できる
参照先
- Amazon Verified Permissions とは – Amazon Verified Permissions
- ポリシーストア – Amazon Verified Permissions
- Cedar ポリシー言語 – Amazon Verified Permissions
- スキーマ – Amazon Verified Permissions
- 認可リクエストのテスト – Amazon Verified Permissions










