IAMロールの権限設定漏れ、デプロイ前に気づきたい!
AWS上で動かすアプリケーションを開発していると、どうしてもアプリケーションが利用するAWSのAPIを利用する権限を付与し忘れ、動かしてみたら権限エラーになることがある。単純に付与し忘れていることもあるし、権限が必要と認識しておらず思わぬエラーで気づくこともある。常々どうにかならないだろうかと思っていたが、GitHub Actions Workflowでチェックする仕組み iam-policy-checker を作ったので紹介する。
iam-policy-checkerはTypeScriptで実装した内製ツールで、ECSタスク定義の設定ファイルからエントリーポイントを検出し、コードを静的解析して呼び出されるAWSのAPIを取得し、AWS上のIAMロールでそのAPIがアクションとして許可されているかをチェックするもの。チェックできていない場合は不足アクションとして出力し、PullRequestのチェックを落とすようになっている。これにより、デプロイ前に少なくともアクションを許可できているかどうかを確認できるというわけである。また、実際には呼び出していない権限のチェックも可能にして過剰分・不足分の両方検出できるようにした。
特徴
主要な特徴を3つ紹介する。
可能な限り呼び出されるコードをたどることで高い精度を実現する
AWS Service Referenceを使ってAPI呼び出しから許可すべきIAMのアクションを解決する
AWS Service Referenceからはわからない暗黙の依存を管理可能にする
1. 可能な限り呼び出されるコードをたどることで高い精度を実現する
tree-sitterや自前のパーサーを使うのではなく、TypeScriptの型チェッカーを使うようにしたり、動的dispatchを追跡可能にしたり、SDKの実装内部も追跡したり、NodeJSのワーカースレッドも追跡したりとできる限り呼び出されるコードを追跡することで呼び出す可能性のあるAPIの網羅度を上げることができた。解析対象となるECSタスク定義も自動取得することで検査漏れがないようにしてある。
2. AWS Service Referenceを使ってAPI呼び出しから許可すべきIAMのアクションを解決する
SDKの利用からIAMポリシーで許可するアクションをどう解決すればいいか最初悩んだが、AWS Service Referenceというものが公開されており、これを使うことで解決できることがわかった。定期的に更新する仕組みも作ることで、今後の変更にも追従できるようになった。
https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/service-reference.html
3. AWS Service Referenceからはわからない暗黙の依存を管理可能にする
運用を始めて少ししてから気づいたのだが、AWS Service Referenceで解決できない暗黙の依存関係も存在していることがわかった。 aws-marketplace:Subscribe と aws-marketplace:ViewSubscriptions がそれで、AWS Marketplace経由で配信されるサードパーティのモデルを初めて実行する際にBedrockが裏側で必要としているアクション。これはAWS Service Referenceには記載されていないため、AWS Service Referenceとは別口で管理して検出可能にした。こういう例外パターンに素早く対応できるのは内製ツールの強みだと思う。
デメリット・制約
いくつかデメリットや制約といえることもある。
言語やSDKが固定である
リソースレベルの検出ができない
検出パターンなど、ハードコードしている箇所がいくつかある
言語やSDKが固定である
NodeJS x TypeScript x AWS SDK v3に特化した作りなので、例えばGoで書いたツールを同じリポジトリで管理する場合は使えない。
リソースレベルの検出ができない
どのようなリソースに対してアクションを許可するか、までは検出できない。例えばS3バケットへのアクセスについては、バケット名がコード上に存在していないためIAM ポリシーを書く際にちゃんと許可する必要がある。
検出パターンなど、ハードコードしている箇所がいくつかある
ワーカー実行や aws-marketplace:Subscribe の依存関係など、例外的な処理がいくつかある。少しやり方が変わったり、ハードコードされていない依存関係があった場合はデプロイしてみて初めてエラーに気づく可能性がある。とはいえ、Staging環境でのテストで気づけるはずなので大きな問題とは思っていない。
iam-policy-autopilotじゃだめか
実装時には存在に気づいていなかったが、iam-policy-autopilotという目的が似ているツールがある。このツールを使うとコードからIAMポリシーを生成できるので、生成したポリシーの自動適用まで可能かもしれない。TypeScript以外をサポートしているという点から、別言語で似たような需要が生じた場合は試してみたい。
まとめ
今回、アプリケーションが利用するAWS APIの権限付与漏れを事前検知する仕組みを作った。結構作業のブロッカーになることが多いし、時間がない時に権限エラーが発生すると非常にストレスなので事前に気づけるようにできたのはいい改善だと思う。皆さんも是非仕組みを作ってみてください。
筆者が所属する株式会社フライルではソフトウェアエンジニアを募集しています。このような改善活動に関心がある方はご連絡ください。
SREやクラウドインフラ、プラットフォームエンジニアリングをやるポジションはこちら:
ソフトウェアエンジニア(SRE/インフラ/プラットフォーム) - 株式会社フライル
株式会社フライルでは現在ソフトウェアエンジニア(SRE/インフラ/プラットフォーム)を募集しています。
株式会社フライル
.ogp-card {
display: flex;
border: 1px solid var(--border-color, #e1e4e8);
border-radius: 8px;
overflow: hidden;
text-decoration: none;
color: inherit;
margin: 1.5em 0;
transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.ogp-card:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
transform: translateY(-1px);
}
.ogp-card-thumbnail {
flex: 0 0 200px;
max-width: 200px;
overflow: hidden;
}
.ogp-card-thumbnail img {
width: 100%;
height: 100%;
object-fit: contain;
background: #f6f8fa;
display: block;
margin: 0;
}
.ogp-card-body {
flex: 1;
padding: 12px 16px;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: center;
}
.ogp-card-title {
font-weight: 600;
font-size: 0.95em;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.ogp-card-description {
font-size: 0.85em;
opacity: 0.75;
margin-top: 4px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.ogp-card-url {
font-size: 0.75em;
opacity: 0.6;
margin-top: 8px;
}
@media (max-width: 480px) {
.ogp-card {
flex-direction: column;
}
.ogp-card-thumbnail {
flex: none;
max-width: 100%;
height: 160px;
}
}
Webアプリケーションをフルサイクルで開発したいポジションはこちら: