Search code examples
amazon-web-servicesamazon-iamamazon-ecsaws-fargate

How do I find my IAM principal ARN, or userID, inside an ECS/Fargate container?


When dealing with S3 bucket policies, and other IAM-related policies in AWS, you sometimes want to allow or deny based on a Principal. However, when you have an ECS task with a Task Role, it is not obvious what your Principal is when the task is actually running.

I struggled with this for several hours, with neither the AWS documentation nor google/Stack Overflow providing much assistance, so I wanted to write up my findings for future strugglers like me.


Solution

  • Use get-caller-identity

    When your ECS container is running, you can invoke the STS function GetCallerIdentity to retrieve information about your current IAM details.

    It will return, among other things:

    • Your 'arn', something like arn:aws:sts::#########:assumed-role/YourRoleName/[uuid representing the ECS container ID] . Note that the bit at the end is a dynamic uuid, not something constant like, for example, ecs-tasks.amazonaws.com
    • Your 'UserId', something like AROA###############:[uuid representing the ECS container ID].

    (Note: you will need to call this as part of the code that your container runs, and will need to log the output, so that you can see it.)

    (Note: this will work in other AWS places, such as the CLI, etc, to give you your arn and UserID)

    Policies using Principals

    The Principal for an ECS container is the arn value you get from get-caller-identity.

    If you need to specify a principal in your policy, you might try to write something like this:

    "Statement": [
      {
        "Effect": "Allow",
        "Principal": {
          "AWS": [
            "arn:aws:sts::########:assumed-role/YourRoleName/*"
          ]
        }
        // statement continues...
    

    (The wildcard is because the uuid at the end of the arn is different for each container.)

    However, that won't work. Principals can be "*", but they otherwise can't contain wildcards. (Seems crazy to me... but apparently it's true: link, link)

    That means you won't be able to refer to your role by its arn, as the trailing uuid always changes.

    However, as explained in those linked articles, you can use Condition, StringLike, and aws:userid instead.

    (Unfortunately, these 'Conditions' don't allow you to reference the Principal / arn, only the UserID and a few other bits of information.)

    The UserID is returned (by that name) from get-caller-identity.

    So, a policy statement might end up looking like this:

    "Statement": [
      {
        "Effect": "Allow",
        "Principal": "*",
        "Condition": {
          "StringLike": {
            "aws:userid": "AROA##############:*"
          }
        }
        // statement continues...
    

    This also works for the inverse, where you want to DENY except where StringNotLike.