Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws: Infer identity from RoleSessionName for IAM too #4178

Closed
james-atwill-hs opened this issue Mar 21, 2018 · 5 comments
Closed

aws: Infer identity from RoleSessionName for IAM too #4178

james-atwill-hs opened this issue Mar 21, 2018 · 5 comments

Comments

@james-atwill-hs
Copy link

Feature Request:

Please see the discussion here: https://groups.google.com/forum/#!topic/vault-tool/Sxj4LOuLoW4

In a nutshell: Currently Vault supports ec2 inference using the RoleSessionName when doing aws/ec2 authn. I would like to extend that to aws/iam athn so that users sharing the same role can be uniquely identified.

@joelthompson
Copy link
Contributor

@jefferai @vishalnayak -- have been spending some time thinking about the right way of accomplishing this. I think the code will be straightforward if we can get the design right. I'm also not super-familiar with the identity system, so if I'm misunderstanding things, let me know!

First, doing this by default would be a breaking change as the backend currently sets the entity alias to be the unique principal ID. Do you have any sense of how important it is to break backwards compatibility?

Second, what exactly do we map to the entity alias?

  1. Using the IAM principal unique ID (as it is now)
  2. Using just the RoleSessionName when it's an assumed role
  3. Using the UniqueId:RoleSessionName format
  4. Using the IAM username when it's an IAM user
  5. Using an artificial UniqueId:IamUsername format when it's an IAM user
  6. Some format that incorporates the account ID (e.g., ARNs)

If we went with just the IAM username or just the RoleSessionName, then anybody who can create/modify roles can map literally anybody onto any entity. For example, let's say I have a corporate AWS account, with an account ID of 123456789012, and I have a SAML IdP like the OP that will give me creds to AWS roles in my corporate account, 123456789012, and that ensures that RoleSessionName is my email address. I then create a Vault role that binds to arn:aws:iam::123456789012:role/RoleName. Lastly, I set up identity aliases that map people's email addresses back to their Vault identities. All is good, right? Well, now Evil Joel has a personal AWS account, 987654321098, and binds a role in the same AWS auth backend mount, to arn:aws:iam::987654321098:role/SomeOtherRoleName. Evil Joel can now assume that role with an arbitrary RoleSessionName and thus impersonate literally anybody in the identity store who has an alias mapped to this backend. It's bad, but not the end of the world -- if I can write to roles in an auth backend, I can map authenticated entities to arbitrary policies anyway, but this lets me mask who I really am by impersonating somebody else, and it could allow me to get around any required_parameters/allowed_parameters/denied_parameters that are on the policy allowing me to write to roles. It's also a bit of a different attack surface compared to something like the LDAP or GitHub auth backends -- on those backends, there is only a single LDAP connection URL or GitHub server/org per mount, and so you can't do these sorts of "redirection" (for lack of a better word) attacks on them unless you also control the configuration of the backend, and so it's more obvious what somebody can do with the ability to modify that configuration.

I think the right thing to do is expose a new config endpoint (e.g., auth/aws/config/identity) that controls what this mapping is. Initially, it can have two options -- one that is the existing default and one that works for the OP, and it can be expanded further if there's more customer demand. This allows admins to only set up identity aliases for mounts where they trust whoever can write to the config endpoint and so is a similar security model to the LDAP and GitHub auth backends (the ones that I spot checked). It would mean that, if a user had existing entity aliases based on the assumption that they could never be altered from the unique principal ID, it would open a small window of attack (e.g., if I can assume a role, I could set RoleSessionName to the unique principal ID of another IAM entity), but I think that is small enough of a risk to be OK.

Thoughts? Am I overthinking this? Poorly explaining something?

@james-atwill-hs -- given the above discussion, what would you find to be most useful to map onto the identity alias? Given some of the risks I outlined, would you still want just RoleSessionName?

@james-atwill-hs
Copy link
Author

Sorry, I had drafted a reply and then never clicked "Comment".

Because our IdP is the one in charge of generating the tokens, there's no way of identifying the specific user other than with RoleSessionName. The UniqueId (as best as I've seen) is a non-sensical role ID that I have no way of correlating.

I would still like to enforce that the bound_iam_principal_arn matches something before attempting to do RoleSessionName matching.

Since this isn't my area of expertise, I defer on having any useful input. That said, I do realize that there are risks involved with "fuzzy matching" the RoleSesionName to something in the identity backend, and I'm comfortable with this risk - on a per-role basis.

HTH?

@jefferai
Copy link
Member

Between your comments, I think I'm pretty convinced that the best idea is to have a secure default but allow it to be user switchable. I don't particularly like the scenario Joel outlined of impersonating identity entries, especially because depending on how it's configured an administrator of the aws backend may no longer be allowed to map directly to policies, instead solely using identity groups -- in fact we may in the future have the ability to tune a mount to set a flag that causes vault to ignore policy requests in responses to better allow decoupling backend admin from authorization.

So I think if an admin knows what they're getting into it's one thing, but the default should be as secure as is reasonable. I'm into the switchable idea.

joelthompson added a commit to joelthompson/vault that referenced this issue Sep 2, 2018
This is inspired by hashicorp#4178, though not quite exactly what is requested
there. Rather than just use RoleSessionName as the Identity alias, the
full ARN is uses as the Alias. This mitigates against concerns that an
AWS role with an insufficiently secured trust policy could allow an
attacker to generate arbitrary RoleSessionNames in AssumeRole calls to
impersonate anybody in the Identity store that had an alias set up.
By using the full ARN, the owner of the identity store has to explicitly
trust specific AWS roles in specific AWS accounts to generate an
appropriate RoleSessionName to map back to an identity.

Fixes hashicorp#4178
@joelthompson
Copy link
Contributor

Hey @james-atwill-hs -- I just opened #5247 that I think should support your use case. I felt it best to specify the full ARN of the assumed role rather than just the RoleSessionName to prevent the kinds of concerns I mentioned. This puts the responsibility of ensuring AWS roles are appropriately locked down where I think it belongs -- on the admin of the identity store. Would love to know what you think of this approach!

@james-atwill-hs
Copy link
Author

Hey @joelthompson -- I think this solves my problem but I'd have to prototype it all out to make sure. Thanks for not letting this fall away!

vishalnayak pushed a commit that referenced this issue Sep 26, 2018
* auth/aws: Make identity alias configurable

This is inspired by #4178, though not quite exactly what is requested
there. Rather than just use RoleSessionName as the Identity alias, the
full ARN is uses as the Alias. This mitigates against concerns that an
AWS role with an insufficiently secured trust policy could allow an
attacker to generate arbitrary RoleSessionNames in AssumeRole calls to
impersonate anybody in the Identity store that had an alias set up.
By using the full ARN, the owner of the identity store has to explicitly
trust specific AWS roles in specific AWS accounts to generate an
appropriate RoleSessionName to map back to an identity.

Fixes #4178

* Respond to PR feedback

* Remove CreateOperation

Response to PR feedback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants