LoginSignup
0
2

More than 3 years have passed since last update.

IAM Roleがなぜ安全にアクセス権限を委任できるかを理解する

Last updated at Posted at 2020-11-15

AWSのAPIにアクセスするには、APIへのリクエストに署名する必要があり、署名するための秘密鍵が必要である。IAM Userのアクセス・キーを割り当てることもできるが、AWSのサービス、例えばEC2インスタンスからAPIにアクセスする場合は、IAM Roleを使用すると、秘密情報をホスト内に保存することなく、安全にAPIへのリクエストを行うことができる。

この記事では、AWSの、あるアカウントのEC2インスタンスから、別のアカウントのAWSサービスのAPIをコールする場合を例として、どのようにアクセス権限を委任しているかを順に説明する。

この記事では、以下のリソースを作成するとする。

  • アカウントA
    • アカウントA内のEC2インスタンスC
    • アカウントA内のIAM Role Role_D
    • アカウントA内のIAM Policy Policy_E
  • アカウントB
    • アカウントB内のIAM Role Role_F

EC2インスタンスAにIAM Roleをアタッチする

EC2インスタンスには、一つだけ IAM Roleをアタッチできる。

EC2インスタンスにアタッチするIAM Role Role_Dの「信頼関係」のポリシー・ドキュメントは、以下のように PrincipalにEC2サービスを指定し、ActionにSTSサービスのAssumeRoleを指定する。AWSコンソールでIAM Roleを作成する場合は、ウィザードで簡単にポリシー・ドキュメントを作成できる。

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

PrincipalがEC2サービスの場合、インスタンス内から以下の仮想的なネットワークのエンドポイントにアクセスすることでActionのサービスを呼び出すことができる。

アクセス先
http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
レスポンス
{
  "Code" : "Success",
  "LastUpdated" : "yyyy-mm-ddThh:mm:ssZ",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIAW7##############",
  "SecretAccessKey" : "G5sCiFYmltsyiHV#########################",
  "Token" : "IQoJb3###########################################################################################",
  "Expiration" : "yyyy-mm-ddThh:mm:ssZ"
}

IAM Role Role_DのActionに指定した STSサービスのAssumeRole APIが、アクセス・キーを作成する。このアクセス・キーは、IAM Userに割り当てたアクセス・キーと同様に、AWSのサービスのAPIへのリクエストの署名の鍵として使用できる。IAM Userのアクセス・キーとは異なり、STSサービスが生成するアクセス・キーには有効期限が設定されていて、保存することなく、都度生成して使用する。

このIAM Roleのアクセス権限に、例えば、CloudWatchReadOnlyポリシーをアタッチすると、EC2インスタンスからCloud WatchのAPIにアクセスできるようになる。

アカウントBに、アカウントAへ権限を委任するRoleを設置する

アカウントBのIAM Roleのポリシー・ドキュメントに、PrincipalがアカウントAを指すARNを指定し、ActionにSTSサービスのAssumeRoleを指定したRole_Fを作成する。

Role_F
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<アカウントAのID>:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

このRoleは、AWSコンソールでは、ウィザードを使用して、アカウントIDを指定するだけで作成できる。

このRoleが存在することで、アカウントAからこのIAM Roleにアタッチしたポリシーの権限の委任を受けることができる。

アカウントAのRole_Dに、アカウントBのRole_Fを要求する権限を与える

Role_Dのアクセス権限に、以下のIAM Policy Policy_Eをアタッチする。Actionに指定した、STSサービスのAssumeRoleにより、Resouceに指定したARNが示すアカウントBのRole_Fにアクセスする権限をこのIAM Roleに与える。

Policy_E
{ 
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::<アカウントBのID>:role/Role_F"
        }
    ]
}

EC2インスタンスAから、アカウントBのIAM Role Role_Fの権限の委任を受ける

EC2インスタンスAから、アカウントBのIAM Role Role_Fを使って、アカウントBのサービスの権限の委任を受けるには、Role_Dの委任により、アカウントAのSTSサービスのAssumeRole APIに、RoleArnパラメータにRole_FのARNを指定してアクセスすることでアクセス・キーを作成し、アカウントBのAWSサービスのAPIへのリクエストの署名の鍵とする。

AWS SDK for Rubyの場合、「AWS STS アクセストークンの作成」のように、Role_FのARNを指定して、アクセスキーを取得する。

rubyによるAPI呼び出し
role_credentials = Aws::AssumeRoleCredentials.new(
  client: Aws::STS::Client.new,
  role_arn: "arn:aws:iam::<アカウントBのID>:role/Role_F",
  role_session_name: "<任意の名前>"
)

s3 = Aws::S3::Client.new(credentials: role_credentials)

上記のコードは、STSサービス、S3サービスにアクセスするリージョンをデフォルト設定から取得していることに注意。必要に応じて、regionオプションを指定する。

まとめ

EC2インスタンスAは、Role_Dにより、Role_DにアタッチされたIAM Policyによる権限の委任を受け、Policy_Eの権限とアカウントBのRole_FによりRole_FにアタッチされたIAM Policyによる権限の委任を受けることで、アカウントBのサービスにアクセスすることができる。

おつかれさまでした。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2