Vault AWS Auth IAM method - setup without AWS access key/secret access key

1,674 views
Skip to first unread message

primate

unread,
May 16, 2018, 5:49:43 AM5/16/18
to Vault

I've been PoC'ing AWS auth and I noticed in the docs there was reference to a way of getting the IAM auth method working without using a AWS access key/secret key  – given this would remove a set of keys to be managed, and by extension removes the requirement to manage IAM policies across accounts as well I wanted to investigate – see https://www.vaultproject.io/api/auth/aws/index.html#access_key – “If using the iam auth method without inferencing, then no credentials are necessary.”

 

Not using inferencing obviously restricts the granularity of the controls you can put in place around the call into Vault, but given my initial use case is for all EC2 instances in an AWS account to have access to a particular secret it may be permissible for this use case. The API reference states you can set the bound_Iam_principle_arn binding without inferencing and it can be wildcarded so e.g. arn:aws:iam::1234567890:instance-profile/* (of course you have to set one binding so this binding is the only option here when inferencing is not enabled correct?)

 

I set up the role as follows, according to the docs I don’t believe I need to set any other values since the arn is wildcarded. I’ve used various  bound_Iam_principle_arn arns including just ‘*’ to be as permissible as possible.


{"allow_instance_migration":false,"auth_type":"iam","bound_account_id":"","bound_ami_id":"","bound_iam_instance_profile_arn":"","bound_iam_principal_arn":"arn:aws:iam::1234567890:instance-profile/*","bound_iam_principal_id":"","bound_iam_role_arn":"","bound_region":"","bound_subnet_id":"","bound_vpc_id":"","disallow_reauthentication":false,"inferred_aws_region":"","inferred_entity_type":"","max_ttl":1800000,"period":0,"policies":["instancebuild-policy","instancelogging-policy"],"resolve_aws_unique_ids":false,"role_tag":"","ttl":0},"wrap_info":null,"warnings":null,"auth":null}

 

However I always receive the following error (which looks like an AWS error message wrapped in a Hashicorp error):


{"errors":["error looking up full ARN of entity \u0026{aws 1234567890 assumed-role  Vault_AWS_Auth_PoC_Instance_Role i-0b49593534abecb31}: error creating IAM client: unable to fetch current caller: InvalidClientTokenId: The security token included in the request is invalid.\n\tstatus code: 403, request id: ce3228e2-58ec-11e8-8787-b30282991493"]}



I know the method I am using to generate the signed API request and send it to Vault is valid since it works fine when using an alternative IAM method config with an access key and other bindings.

 

David Adams

unread,
May 16, 2018, 7:18:58 AM5/16/18
to vault...@googlegroups.com
The "instance-profile" ARN is not your principal. You want the ARN of the role that is attached to that instance profile. But I don't think that's even what's causing the error.

It would also help if you could explain the context of where you are getting these messages. I assume you are using EC2 credentials, how are you retrieving them? The error mentions an invalid security token, are you providing one, or are you just passing the key ID and secret? Are you using the AWS SDK, or command line tools, or....

--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/vault/issues
IRC: #vault-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Vault" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vault-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/vault-tool/9d50e516-be3c-4484-9ee2-6c56f75eb11c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Adams

unread,
May 16, 2018, 7:21:51 AM5/16/18
to vault...@googlegroups.com
Also, what exact Vault endpoint are you calling and what are you passing? Are you constructing a signed sts:GetCallerIdentity request and passing that?

primate

unread,
May 16, 2018, 9:02:46 AM5/16/18
to Vault
David - thanks for replying.

I've tried multiple formats of the ARN, including the ARN of the role as you suggest, so I agree, I don't think that's what is causing the error.

I get the error message at the console of EC2 instance I am trying to login from. Generated by curling the Vault login route as follows:

curl -k -X POST "https://1.2.3.4:80/v1/auth/aws/login" -d '{headers}'

Since I'm using the IAM method I am passing a signed sts:GetCallerIdentity request. I'm constructing this using Joel Thompson's Python 2 library here.

Like I said, I know this is working OK because I can login fine and get a Vault token if I config Vault with an alternate IAM method setup (that uses the AWS access/secret access key and and IAM role). Its when I switch the config to using no AWS keys etc. that the error message appears.

Thanks
To unsubscribe from this group and stop receiving emails from it, send an email to vault-tool+...@googlegroups.com.

Joel Thompson

unread,
May 16, 2018, 10:05:49 PM5/16/18
to vault...@googlegroups.com
There's a couple things going on.

First, David is right in that you can't bind to an instance profile. (An instance profile is merely an abstraction layer that maps to at most a single IAM role and defines what role EC2 hypervisors call AssumeRole on your behalf; it's not really an IAM principal that you can authenticate as.) You have to bind to either a role or a user.

Second, the documentation you cited is a little bit outdated (sorry, that's my fault). The tl;dr: I _believe_ (but haven't tested) you don't need to give Vault AWS credentials (either explicitly or by putting it on an EC2 instance in an instance profile) if ALL of the following are true:
1: You are using the IAM auth method;
2: You have not enabled inferencing;
3: You have disabled resolve_aws_unique_ids on the role (but see the security caveat in the documentation); and
4: You are NOT using a wildcard in the bind.

The reason #1 and #2 are necessary is because otherwise Vault would need to look up the EC2 instance at client login time to validate the instance ID.

The reason #3 is necessary is because setting resolve_aws_unique_ids to true tells Vault, at role creation time, to resolve the bound_iam_principal_arn to the internal AWS unique ID, which requires AWS credentials to call out to the IAM APIs.

Disabling resolve_aws_unqiue_ids also triggers a backwards compatibility code path in which the path of AWS Role principals gets ignored. That is, you could have an AWS Role with a full ARN of arn:aws:iam::123456789012:role/Some/Path/To/RoleName, but with resolve_aws_unique_ids set to false, Vault would require you to set a bound_iam_principal_arn to arn:aws:iam::123456789012:role/RoleName. The reason is that the AWS sts:GetCallerIdentity call, when using assumed-role credentials, will return a caller ARN of arn:aws:sts::123456789012:assumed-role/RoleName and drop the /Some/Path/To/ part of the ARN.

The reason this is relevant is to explain #4. Let's say you have a bound_iam_principal_arn of arn:aws:iam::123456789012:role/Some/Path/* and you want to authenticate to vault with assumed-role credentials that has the same full ARN as above. When you authenticate to Vault by providing a signed GetCallerIdentity request, again, all AWS provides to Vault is arn:aws:sts::123456789012:assumed-role/RoleName. Vault doesn't know the _full_ ARN (i.e., including the path) of the bound role and so can't know whether it matches the wildcard bind. So, Vault has to look up the IAM role RoleName to find its full path and see if it matches the bind. The error message you posted is from precisely this code path -- Vault is trying to resolve the full ARN of your authenticated principal.

One important consideration with the backwards compatibility code path with resolve_aws_unqiue_ids set to false is precisely to not break customers that didn't have AWS credentials configured for Vault. However, the support for wildcard binds was added after AWS unique ID resolution was turned on by default for new roles, and being able to properly handle paths was critically important to safely handle the use case I described above with wildcard binds, so it seems reasonable to require Vault to possess AWS credentials when using wildcard binds.

In some specific cases such as what you're describing (where there's a wildcard immediately after the first "/" in the ARN, or anywhere before), Vault doesn't strictly need to do the lookup to resolve the full ARN and could just take a shortcut. However, in the interests of code simplicity, Vault doesn't have code for that shortcut and instead just requires AWS credentials.

If you've made it this far, one possible solution is if you have a limited number of roles that EC2 instances in your account would be in. Then, you could just pass Vault the list of all of those roles as the bound_iam_principal_arn. Another, less elegant solution, is you could give all EC2 instances in your account the ability to call sts:AssumeRole on a shared role and then set bound_iam_principal_arn to that shared role's ARN.

Anyway, sorry this was so long; hope you find this helpful!

--Joel

p.s.

> of course you have to set one binding so this binding is the only option here when inferencing is not enabled correct?

Yes, that is correct

primate

unread,
May 17, 2018, 11:14:40 AM5/17/18
to Vault
Thanks for taking the time to give such a detailed response.

To summarise, and to check my understanding, you're saying - if you have a wildcard, you need an AWS access key/secret key, so I would have to use the full path to a known role ARN in the bound_iam_principal_arn - this would be tricky given my use case.

You mention giving all EC2 instances in an account the ability to call sts:AssumeRole on a shared role - this might work for me - do you literally mean just setting the sts:AssumeRole perm in the IAM policy or do you mean that the EC2 instances would have to assume this role before constructing the sts:GetCallerIdentity query and submitting it to Vault?

Thanks again.

Joel Thompson

unread,
May 17, 2018, 12:40:19 PM5/17/18
to vault...@googlegroups.com
I would have to use the full path to a known role ARN in the bound_iam_principal_arn

Yes, AND you would have to disable resolve_aws_unique_ids. One note though -- bound_iam_principal_arn, as of 0.9.6, supports a list of ARNs, not just a single ARN. Don't know if that'll help or not.

do you literally mean just setting the sts:AssumeRole perm in the IAM policy or do you mean that the EC2 instances would have to assume this role before constructing the sts:GetCallerIdentity query and submitting it to Vault?

The latter. The EC2 instances would need to call sts:AssumeRole and use the returned credentials to sign the sts:GetCallerIdentity request and submit that to Vault. That way, all instances would authenticate as the same principal and you'd only have one bound to the role in Vault.

--Joel

primate

unread,
May 21, 2018, 9:51:46 AM5/21/18
to Vault
Hi Joel,

Haha - was just wondering why I couldn't feed a list into bound_iam_principal_arn then I re-read your comment "bound_iam_principal_arn, as of 0.9.6, supports a list of ARNs"

That's all working now, I have a couple of accounts logging in and retrieving secrets. Thanks for your help.
Reply all
Reply to author
Forward
0 new messages