Is it possible to get the canonical user id from AWS IAM users, from the .NET API?

11,746

Solution 1

You can easily get CanonicalUser ID using ListAllMyBuckets API call [1] (s3:ListAllMyBuckets permission is required):

$ aws s3api list-buckets --query Owner
{
    "DisplayName": "lord-vader",
    "ID": "f420064cb076f772e10584fc40ab777c09f6b7d154342cf358f1bd1e573c9cf7"
}

In AWS SDK for .NET, use code like this [2]:

AmazonS3Client client = new AmazonS3Client();
ListBucketsResponse response = client.ListBuckets();
Console.WriteLine("Canonical user ID - {0}", response.Owner.Id);

In AWSJavaSDK you can use AmazonS3.getS3AccountOwner wrapper method [3].

  1. https://docs.aws.amazon.com/AmazonS3/latest/API/RESTServiceGET.html
  2. https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/S3/MS3ListBuckets.html
  3. https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#getS3AccountOwner--

Solution 2

No, it is not possible to get the canonical user id from code - you've hit a somewhat odd and likely legacy aspect due to the different way to manage access permissions for S3 resources, see the AWS team's response to How to find out Canonical ID for an IAM user?:

You can not add IAM Users to ACL's as a grantee. I'll have the documentation updated to clarify that IAM Users are not supported in ACL's. There are a few solutions you can use to grant this User access to your Amazon S3 content: [...]

You might indeed want to reconsider using the more versatile S3 bucket policies instead (see below) - however, if you have access to the account's root credentials, you might find the canonical user ID associated with your AWS account as outlined in Specifying a Principal in a Policy (mind you, this doesn't work with IAM user credentials):

  1. Go to http://aws.amazon.com and from the My Account/Console drop-down menu, select Security Credentials.
  2. Sign in using appropriate account credentials.
  3. Click Account Identifiers.

I shall emphasize again that AWS strongly recommends to only use IAM users these days, see e.g. Root Account Credentials vs. IAM User Credentials:

Because you can't control the privileges of the root account credentials, you should store them in a safe place and instead use AWS Identity and Access Management (IAM) user credentials for day-to-day interaction with AWS.

This canonical user id requirement for S3 is a rare exception, and as I said likely to be considered a legacy artifact due to S3's ACL layer predating IAM, thus best avoided, if possible.

Share:
11,746
KTW
Author by

KTW

Updated on June 09, 2022

Comments

  • KTW
    KTW almost 2 years

    I have successfully created a user, credentials, and a bucket.
    Now I need to grant bucket access to this user.

    Is there any way to get this CanonicalUser value from code?
    The IAM user object only provides ARN, Path, UserId and UserName values, but none of these are valid for the grant.

    using (var s3 = new Amazon.S3.AmazonS3Client("[user_key]", "[secret_user_key]", RegionEndpoint.GetBySystemName("eu-west-1")))
    {
        var response = s3.GetACL("[bucket_id]");
        var acl = response.AccessControlList;
        acl.AddGrant(
            new S3Grantee() { 
                CanonicalUser = **???** 
            }, 
            new S3Permission(S3Permission.FULL_CONTROL)
        );
        s3.PutACL(
            new PutACLRequest() { 
                AccessControlList = acl, 
                BucketName = "[bucket_id]" 
            }
        );
    }