Reputation:
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?
Upvotes: 39
Views: 33397
Reputation: 2273
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();
}
Upvotes: 1
Reputation: 5289
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];
}
Upvotes: 0
Reputation: 25187
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.
Upvotes: 10
Reputation: 64751
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
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
Upvotes: 36
Reputation: 22407
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.
Upvotes: 0
Reputation: 4561
If you have the AWS CLI tools, you can:
aws iam get-user | awk '/arn:aws:/{print $2}'
Upvotes: 10
Reputation: 99
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];
}
Upvotes: 2
Reputation: 6856
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.
Upvotes: 2
Reputation: 855
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.
Upvotes: 5
Reputation: 1140
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();
Upvotes: 8
Reputation: 279
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);
}
Upvotes: 10