一覧SP-16-2 · CSPM・CIEM:クラウド構成と権限

クラウドの権限と委譲の分析

直接の実効権限と、別の主体へ移ることで得られる権限を分けて評価します。

説明

CIEMはクラウド主体の権限や利用状況を調べます。付与された許可だけでなく、上限となる境界、明示的拒否、別ロールへ委譲する経路も確認する必要があります。

許可集合と境界集合を使う限定モデルで実効操作を求めます。使用記録と比較した後、別ロールへの委譲をたどります。AWS IAM全条件の評価器ではありません。

直接の実効権限と、別の主体へ移ることで得られる権限を分けて評価します。

1三つの条件を表示する

read・write・delete・assumeという教材用の操作名です。

from sp16 import * from sp02 import show db=connect() print('allow',sorted三つの条件を表示する(ALLOW)) print('boundary',sorted(BOUNDARY)) print('deny',sorted(DENY))

境界は上限であり、それだけで新しい操作を許可する集合ではありません。

2許可と境界の共通部分を求める

両方にある操作だけを残します。

print(sorted(ALLOW & BOUNDARY許可と境界の共通部分を求める))

deleteが外れます。許可文にdeleteがあっても、今回の境界では使えません。

3明示的拒否を適用する

共通部分からdenyを引きます。

active=effective明示的拒否を適用する(ALLOW,BOUNDARY,DENY) print(sorted(active))

readとassumeだけです。writeは許可と境界に含まれていても明示的拒否で外れます。

4境界だけにある操作が付与されないことを確認する

許可をreadだけにした場合です。

print(sorted(effective境界だけにある操作が付与されないことを確認する({'read'},BOUNDARY,DENY)))

readだけです。境界にassumeが含まれるだけではassumeを実行できません。

5観測期間に使われなかった実効権限を探す

使用記録の範囲は10秒と20秒の固定2行です。

used={r[0] for r in db.execute("SELECT DISTINCT action FROM usage")} print('used',sorted(used)) print('not_seen',sorted(active-used観測期間に使われなかった実効権限を探す))

assumeは未観測です。未使用と判断するには、記録の期間・サービス・アカウント範囲を確認します。

6委譲による別主体への経路を読む

builderからdeploy-roleへ移る関係がある資料です。

show委譲による別主体への経路を読む(db,"SELECT * FROM delegation ORDER BY src")

deploy-roleにはrelease-secretのreadがあります。元の主体の直接権限だけでは、この先の到達範囲を表せません。

7委譲を経由する対象を抽出する

assumeの先のread対象を結びます。

show(db,"SELECT a.src,a.dst AS role,b.dst AS target FROM delegation a JOIN委譲を経由する対象を抽出する delegation b ON a.dst=b.src WHERE a.action='assume' AND b.action='read'")

builder→deploy-role→release-secretという経路です。実際には信頼ポリシー、セッション条件、対象資源側の規則も照合します。

まとめ

許可、境界、拒否の役割を分けます。

使用記録の範囲を添えて未観測権限を評価します。

委譲先の権限もたどります。

操作履歴と解説を振り返れます。

Python 3.15 / 固定のクラウド構成と限定した評価モデル

1
from sp16 import * from sp02 import show db=connect() print('allow',sorted(ALLOW)) print('boundary',sorted(BOUNDARY)) print('deny',sorted(DENY))
allow ['assume', 'delete', 'read', 'write']
boundary ['assume', 'read', 'write']
deny ['write']
2
print(sorted(ALLOW & BOUNDARY))
['assume', 'read', 'write']
3
active=effective(ALLOW,BOUNDARY,DENY) print(sorted(active))
['assume', 'read']
4
print(sorted(effective({'read'},BOUNDARY,DENY)))
['read']
5
used={r[0] for r in db.execute("SELECT DISTINCT action FROM usage")} print('used',sorted(used)) print('not_seen',sorted(active-used))
used ['read']
not_seen ['assume']
6
show(db,"SELECT * FROM delegation ORDER BY src")
src | dst | action
builder | deploy-role | assume
deploy-role | release-secret | read
7
show(db,"SELECT a.src,a.dst AS role,b.dst AS target FROM delegation a JOIN delegation b ON a.dst=b.src WHERE a.action='assume' AND b.action='read'")
src | role | target
builder | deploy-role | release-secret

演習完了