[Alibaba Cloud]ユーザーロールでの一時的な認証アクセスについて

## はじめに
本投稿は [SBCloud Engineers' Blog](https://techblog.sbcloud.co.jp/) にも投稿しています。SBCloud Engineers' Blogには日中間接続をはじめ、Alibaba Cloud関連のソリューションや技術ネタを記載していますので、よかったら是非一度アクセスみてください。

先日は下記図の① [ユーザーロールでのクロスアカウントアクセスについて](https://techblog.sbcloud.co.jp/2018/10/01/cross-account-access-with-switch-role/) 、ご紹介させていただきました。
本日はその② Command Line Interface(以下、CLI)などを用いた場合の、一時的な認証アクセスの方法についてご紹介します。
![role](https://techblog.sbcloud.co.jp/assets/2018/10/role-2.jpg)

## 前提条件
今回利用するアカウントとロールは下記の通りです。また、aliyuncli  を利用するので、事前にaliyuncliのインストールが必要です。aliyuncliのインストール方法は該当githubリポジトリのREADME.md にてご確認ください。

●アカウントA(5450********6520)
RAMユーザー: test_user1(アクセスキー付き)
RAMユーザーの権限: AliyunSTSAssumeRoleAccess ( Alibaba Cloud側作成されているRAMポリシー)

●アカウントB(5568********6773)
RAMロール: switchRoleSbc
ロールARN: acs:ram::5568********6773:role/switchrolesbc
ロール権限: AliyunECSReadOnlyAccess

ユーザーロールの作成は、公式ドキュメント ([ユーザーロールの作成](https://jp.alibabacloud.com/help/doc-detail/28649.htm#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90))にてご確認ください。

## 別アカウントへの一時的な認証アクセス
アカウントAからアカウントBへ一時的な認証アクセスには、AssumeRoleという概念があります。

>AssumeRole
実際のユーザーは、AssumeRole 操作を実行することにより、ロールのセキュリティトークンを取得できます。AssumeRole API を呼び出すことにより、ロールのセキュリティトークンを取得し、このトークンを使用してクラウドサービス API にアクセスできます。

今回は別アカウントへのアクセスとしていますが、もちろん同じアカウント内でも可能です。

### AssumeRoleの手順

1: まずは、現在のアカウントの情報を確認します。出力結果から、現在利用しているのがアカウントAのtest_user1だとわかります。

```shell:code

$ aliyun sts GetCallerIdentity | jq
{
"AccountId": "5450********6520",
"RequestId": "E698A29F-319D-4193-85FD-7D000A2092DA",
"PrincipalId": "28397*****6642425",
"IdentityType": "RAMUser",
"Arn": "acs:ram::5450********6520:user/test_user1",
"UserId": "2839*****6642425"
}

```

2: アカウントAのロールswitchRoleSbcに対して、AssumeRoleを実行すると、<font color="red">AccessKeySecret、AccessKeyId、SecurityToken</font>などの情報が返されます。 

```shell:code

$ aliyun sts AssumeRole --RoleArn acs:ram::5568********6773:role/switchrolesbc --RoleSessionName assume_role | jq
{
  "RequestId": "B8C5B0DC-D70A-413E-B0EE-C8CA3001BE2C",
  "AssumedRoleUser": {
    "AssumedRoleId": "340275294216312866:assume_role",
    "Arn": "acs:ram::5568********6773:role/switchrolesbc/assume_role"
  },
  "Credentials": {
    "AccessKeySecret": "Hxhx8V2xr****************d5ahmbfm",
    "AccessKeyId": "STS.NH********URdTehJi",
    "Expiration": "2018-10-04T05:09:07Z",
    "SecurityToken": "CAIS9wF1q6Ft5B2yfSjTOZsebWZ+LmNqC/Ht6md1HDkAJq3LL+bk/Mdle5MJqP+/UFB5ZtKWve*************yUigxj3ETbkTfGT7cR6nvylq/AGeSGy6YiRn2YCsJErWU1d/Gg6sTG1s1C4YBQpdon0yPgdZLgdirlZmu21MOrJGdwGI4gbEmls+lV7rPYuBAZE="
  }
}

```

3: 一時的な認証情報( AccessKeySecret、AccessKeyId、SecurityToken )を環境変数に設定しておきます。

```shell:code

$ export AccessKeySecret=Hxhx8V2***********bwSyAd5ahmbfm
$ export AccessKeyId=STS.NH***************URdTehJi
$ export SecurityToken=CAIS9wF1q6Ft5B2yfS***************21MOrJGdwGI4gbEmls+lV7rPYuBAZE=

```

4: 一時的な認証情報を利用して、アカウントの情報を確認してみると、現在利用しているのがアカウントBのロールswitchrolesbcだとわかります。

```shell:code

$ aliyun sts GetCallerIdentity --access-key-id ${AccessKeyId} --access-key-secret ${AccessKeySecret} --sts-token ${SecurityToken} | jq
{
  "AccountId": "5568******6773",
  "RequestId": "9348E538-FDC5-4379-B18A-4B228D6832EF",
  "PrincipalId": "340275294216312866:assume_role",
  "IdentityType": "AssumedRoleUser",
  "Arn": "acs:ram::5568********6773:assumed-role/switchrolesbc/assume_role",
  "RoleId": "340275294216312866"
}

```

5: switchrolesbcはECS関連情報の閲覧権限(AliyunECSReadOnlyAccess)を持っているので、ECSの情報を取得することが可能です

```shell:code

$ aliyun ecs DescribeInstances --access-key-id ${AccessKeyId} --access-key-secret ${AccessKeySecret} --sts-token ${SecurityToken} | jq
{
  "PageNumber": 1,
  "TotalCount": 1,
  "PageSize": 10,
  "RequestId": "794EF29E-6C0E-4210-9700-2BFFF7D39AB0",
  "Instances": {
    "Instance": [
      {
        "ImageId": "alinux_17_01_64_20G_cloudinit_20171222.vhd",
        "VlanId": "",
        "EipAddress": {
          "IpAddress": "",
          "AllocationId": "",
          "InternetChargeType": ""
        },
        "ZoneId": "ap-northeast-1a",
        "IoOptimized": true,
        "SerialNumber": "1e750bd9-03d7-4631-bc28-6b9127600bad",
        "Cpu": 1,
        "Memory": 1024,
        "DeviceAvailable": true,
        "SecurityGroupIds": {
          "SecurityGroupId": [
            "sg-6we66jzmsh3vrjvu3ms1"
          ]
        },
     ...
      
     ...
    
     ...

```

6: 一時認証情報を利用して、許可されていない操作をやろうとすると、エラーメッセージが表示されます。

```shell:code

$ aliyun oss ls --access-key-id ${AccessKeyId} --access-key-secret ${AccessKeySecret} --sts-token ${SecurityToken}
ERROR: oss: service returned error: StatusCode=403, ErrorCode=AccessDenied, ErrorMessage=You are forbidden to list buckets., RequestId=5BB596BE928238E00FFE07D2

```

## その他
下記、２点補足情報として記載させていただきます。

1: AssumRoleを実行すると、SecurityTokenが返されますが、SecurityTokenの有効期限の範囲は900 ～ 3600秒です。デフォルト3600秒です。

2: 今回アクセスキーを利用して、AssumeRoleを実行しましたが、(必要な権限が付与されていれば)サービスロールを利用して、AssumeRoleも可能です。

## 最後
今回はAssumeRoleを利用して、別アカウントへの一時的な認証アクセスについてご紹介させていただきました 。AssumeRoleはアカウント間の連携が簡単にかつセキュアに実現することができますので、開発の状況に応じて、是非AssumeRoleの活用を一度検討してみてください。