How to read encoded authorization error messages in AWS
Tags: aws, security, iam
Published: 2022-03-25 06:50:33

## 1. The problem

The other day I wanted to deploy an AWS stack written in <a href="https://aws.amazon.com/cdk/" class="link" target="_blank" rel="noopener noreferrer">CDK</a>. The process had worked seamlessly with <a href="https://github.com/features/actions" class="link" target="_blank" rel="noopener noreferrer">GitHub Actions</a> until it didn't. To my surprise the deployment failed.

I got an error message similar to this one:

```bash
An error occurred (UnauthorizedOperation) when calling the AuthorizeSecurityGroupIngress\
 operation: You are not authorized to perform this operation. Encoded authorization\
  failure message: <ENCODED MESSAGE>
```

It was weird because I had no problems at all the day before. No doubt, something must have happened to my permissions overnight.

## 2. The reason

I went to investigating the stack in <a href="https://aws.amazon.com/cloudformation/" class="link" target="_blank" rel="noopener noreferrer">CloudFormation</a>. As the error message (the unencoded part) indicated I wasn't authorized to access one of the <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html" class="link" target="_blank" rel="noopener noreferrer">security groups</a> which was part of the stack.

The <q>You are not authorized to perform this operation</q> error message refers to an <a href="https://aws.amazon.com/iam/" class="link" target="_blank" rel="noopener noreferrer">IAM</a> issue, the right permissions were clearly not attached to my identity-based policy.

## 3. The solution

The error message in this form is of less use, so we need to decode is first. The following <a href="https://aws.amazon.com/cli/" class="link" target="_blank" rel="noopener noreferrer">CLI</a> command will help (you'll need `sts:DecodeAuthorizationMessage` permission):

```bash
aws sts decode-authorization-message --encoded-message <ENCODED MESSAGE>
```

After parsing the value of the `DecodedMessage` key in the response, we'll get an object similar to this:

```json
{
  "allowed": false,
  "explicitDeny": false,
  "matchedStatements": {
    "items": []
  },
  "failures": {
    "items": []
  },
  "context": {
    "principal": {
        "id": "AIDAXXXXXXXXXXXXXXXXX",
        "name": "my-user-name",
        "arn": "arn:aws:iam::123456789012:user/my-user-name"
    },
    "action": "ec2:AuthorizeSecurityGroupIngress",
    "resource": "arn:aws:ec2:us-west-2:123456789012:security-group/sg-0123456789abcdefg",
    "conditions": {
      "items": "ARRAY OF KEY-VALUE PAIRS - OMITTED FOR BREVITY"
    }
  }
}
```

The response is clear. It shows that we are not `allowed` to perform the required operation, and it's not because of an explicit `DENY`.

This means that there is no explicit `ALLOW` (`matchedStatements` array is empty) after all relevant policies have been evaluated, and AWS falls back to the default, which is implicit `DENY`.

We always need an overall explicit `ALLOW` to access an AWS service. If no permission explicitly allows the operation, the final decision will be `DENY`.

The response also contains the permission we need to add to the relevant user or role. It says that the my user with ARN `arn:aws:iam::123456789012:user/my-user-name` needs to be allowed to perform the `ec2:AuthorizeSecurityGroupIngress` action on the `sg-0123456789abcdefg`.

The `items` in the `conditions` element contains the key-value pairs of the user's context (resource, account, any tags, etc).

All we need to do is go to IAM, find the relevant user, role, or group, and add the above permission.

## 4. Not every operation supports encoded messages

IAM error messages don't always look like this because not every operation supports an encoded error message.

For example, `ec2:DeleteSecurityGroup` does support it while `application-autoscaling:DescribeScalingPolicies` doesn't. The second operation returns an error message similar to this:

```bash
User: arn:aws:iam::123456789012:user/USERNAME is not authorized to perform:\
 application-autoscaling:DescribeScalingPolicies because no identity-based policy allows the\
  application-autoscaling:DescribeScalingPolicies action (Service: AWSApplicationAutoScaling;\
   Status Code: 400; Error Code: AccessDeniedException; Request ID: <REQUEST ID>; Proxy: null)
```

The message is also clear, it explicitly states that the user's permission policy (which is an identity-based policy) doesn't allow the operation.

## 5. Hurry up

I tried to decode the same message a few days later but I got the following error:

```bash
An error occurred (InvalidAuthorizationMessageException) when calling the\
 DecodeAuthorizationMessage operation: Message is expired
```

At this point it's unclear to me what the time limit on the `DecodeAuthorizationMessage` operation is for the message to be valid. I haven't found any relevant info about this in the documentations.

According to the <a href="https://docs.aws.amazon.com/STS/latest/APIReference/API_DecodeAuthorizationMessage.html" class="link" target="_blank" rel="noopener noreferrer">API reference</a> this error is returned when <q>the token contains invalid characters, such as linebreaks</q>. This is clearly not the case here as well as there's no timestamp is the decoded message either.

## 6. Summary

AWS can return encoded error messages for some operations. The `DecodeAuthorizationMessage` API will help us put the error message in a readable format.

## 7. References and more reading

If you want to know more about IAM-related errors, check out the <a href="https://aws.amazon.com/premiumsupport/knowledge-center/troubleshoot-iam-policy-issues/" class="link" target="_blank" rel="noopener noreferrer">Unathorized operation errors</a> page. It's a great summary of the different error message types that are related to the lack of IAM permissions.