Can't seem to find this anywhere in the docs; if I am authenticated with BasicAWSCredentials, e.g. AccessKeyId and SecretKey, is it possible to get the AWS Account ID?
12 Answers
Update
AWS has just silently addressed this long standing gap by introducing the dedicated STS API action GetCallerIdentity, which returns details about the IAM identity whose credentials are used to call the API, including the AWS Account ID - there are a few sample responses, e.g.:
<GetCallerIdentityResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
<GetCallerIdentityResult>
<Arn>arn:aws:iam::123456789012:user/Alice</Arn>
<UserId>AKIAI44QH8DHBEXAMPLE</UserId>
<Account>123456789012</Account>
</GetCallerIdentityResult>
<ResponseMetadata>
<RequestId>01234567-89ab-cdef-0123-456789abcdef</RequestId>
</ResponseMetadata>
</GetCallerIdentityResponse>
You can use the AWS Command Line Interface to obtain just the account ID, here's an example:
$ aws sts get-caller-identity --output text --query Account
121371349383
Initial Answer
This is at least indirectly possible via AWS Identity and Access Management (IAM) by means of the GetUser action (available via getUser() in the AWS SDK for Java):
Retrieves information about the specified user, including the user's path, GUID, and ARN.
If you do not specify a user name, IAM determines the user name implicitly based on the AWS Access Key ID signing the request.
The returned User data type (Class User) contains an Arn element (getArn()), which is the Amazon Resource Name (ARN) specifying the user. This is further detaild in Identifiers for IAM Entities, specifically in section ARNs, which describes the format of the User Resource Type:
arn:aws:iam::{account_ID}:user/{path/to/user/UserName}
Example: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob

- 63,899
- 11
- 192
- 211
-
1I did know this, but it just seems like I shouldn't have to parse the ID out of any requests! This will remain best answer until I'm told it's not possible :) – Apr 17 '12 at 21:13
-
1And... if you don't have iam:getUser permission, you can parse the arn that you would get otherwise get back, out of the 403 error you get instead! It seems you really ought to be able to get this info, not only without parsing, but without requiring any privileges. You've already authenticated yourself to the account, and obviously this is public-enough info that they put it in the error message! (It's also exposed in other context, like AMI ownership, etc.) – Bob Kerns Feb 23 '14 at 22:04
-
3FYI, GetUser will not work if you are running on an EC2 instance under an IAM role, regardless of your permissions, because there is no IAM user in that context. – jarmod Feb 17 '15 at 19:07
-
Good point @jarmod, the answer is a bit dated (and yet no official solution available, unfortunately) - Josh Hancock's [answer](https://stackoverflow.com/a/27406872/45773) provides a good workaround for this scenario (+1), and tavvit's [answer](https://stackoverflow.com/a/18124234/45773) covers another workaround for a different one, guess someone should write a library to hide all those behind a unified API ;) – Steffen Opel Feb 17 '15 at 22:18
This is an old question, but for the poor souls out there - The answer based on ARN is the most correct answer that we found. There's also an OwnerId field when calling DescribeInstances, but there may be no instances ..
However the reality is a bit more complex. Sometimes the IAM user does not have the permission to issue getUser(), and then he gets AmazonServiceException with
getErrorCode() = "AccessDenied"
In this case, the ARN is a part of the AWS error message:
User: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob is not authorized to perform:
iam:GetUser on resource: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
So here the matters are even worse: we need to parse a free text error message and then extract the account number:
try {
... iam.getUser(); ...
} catch (AmazonServiceException e) {
if (e.getErrorCode().compareTo("AccessDenied") == 0) {
String arn = null;
String msg = e.getMessage();
// User: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob is not authorized to perform: iam:GetUser on resource: arn:aws:iam::123456789012:user/division_abc/subdivision_xyz/Bob
int arnIdx = msg.indexOf("arn:aws");
if (arnIdx != -1) {
int arnSpace = msg.indexOf(" ", arnIdx);
arn = msg.substring(arnIdx, arnSpace);
}
System.out.println("ARN: " + arn);
}
If you have the AWS CLI tools, you can:
aws iam get-user | awk '/arn:aws:/{print $2}'

- 4,051
- 4
- 29
- 29
Here's the code to get the newer STS getCallerIdentity stuff working (in Java):
private String getAccountIDUsingAccessKey(String accessKey, String secretKey) {
AWSSecurityTokenService stsService = AWSSecurityTokenServiceClientBuilder.standard().withCredentials(
new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))).build();
GetCallerIdentityResult callerIdentity = stsService.getCallerIdentity(new GetCallerIdentityRequest());
return callerIdentity.getAccount();
}
Props to @SteffenOpel for giving the clues needed, of course.

- 23,006
- 14
- 93
- 108
-
1Just to add, _No permissions are required to perform this operation. If an administrator adds a policy to your IAM user or role that explicitly denies access to the sts:GetCallerIdentity action, you can still perform this operation. Permissions are not required because the same information is returned when an IAM user or role is denied access._ – TheCommonEngineer Dec 11 '19 at 12:45
With the latest API there's a direct way of finding the user ID:
BasicAWSCredentials basicAWSCredentials = new BasicAWSCredentials("your access key", "your secret key");
AmazonIdentityManagementClient iamClient = new AmazonIdentityManagementClient(basicAWSCredentials);
String userId = iamClient.getUser().getUser().getUserId();

- 1,030
- 1
- 11
- 13
-
Tested this once again - and the `getUserId()` method seems to work with at least regular accounts - didn't test this with IAM users. – Michael Yakobi Nov 25 '13 at 07:36
-
4For IAM users, it returns your access key ID instead of the account number. This has the advantage that it distinguishes between accounts, but fails to identify the global account (and thus the space of possible resources). We really need both. – Bob Kerns Feb 23 '14 at 22:10
-
Adding this here, because it's the top SO result for "find aws account number", and because it's bad practice to use keys instead of IAM Roles for deployed apps anyway...
If you're running from an AWS instance that has an IAM Role on it, you can do curl -s http://169.254.169.254/latest/meta-data/iam/info
and get the ARN of the instance's role from the InstanceProfileArn
key of the results, without having to worry about trying to parse an exception message or granting IAM permissions to an instance that doesn't need them.
Then, you just have to parse the ARN for the account number.

- 795
- 10
- 15
-
Ideally there would be a common way to do this when running the app locally with credentials (federated, or IAM user with keys) and when running on an instance. – Michael Andrews Apr 05 '18 at 18:16
I made a funny discovery - if you call GetRole with a non-existent RoleName, the error message you get back contains the ARN of the calling account, so just parse out the account number from that. This is nice because it works in all cases that I can think of, even if the caller does not have permissions to call GetRole.
Here's the error message I get:
User: arn:aws:sts::669916120315:assumed-role/CloudMail_Server/i-31dd19cd is not authorized to perform: iam:GetRole on resource: role _no_such_role_
The '669916120315' portion of the error message is the AWS Account ID.

- 6,507
- 6
- 40
- 69
While I don't consider this an ideal scenario, it does get the job done. This uses the AWSSDK 3.0.
public string GetUserId()
{
AmazonIdentityManagementServiceClient c =
new AmazonIdentityManagementServiceClient();
GetUserRequest request = new GetUserRequest();
GetUserResponse response = c.GetUser(request);
//parse it from the ARN
//should be similar to "arn:aws:iam::111111111111:user/username"
string[] arnParts = response.User.Arn.Split(new char[] { ':' });
return arnParts[4];
}
Using AWS Java SDK v2:
public String getAccountId(AwsCredentialsProvider awsAuth, Region awsRegion) {
StsClient stsClient = getClient(awsAuth, awsRegion);
GetCallerIdentityRequest request = GetCallerIdentityRequest
.builder()
.build();
GetCallerIdentityResponse response = stsClient.getCallerIdentity(request);
return response.account();
}
public StsClient getClient(AwsCredentialsProvider awsAuth, Region awsRegion) {
return StsClient
.builder()
.credentialsProvider(awsAuth)
.region(awsRegion)
.build();
}

- 1,949
- 1
- 26
- 32
ElasticTranscoder ListPresets returns a data structure that includes ARNs that include the AWS account id.
Unlike many other popular suggestions, this aws-cli command works for basic credentials, IAM user, IAM roles, instance roles, and cross-account role assumption:
aws elastictranscoder list-presets --query 'Presets[0].Arn' |
cut -d: -f5
Of course, you will need permission to make the ListPresets API call, but that's true of any answer.

- 22,089
- 5
- 66
- 75
Some answers provide a way to retrieve the AWS Account ID from an IAM User. Those solutions will generate a runtime exception if you use the credentials of an IAM Role.
In this case, you can do this:
// you can get it with @Import(SnsConfiguration::class) for instance
@Autowired
private AWSCredentialsProvider credentialsProvider;
private String resolveAmazonAccountId() {
AmazonIdentityManagement imClient = AmazonIdentityManagementClientBuilder.standard()
.withCredentials(credentialsProvider)
.build();
String roleArn = imClient.getRole(new GetRoleRequest().withRoleName("role name")).getRole().getArn();
// https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns
// arn:partition:service:region:account:resource
return roleArn.split(":")[4];
}

- 4,813
- 2
- 27
- 45