cloud-sre
AWS Glue の iam:PassRole AccessDenied を調査した流れ
Glue コンソールの updateJob 失敗から、IAM グループポリシー、管理ポリシーの対象範囲、MFA ガードレール、最終的な simulator 検証までを整理した調査メモ。
AWS Glue Job をコンソールから保存しようとしたときに、AccessDeniedException
で失敗しました。エラーは iam:PassRole を指していました。
この種の Glue エラーでは、ユーザーが Glue に対する広い権限を持っていても、 Job が使う IAM Role を Glue に渡す権限が別途必要になります。
以下の例では、公開用に名前を匿名化しています。
| 項目 | 例 |
|---|---|
| 人間の IAM ユーザー | arn:aws:iam::<account-id>:user/<human-user> |
| Glue Job | <glue-job-name> |
| Runtime Role | arn:aws:iam::<account-id>:role/<glue-runtime-role> |
| ユーザーグループ | GlueAccess |
用語の説明
| 用語 | 意味 |
|---|---|
iam:PassRole | ユーザーが IAM Role を AWS service に渡すための権限。Glue Job が runtime role を使うときに必要になります。 |
| Runtime Role | Glue Job の実行時に Glue が assume する IAM Role。Job が読めるもの、書けるものを決めます。 |
| Trust policy | IAM Role 側にある信頼設定。どの AWS service や principal が role を assume できるかを決めます。 |
explicitDeny | IAM simulator の結果。明示的な deny に一致した状態で、allow より優先されます。 |
implicitDeny | IAM simulator の結果。deny は一致していないが、allow も存在しない状態です。 |
最初に失敗していた場所
コンソールには次のようなエラーが表示されました。
Failed to update job
updateJob: AccessDeniedException:
User: arn:aws:iam::<account-id>:user/<human-user>
is not authorized to perform: iam:PassRole
on resource: arn:aws:iam::<account-id>:role/<glue-runtime-role>
because no identity-based policy allows the iam:PassRole action
見る点は、拒否された action が glue:UpdateJob ではなく
iam:PassRole である点です。Glue の操作権限ではなく、Glue に Role を渡す
権限が不足している可能性が高いと判断しました。
調査対象のアカウントを確認する
まず CLI profile が、コンソールエラーに出ている AWS account と同じかを確認します。
aws sts get-caller-identity --profile <production-profile>
返ってきた account ID がエラーの account ID と一致したため、以降の IAM 調査は 正しいアカウントに対して行えていると判断できます。
ユーザーの権限ソースを確認する
対象ユーザーに直接 attached policy や inline policy があるか確認しました。
aws iam list-attached-user-policies \
--user-name <human-user> \
--profile <production-profile>
aws iam list-user-policies \
--user-name <human-user> \
--profile <production-profile>
ユーザー自身には直接の policy はありませんでした。
次に所属グループを確認します。
aws iam list-groups-for-user \
--user-name <human-user> \
--profile <production-profile>
ユーザーは GlueAccess と汎用 developer group に所属していました。ここで調査の
焦点は、どのグループポリシーが iam:PassRole を許可すべきか、に絞られます。
Glue Role 自体を確認する
対象の role 自体は問題ではありませんでした。
aws iam get-role \
--role-name <glue-runtime-role> \
--profile <production-profile>
trust policy には Glue service principal が含まれていました。
{
"Effect": "Allow",
"Principal": {
"Service": "glue.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
ユーザーがこの role を pass できれば、Glue はその role を assume できます。 role trust の問題ではありません。
Job がその Role を使っていることを確認する
次に Glue Job の設定を読みます。
aws glue get-job \
--job-name <glue-job-name> \
--region ap-northeast-1 \
--profile <production-profile> \
--query "Job.{Name:Name,Role:Role,LastModifiedOn:LastModifiedOn}"
Job.Role は、コンソールエラーに出ていた role と一致しました。これで UI の
エラーと具体的な IAM resource が結びつきました。
拒否された action を simulator で確認する
IAM policy simulator を使うと、次の可能性を切り分けられます。
| 仮説 | 確認方法 |
|---|---|
| Role trust が間違っている | get-role の trust policy に Glue がない |
| ガードレールが明示的に拒否している | simulator が explicitDeny を返す |
| その role を pass する allow がない | simulator が implicitDeny を返す |
まず、対象 principal、action、role、渡し先サービスを指定してシミュレーションします。
aws iam simulate-principal-policy \
--profile <production-profile> \
--policy-source-arn arn:aws:iam::<account-id>:user/<human-user> \
--action-names iam:PassRole \
--resource-arns arn:aws:iam::<account-id>:role/<glue-runtime-role> \
--context-entries \
ContextKeyName=iam:PassedToService,ContextKeyValues=glue.amazonaws.com,ContextKeyType=string
最初の結果は、MFA ガードレールによる explicitDeny でした。これは実際に存在する
制御で、MFA がない場合に多くの操作を拒否する policy がありました。
この時点ではまだ結論にしません。MFA が存在する前提の context を追加して再度確認します。
aws iam simulate-principal-policy \
--profile <production-profile> \
--policy-source-arn arn:aws:iam::<account-id>:user/<human-user> \
--action-names iam:PassRole \
--resource-arns arn:aws:iam::<account-id>:role/<glue-runtime-role> \
--context-entries \
ContextKeyName=iam:PassedToService,ContextKeyValues=glue.amazonaws.com,ContextKeyType=string \
ContextKeyName=aws:MultiFactorAuthPresent,ContextKeyValues=true,ContextKeyType=boolean
ガードレールの条件を満たした状態でも、結果は implicitDeny でした。この
role を pass する allow statement が存在しません。
不足していた Allow を特定する
GlueAccess グループには AWS managed policy の AWSGlueConsoleFullAccess が
付与されていました。
この policy には iam:PassRole が含まれていますが、対象 role は Glue service
role の命名規則に合うものだけです。
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::*:role/AWSGlueServiceRole*",
"Condition": {
"StringLike": {
"iam:PassedToService": "glue.amazonaws.com"
}
}
}
service-role path の variant も許可されています。
arn:aws:iam::*:role/service-role/AWSGlueServiceRole*
しかし、今回の Job は独自名の runtime role を使っていました。
AWSGlueServiceRole* にはマッチしません。これが、Glue Console Full Access が
あっても保存できなかった理由です。
最小の権限変更
最小権限で直すには、GlueAccess グループに inline policy を追加します。
aws iam put-group-policy \
--profile <production-profile> \
--group-name GlueAccess \
--policy-name AllowPassGlueRuntimeRoleToGlue \
--policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPassGlueRuntimeRoleToGlue",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::<account-id>:role/<glue-runtime-role>",
"Condition": {
"StringEquals": {
"iam:PassedToService": "glue.amazonaws.com"
}
}
}
]
}'
この権限は、対象 role と渡し先サービスを Glue に限定しています。
変更後の確認
まず group inline policy を読み戻します。
aws iam get-group-policy \
--profile <production-profile> \
--group-name GlueAccess \
--policy-name AllowPassGlueRuntimeRoleToGlue
その後、同じ principal、action、resource、Glue service context で simulator を 再実行します。結果は次のように変わりました。
allowed
これは、コンソールで再試行するだけよりも強い検証です。失敗していた IAM action そのものが identity-based policy によって許可されたことを確認できるためです。
次に Glue PassRole で止まったときに見る順番
Glue Job の更新で iam:PassRole が失敗したら、次の順番で確認します。
- CLI profile とコンソールエラーの AWS account が一致しているか確認する。
- ユーザーに直接付与された policy を確認する。
- ユーザーの所属グループと group policy を確認する。
- 対象 role の trust policy を確認する。
- Glue Job が現在使っている role を確認する。
iam:PassedToService=glue.amazonaws.com付きでiam:PassRoleを simulate する。explicitDenyなら、MFA、IP、SCP、permission boundary などのガードレールを見る。implicitDenyなら、対象 role への最小 allow を追加する。- 修正後は、ユーザーに再試行してもらう前に simulator を再実行する。
次から残しておく判断基準
glue:* や AWSGlueConsoleFullAccess は、「任意の Glue runtime role を pass できる」
ことを意味しません。iam:PassRole は独立した IAM action であり、AWS managed
policy は AWS の service role 命名規則に合う role だけを対象にしている場合があります。
安定した修正パターンは次の形です。
iam:PassRole を許可する
ただし対象は Job が必要とする runtime role のみ
かつ iam:PassedToService は glue.amazonaws.com のみ