ロールは作ってもらいたいけどユーザは作らせたくない時のIAMポリシー

わけあってAWSアカウントを共用で使っているとき、自由にやって欲しいけど、あんまり何でもできすぎると困る。
とりあえずユーザ管理はこちらでやりたい、といったケースがある。

ということで今回は以下の要件を満たすポリシーを作る。

  • 新規ユーザの作成はさせない
  • ロールやポリシーの作成はなるべく自由にさせたい
  • 自分より強い権限を持つユーザやサービスを作り出させない
  • ユーザやグループへのインラインポリシーのアタッチはさせない


出来上がったポリシーは以下。
この記事では以下のポリシーを本ポリシーと呼ぶ。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PowerUser",
      "Effect": "Allow",
      "NotAction": "iam:*",
      "Resource": "*"
    },
    {
      "Sid": "TheseActionsSupportKindOfReferenceFromIAM",
      "Effect": "Allow",
      "Action": [
        "iam:Get*",
        "iam:List*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ThisActionSupportPassingIAMRoleToAnyServices",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ThisActionSupportServiceLinkedRoles",
      "Effect": "Allow",
      "Action": [
        "iam:CreateServiceLinkedRole"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ThisActionSupportUsToAttachAndDetachAnyMangedPoliciesAndAnyInlinePoliciesToAnyRoles",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:PutRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:PutRolePermissionsBoundary"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::<youraccountid>:policy/<thispolicyname>"
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:UpdateRoleDescription",
        "iam:CreatePolicy",
        "iam:DeleteRole",
        "iam:SimulateCustomPolicy",
        "iam:SimulatePrincipalPolicy",
        "iam:TagRole",
        "iam:AddRoleToInstanceProfile",
        "iam:CreateInstanceProfile",
        "iam:DeleteInstanceProfile"
      ],
      "Resource": "*"
    },
    {
      "Sid": "ManageOwnAccessKeys",
      "Effect": "Allow",
      "Action": [
        "iam:CreateAccessKey",
        "iam:DeleteAccessKey",
        "iam:GetAccessKeyLastUsed",
        "iam:GetUser",
        "iam:ListAccessKeys",
        "iam:UpdateAccessKey"
      ],
      "Resource": "arn:aws:iam::*:user/${aws:username}"
    }
  ]
}

解説

以下は本ポリシーの解説。

PowerUser

IAMを除く、全てのアクションをどのリソースに対しても実施できる権限。
最近は少しPowerUser自体も複雑になっておりこちらの記事で解説。

{
  "Sid": "PowerUser",
  "Effect": "Allow",
  "NotAction": "iam:*",
  "Resource": "*"
}

単純な操作であればこれだけで十分。
ただ、AWSは複数のサービスを組み合わせることが多い。
組み合わせる時にはIAMロールを作ったり、作ったIAMロールをサービスに渡す。

つまりIAMのアクションもある程度できないとまともにAWSを使えない。

今回はPowerUserをベースに必要な権限を足していく。

Permissions Boundary

ロールやポリシーを自由に作れ、どんなサービスにも渡すことができるとセキュリティ上良くない。

今回の要件だと「新規ユーザを作成させない」縛りがあるがこれを突破できてしまう。

例えば管理者権限を持つIAMロールを作成し、EC2に渡す。
すると、そのEC2のAWS CLIから新規ユーザ作成ができてしまう。

ではどうやるのか?

与えた権限の範囲内でのみ自由にロールやポリシーの作成、アタッチを可能にする基本的な方針は

本ポリシーがPermissions Boundaryに設定されたロールしか作成できないようにする

Permissions Boundaryとは

https://aws.amazon.com/blogs/security/delegate-permission-management-to-developers-using-iam-permissions-boundaries/

2018年7月にリリースされたIAMの機能で、ロールの権限をポリシーを使って制限することができる。

ポリシーをロールのPermissions Boundaryとしてアタッチすると、そのロールにおいて、そのポリシーで有効な権限以上のことができなくなる。


実際の挙動としては、ロールにPermissions Boundaryを超える権限を持つポリシーをアタッチすることはできるが、実行時にPermission Errorが出る。

通常のポリシーとPermissions Boundaryに設定されたポリシーの重複部分が最終的に実行可能

IAM作成時にPermissions Boundary(アクセス権限の境界)のポリシーを指定できる

この機能を使うことで本ポリシーは

  • ロールの作成
  • ロールへの管理ポリシーのアタッチ
  • ロールへのインラインポリシーの追加
  • ロールから管理ポリシーのデタッチ
  • ロールからインラインポリシーの削除

といったことが可能だが、
それらを行うには対象のロールにPermissions Boundaryとして本ポリシーが設定されていなけれればならない、
という制約をつけている。

つまり権限を付与するときに自身の権限以上のものを付与しようとしていないかチェックが走る。

以下本ポリシーのPermissions Boundary設定部分。
本ポリシーがPermissions Boundaryに設定されていればこれらの操作を行うことができる。
<thispolicyname>と<youraccountid>には自分のものを使用ください。

{
  "Sid": "ThisActionSupportUsToAttachAndDetachParticularMangedPoliciesAndAnyInlinePoliciesToAnyRoles",
  "Effect": "Allow",
  "Action": [
    "iam:CreateRole",
    "iam:AttachRolePolicy",
    "iam:DetachRolePolicy",
    "iam:PutRolePolicy",
    "iam:DeleteRolePolicy",
    "iam:PutRolePermissionsBoundary"
  ],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "iam:PermissionsBoundary": "arn:aws:iam::<youraccountid>:policy/<thispolicyname>"
    }
  }
},

参考: IAMアクションに関連するConditionで使用可能なキーは以下で確認可能
https://docs.aws.amazon.com/IAM/latest/UserGuide/list_identityandaccessmanagement.html

ポリシー作成を許可

あわせてポリシーの作成等に必要なものを追加。

ポリシーはどんなものでも作れるようにする。
ポリシーを作っただけではなにもできず、ユーザやロールにアタッチして初めて効果を発揮する。
アタッチするときにPermission Boundaryによって権限チェックが入るのでポリシーは自由に作っても大丈夫。

 {
  "Effect": "Allow",
  "Action": [
    "iam:UpdateRoleDescription",
    "iam:CreatePolicy",
    "iam:DeleteRole",
    "iam:SimulateCustomPolicy",
    "iam:SimulatePrincipalPolicy",
    "iam:TagRole",
    "iam:AddRoleToInstanceProfile",
    "iam:CreateInstanceProfile",
    "iam:DeleteInstanceProfile",
    "iam:Get*",
    "iam:List*"
    ],
  "Resource": "*"
 }

PassRole

作成したIAMロールをサービスに渡す為にはpassroleのアクションを許可する。
これにより任意のIAMロールを任意のサービスにつけることができる。

なお、passroleに似たアクションとしてassumeroleがある。
passroleは自分以外に権限を委任するものだが、assumeroleは自分自身がそのIAMロールになりきる、というもの。

本ポリシーではassumeroleは外しているが、入れても問題ない。
入れる場合はpassroleと同じように任意のリソースに対して許可する。

{
  "Sid": "ThisActionSupportPassingIAMRoleToAnyServices",
  "Effect": "Allow",
  "Action": [
    "iam:PassRole"
  ],
  "Resource": "*"
},

サービスリンクロール

サービスリンクロールを作成する権限もつける。


サービスリンクロールとはサービスに必要なポリシーがAWSによって事前定義されたIAMロールで、このサービスにはどのような操作が必要か?というのを考えなくてよい。


サービスリンクロールはその性質上過剰な権限が入ることはないので特に制限は入れていない。

{
  "Sid": "ThisActionSupportServiceLinkedRoles",
  "Effect": "Allow",
  "Action": [
    "iam:CreateServiceLinkedRole"
  ],
  "Resource": "*"
}

アクセスキー

自身のアクセスキーの発行や有効/無効、削除といったアクセスキー管理の権限もつけておく。

{
  "Sid": "ManageOwnAccessKeys",
  "Effect": "Allow",
  "Action": [
    "iam:CreateAccessKey",
    "iam:DeleteAccessKey",
    "iam:GetAccessKeyLastUsed",
    "iam:GetUser",
    "iam:ListAccessKeys",
    "iam:UpdateAccessKey"
  ],
  "Resource": "arn:aws:iam::*:user/${aws:username}"
}

テスト

今回作成したポリシーをインラインポリシーにつけたユーザでPermission Boundaryをつけて/つけずにIAMロールを作成するとどうなるかテスト。

aws iam create-role \ 
--permissions-boundary "arn:aws:iam::************:policy/本ポリシー" \
--role-name temprole \
--profile test \
--assume-role-policy-document file://sample-trust.json

{
    "Role": {
        "Path": "/",
        "RoleName": "temprole",
       ・・・省略・・・・
}

Permissions Boundaryを指定した場合は正常にロールが作成できた。


次にPermissions Boundaryを指定しないで作成。

$ aws iam create-role \
--role-name mijikaiinochi \
--profile test \
--assume-role-policy-document file://sample-trust.json

An error occurred (AccessDenied) when calling the CreateRole operation: 
User: arn:aws:iam::***********:user/iamtest is not authorized to perform: 
iam:CreateRole on resource: arn:aws:iam::***********:role/mijikaiinochi

正しくDenyされる。

想定QA

Q. ユーザが自分以上の権限を持つポリシーを作ってサービス(EC2など)にpassroleできてしまう?

A.

サービスにはロールとして権限を委任する必要があり、ロールを作成するときにはPermissions Boundaryが必ず設定されている必要があるのでそういったことはできない。

Q. 強いポリシーをアタッチした後にPermissions Bounaryを削除されてしまったら?

A.

DeleteRolePermissionsBoundaryはできないようにしている為、削除はできない。
putrolepermissionboundaryで既存のpermission boundaryが書き換えようとしても、書き換え後のPermissions Boundaryに本ポリシーが設定されていないとNGなので不可。

Q. すでに自分より権限が強いロールがあったらそれをサービスに渡したり、AssumeRoleできるんじゃない?

A.

そのロールが特にエンティティを絞っていなければできる。
ただ、そういうロールがあること自体がまずい。

Q. ユーザやグループにインラインポリシーつけたら突破できる?

A.

今回はユーザやグループへのインラインポリシーのアタッチは許可していません。

Q. ポリシーをアタッチした後に変更したら強い権限付与できてしまうのでは?

A.

Permissions Boundaryが設定されているロールにすでにアタッチされているポリシーを変更した場合、その際にもPermissions Boundaryのチェックが入るので、そういったことはできません。

Q. リソースベースのポリシーを使ったら突破されるのでは?

A.

リソースベースポリシーは、アタッチされたリソースへのアクセスを許可するポリシーで、今回はIAM以外のサービスにはフルアクセスできるようにしているので、リソースベースポリシーで特定のリソースへのアクセス権をつけられたしても特に意味はないので問題ありません。
別AWSアカウントからリソースベースポリシー(信頼ポリシーも)つけられたとしてもそこに関しては管理の範囲外なので問題としません。

リソースベースポリシーが使えるサービス一覧
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html
アイデンティティポリシーとリソースポリシーの違い
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_identity-vs-resource.html

Q. AWS Organizations サービスコントロールポリシー (SCP)使えばいいんじゃない?

A.

Yesで、SCPが使える環境であればSCPで実現できないかをまず検討したほうが良い。

最後に

ここまで読んでくださりありがとうございます。
ユーザとかは情シスなど管理側で管理したいけど、検証とかは自由にやってほしいという時にこういうのが必要なんじゃないかと思って作ってみました。
本ポリシーには抜け道がある、もっといい方法がある、といったことがあればぜひ教えてください。

こういったポリシーが作りたいんだけど、といった相談もどうぞ。

こちらの本もIAMを学ぶのに良い。
マニアックと書かれているが入門書的な内容。




コメントする

メールアドレスが公開されることはありません。