JAWSUG_CLI専門支部 AWS Security Token Service (STS)ハンズオンのまとめ

# はじめに

12/20の昼と夜にJAWSUG_CLI専門支部で開催された、AWS Security Token Service (AWS STS)のハンズオンをやってみました。STSの主な機能とそのコマンドについて書こうと思います。

### イベントページ

https://jawsug-cli.connpass.com/event/230425/

https://jawsug-cli.connpass.com/event/233827/

# AWS Security Token Service (AWS STS) とは

 - AWS リソースへのアクセスをコントロールできる一時的セキュリティ認証情報を持つ、信頼されたユーザーを作成および提供する。
 - リスクになりうるIAMユーザーを発行しないようにするため、使用期限の短いセキュリティ認証。

# STSの主な機能

## 認証情報取得

### get-access-key-info

事前にIAMユーザのアクセスキーIDを取得して、変数${IAM_ACCESS_KEY_ID}に格納します。
`aws sts get-access-key-info`を実行してアクセスキーを渡すと、アカウントキーが返されます。

```
aws sts get-access-key-info \
  --access-key-id ${IAM_ACCESS_KEY_ID} \
  --output text
```

### get-caller-identity

`aws sts get-caller-identity`と入力すると、以下のように表示されます。

```
{
    "UserId": "XXXXXXXXXXXXXXXXXXXXX",
    "Account": "xxxxxxxxxxxx",
    "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/handson-cli/username"
}
```

UserIdを取得する場合

```
aws sts get-caller-identity \
  --query 'UserId' \
  --output text
```

Accountを取得する場合

```
aws sts get-caller-identity \
  --query 'Account' \
  --output text
```


ARNを取得する場合

```
aws sts get-caller-identity \
  --query 'Arn' \
  --output text
```

## 暗号化エラーメッセージ復号

### DecodeAuthorizationMessage

例えば、EC2を起動しようとしてエラーになった際に、以下のようなメッセージを出力します。

```
An error occurred (UnauthorizedOperation) when calling the RunInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: <暗号化エラーメッセージ（ランダム文字列）>
```

暗号化されているエラーメッセージをファイルに出力します。
そのファイルパスを変数 `${FILE_STS_DECODE_AUTHORIZED_MESSAGE_ENCODED_TEXT}` に指定し、`decode-authorization-message`を実行します。

```
aws sts decode-authorization-message \
   --encoded-message file://${FILE_STS_DECODE_AUTHORIZED_MESSAGE_ENCODED_TEXT}
```

エラーメッセージがJSON形式でデコードされます。

```
{
    "DecodedMessage": "{\"allowed\":false,\"explicitDeny\":false,<略>}"
}
```

この場合、明示的な拒否（"explicitDeny":false）もされていないが、許可（"allowed":false）されていない。
つまり、EC2の実行権限がないということになります。

## トークン発行

### get-session-token

セッショントークンの有効期間`${STS_SESSION_TOKEN_DURATION_SECONDS}`を指定して実行します。

```
aws sts get-session-token \
  --duration-seconds ${STS_SESSION_TOKEN_DURATION_SECONDS}
```

そうすると、アクセスキーIDとシークレットアクセスキー、そしてセッショントークンと有効期限がJSON形式で返されます。

```
{
    "Credentials": {
        "AccessKeyId": "XXXXXXXXXXXXXXXXXXXX",
        "SecretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXSXXXXX",
        "SessionToken": "xxxxxxxxxxxx・・・・xxxxxx",
        "Expiration": "2021-12-21T18:11:23Z"
    }
}
```

認証ファイルに設定することで、有効期限の間、AWSリソースにアクセスすることができます。
有効期限を過ぎると、アクセスできなくなりエラーとなります。

```
An error occurred (RequestExpired) when calling the DescribeVpcs operation: Request has expired.
```

また、セッショントークンが有効でもリクエストに MFA 情報が含まれていない場合は、
IAM API オペレーション(`list-users`など)を呼び出せず、以下のようなエラーが表示されます。

```
An error occurred (InvalidClientTokenId) when calling the ListUsers operation: The security token included in the request is invalid
```

MFAを付与したSTSセッショントークンを作成してアクセスするためには、以下の通り入力します。
仮想デバイス`${MFA_DEVICE_SERIAL}`と、MFA認証コード`${MFA_AUTH_CODE}`を指定します。

```
aws sts get-session-token \
  --duration-seconds ${STS_SESSION_TOKEN_DURATION_SECONDS} \
  --serial-number ${MFA_DEVICE_SERIAL} \
  --token-code ${MFA_AUTH_CODE} 
```

# 最後に

ランダム文字列をデコードして読むこと機会はこれまでになかったため、STSの機能を使ってそれを体験できたのは大きな学びになりました。

STSの認証情報を扱う挙動について理解するのは大事だと思い、今回と12/21のAssumeRole回は、ぜひ参加して理解を深めたいと思いました。まだ理解不十分で説明できるレベルではありませんが、公式ドキュメントを読んで更に理解を深めていきたいと思いました。

AssumeRoleのハンズオンについてはここに書くと長くなりそうなので、いったんここまでにして別記事で書きます。
最後まで読んでいただきありがとうございました。

https://jawsug-cli.connpass.com/event/233829/