Carpe Diem

備忘録

Assume Roleの用途・メリット

概要

sts:Assume Roleは三者に自分のAWSアカウントのAPI権限を委譲する仕組みです。
ここで言う第三者というのは

のように様々なモノに委譲が可能です。

sts:Assume Role

どういう用途として使える?

具体的にこの仕組みがどういったことに使えるかをざっと挙げてみます。

ポリシー
(付与する権限)
信頼関係
(誰に付与するか)
どうなるか
EC2ReadOnly EC2 EC2インスタンスから
http://169.254.169.254/latest/meta-data
にアクセスが可能
PowerUser IAMユーザ IAMユーザ自体は権限を持っていなくても、
AssumeRoleでPowerUserの
一時的な権限を取得できる
S3ReadOnly AWSアカウント AWSアカウントから自分の
S3バケットへアクセス可能

何がメリット?

sts:Assume Roleは一時的なCredentialsしか発行されないので、

  • IAMユーザを作ってアクセスキーを生成する
  • S3の公開設定を細々指定する

といった後々セキュリティ的に負の遺産となる部分を避ける事が可能です。
特に前者は

  • アクセスキーがどこかしら(コード・Jenkinsなど)に残ってしまう
  • 退職者が出たときのキーローテーションが大変

という問題が起きます。IAMロールであればロールを指定するだけで済むのでそれらの問題を発生させません。

また基本的にAWS CLIや各SDKはIAMロールを指定しておけば一時Credentialsの発行を自動で行ってくれるので、発行部分を気にせずそのポリシーの権限で操作する事が可能です。

具体的な信頼関係の設定

ロールの信頼関係の部分を設定することで、第三者に権限を付与することが可能です。

f:id:quoll00:20181231021756p:plain

これの中身を見ると

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

とありますが、このPrincipalという部分が付与したい第三者に当たります。
今回だとEC2サービスに付与する感じですね。

自アカウントのIAMユーザに付与したい場合

自アカウント123456789010のIAMユーザaliceに権限を付与したい場合は以下のようにします。
alice自身には何の権限も付与せず、sts:AssumeRole経由でのみ一時的な権限を付与してもらうことでセキュアに管理できるようになります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789010:user/alice"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

別アカウントのIAMユーザに付与したい場合

別のAWSアカウント123456789012のIAMユーザbobに付与したい場合は以下のようにします。
先の例とほぼ同じですが、アカウントIDやユーザ名が変わってます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/bob"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

と書きます。

他のケース

IAM JSON ポリシーの要素:Principal - AWS Identity and Access Management

に色んなケースが載っているので、利用したいケースに合わせて設定してください。

Assume Roleで一時的なCredentialsを発行

信頼関係を設定したIAMロールの権限が利用できるよう、一時的なCredentialsを発行します。

前提

今回作ったIAMロールが以下とします。

項目
アカウントID 123456789010
ポリシー ReadOnlyAccess
信頼関係 自アカウント123456789010のIAMユーザalice
ロール名 read-only

今何の権限も持たないaliceユーザとして、ローカルではこのユーザのアクセスキーでログイン済みとします。
権限を持たないため、そのままであればAPIを使おうとしても

$ aws s3 ls

An error occurred (InvalidToken) when calling the ListBuckets operation: The provided token is malformed or otherwise invalid.

このようにエラーが出ます。

発行

以下のように一時Credentialsを発行します。

$ aws sts assume-role \
 --role-arn arn:aws:iam::123456789010:role/read-only \
 --role-session-name test-session
{
    "Credentials": {
        "AccessKeyId": "ASIAWDCMQX6BJNMKE5BK",
        "SecretAccessKey": "6R4wsfwwIGw/JJO3sb3ueV+9dAzB9r4YH2hPHnh+",
        "SessionToken": "FQoGZXIvYXdzEEoaDPzruozGwoxTYIVP8CLtA7qSQGcpLHFur3c3Ay4x5EpVtIBc380rzNk5SxthnclYHsUM/yQRMpHJ3tfUsOOw00+c9Vc6/PlkAL5acm5ZqkhakZCkhqc0FOR3GfZJ2HoWU8MJqTpxwLOVYMvJDQIzUQ08HuaPZb1Mmlvb/ygMwFzkJPUpW42Wnp3acnuBQtfmjFrlqYD6w2f7UNhuaAx5zEyd7x3N5xp5J4vMfJfRj0ZqWAeJ8u4NRX/cs5uuAIQjfnG8cjNlMfqTrcw4JnYQ6xaxDEif4dlzUGUBqeG7ilWH3e8pZoS1cl7uK8TogZk+XuZmihBCFZU6ADp1bijE2aPhBQ==",
        "Expiration": "2018-12-30T17:05:24Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAIFHIZYMC4SVNWVFKI:test-session",
        "Arn": "arn:aws:sts::123456789010:assumed-role/read-only/test-session"
    }
}

これでReadOnlyAccessの権限を持った1時間だけ有効なCredentialsが発行されました。
※上記は値をいじったダミー値です

発行したCredentialsでAPIを叩く

以下のように発行したCredentialsを環境変数にセットして

$ export AWS_ACCESS_KEY_ID=ASIAWDCMQX6BJNMKE5BK
$ export AWS_SECRET_ACCESS_KEY=6R4wsfwwIGw/JJO3sb3ueV+9dAzB9r4YH2hPHnh+
$ export AWS_SESSION_TOKEN=FQoGZXIvYXdzEEoaDPzruozGwoxTYIVP8CLtA7qSQGcpLHFur3c3Ay4x5EpVtIBc380rzNk5SxthnclYHsUM/yQRMpHJ3tfUsOOw00+c9Vc6/PlkAL5acm5ZqkhakZCkhqc0FOR3GfZJ2HoWU8MJqTpxwLOVYMvJDQIzUQ08HuaPZb1Mmlvb/ygMwFzkJPUpW42Wnp3acnuBQtfmjFrlqYD6w2f7UNhuaAx5zEyd7x3N5xp5J4vMfJfRj0ZqWAeJ8u4NRX/cs5uuAIQjfnG8cjNlMfqTrcw4JnYQ6xaxDEif4dlzUGUBqeG7ilWH3e8pZoS1cl7uK8TogZk+XuZmihBCFZU6ADp1bijE2aPhBQ==

適当なコマンドを叩いてみると

$ aws s3 ls
2018-12-24 17:49:28 assume-role-test-bucket

このように使えるようになります。

期限が切れると

1時間が過ぎると

$ aws s3 ls

An error occurred (ExpiredToken) when calling the ListBuckets operation: The provided token has expired.

このように怒られます。
自動的に使えなくなるので安心ですね。

まとめ

当初IAMロールは「アクセスキー発行しなくて済むから便利だなぁ」くらいにしか考えていませんでしたが、信頼関係の仕組みによってクロスアカウントアクセスなども簡単に設定できますし非常に良い機能だと思います。

ソース