AWS IAM Role の権限設計に深く潜る
IAM Role の Policy と Trust Relationship の責任分業を解き明かす
クラウドを始めたばかりのユーザーなら、
IAM に対して愛と恨の感情を持ったことがあるはずです。
AWS の様々な機能を段階的に理解していくにつれて、
AWS が推奨するベストプラクティスを学び始め、
ロール、つまり IAM Role で実行することを心がけ始めます。
実際に IAM Role の奥妙さを理解するのに少し時間をかけたら、
これが実に見事な設計だということに気づくでしょう。
伝統的な Web での権限管理
伝統的な Web システムでは、権限は通常 2 つの事柄に分かれています:
- あなたは誰ですか(認証)
- あなたは何ができますか(認可)
例えば、ユーザーがログインしたら、システムはまずその人が誰であるかを確認します。通常データベース内で Account にマップされます。
小さいシステムは Account と Permission を直接対応させるかもしれません。
ある程度の規模になったシステムは、ロール Role を設計するかもしれません。
Account は複数の Role にバインドできて、
各 Role は異なる Permission にバインドできます。
この概念を AWS に適用しても、本質的には同じです。ただ、ロールが AWS の身元システムに置き換わるだけです。
IAM
AWS では、IAM Role は 2 つのことを分離できます:
- 「この身元を得られるのは誰か」
- 「得た後は何ができるか」
この分離こそが、IAM Role 設計が秀逸な理由です。
IAM Role は 2 つの部分から成り立っています:
- 信頼関係(Trust Relationship):誰がこのロールを引き受けられるかを定義する
- ポリシー(Policy):このロールがどのリソースに対してどのアクションを実行できるかを定義する
つまり、
信頼関係はエントリールールで、
ポリシーはエントリー後の動作ルールです。
信頼関係
信頼関係の重点は権限そのものではなく、「誰がこのロールを演じる資格があるか」です。
IAM Role を会社の職位と考えるなら、信頼関係は「誰がこの職位に任命できるか」を決めるものです。
例えば、次の信頼ポリシーは:EC2 サービスだけがこのロールを引き受けられることを意味しています。
1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
あなたのシナリオが EKS IRSA、GitHub Actions OIDC、またはクロスアカウントアクセスの場合、Principal は Federated Provider または他の AWS Account に置き換わりますが、核となる概念は変わりません:
まず、誰がこのロールを得られるかを決めましょう。
ポリシー
ポリシーこそが、皆が「権限」と呼ぶものです。
それが説明するのは:あるエンティティが正常にロールを引き受けた後、具体的に何ができるかです。
例えば、次のポリシーは指定した S3 バケット内のオブジェクトの読み取りだけを許可しています:
1
2
3
4
5
6
7
8
9
10
11
12
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
ここで最も一般的な誤解は:
信頼関係が厳しければ、権限は確実に安全だと思うことです。
実際には、ポリシーが過度に寛容だと(例えば Action: * + Resource: *)、誰かがロールを引き受けられれば、リスクは依然として高いのです。
その逆もしかり。ポリシーがどんなに厳密でも、信頼関係が広すぎると(例えば、アクセスできない Principal も引き受けられる)、問題が生じます。
IAM Role 設計時に尋ねるべき 4 つの質問
実務では、JSON を書く前にこの 4 つの質問を必ずします:
- 誰がこのロールを必要としていますか?
- この身元がロールを引き受けるための条件は何ですか?
- 引き受けた後、最小限どのアクションとリソースが必要ですか?
- どのような操作は絶対に許可されてはいけませんか?
このアプローチの利点は、「アイデンティティエントリー」と「権限スコープ」を別々に収束させることで、最初からすべての権限をユニバーサルロールにまとめる罠を避けられることです。
完全なメンタルモデル
IAM Role を 2 つのロックがある扉だと考えるのが良いでしょう:
- 最初のロックは信頼関係:扉に入る資格があるか
- 2 番目のロックはポリシー:入った後、どこに行けるか
両方のロックが正しく設計されてこそ、権限モデルは本当に安全で保守可能になります。
まとめ
IAM Role が便利なのは、単に長期 Access Key を置き換えるからではなく、より重要なことに、権限モデルを 2 つの明確な側面に分割するからです。
信頼関係とポリシーの責任分業を理解したら、EC2、Lambda、EKS IRSA、またはクロスアカウント認可のいずれでも、設計はより一貫性を持つようになります。
1 文で要約するなら:
まずロールを演じられる人を定義し、その後ロールができることを定義する。
これが IAM Role 権限設計の核です。