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

Support longer token duration #31

Closed
ldragone opened this issue Apr 3, 2024 · 7 comments
Closed

Support longer token duration #31

ldragone opened this issue Apr 3, 2024 · 7 comments
Labels
enhancement New feature or request

Comments

@ldragone
Copy link

ldragone commented Apr 3, 2024

Is your feature request related to a problem? Please describe.
Currently the tokens generated from IAM role have a fixed expiration of 1 hour. There is no way to set a longer duration.

Describe the solution you'd like
Enter a setting to specify the desired duration (maximum 12 hours as required by AWS).

Describe alternatives you've considered
Alternatively you can support the duration_seconds parameter which you can insert into your AWS profile configurations.

Additional context
image

@ldragone ldragone added the enhancement New feature or request label Apr 3, 2024
@rehanvdm
Copy link
Contributor

rehanvdm commented Apr 3, 2024

CloudGlance sets the value to a maximum of 12 hours and then AWS reduces this depending on the maximum session duration of the role and then role chaining.

  1. Can you double-check that the Maximum session duration on the Role is longer than 1 hour?

  2. Also are you role chaining? Meaning you assume role A and then assume role B. The resulting expiration time will then be limited to a maximum of 1 hour, no matter what you specify duration_seconds as. This is mentioned here:
    https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
    image

@ldragone
Copy link
Author

ldragone commented Apr 3, 2024

  1. Can you double-check that the Maximum session duration on the Role is longer than 1 hour?

Yes, I confirm that the Maximum session duration settings of the role I assume is set to 12 hours in AWS console on IAM role summary.

  1. Also are you role chaining? Meaning you assume role A and then assume role B. The resulting expiration time will then be limited to a maximum of 1 hour, no matter what you specify duration_seconds as. This is mentioned here:
    https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html

I use a source profile with Access Key and Secret, with which I assume the target role which is located in another AWS account. This shouldn't be about role chaining, right?
This is the configuration I use:
image

The same role assumed directly by the AWS console have a session of 12 hours.
I'm doing something wrong with my CloudGlance configuration?

@rehanvdm
Copy link
Contributor

rehanvdm commented Apr 4, 2024

Okay, it's not you it's me. Thankfully I wrote this blog as a means of documentation https://blog.cloudglance.dev/how-does-cloudglance-do-aws-auth/index.html#aws-iam-role in the IAM Role section (see snippet I copied from it below)

The script will always first do GetSessionToken (MFA is attached here) then it will assume the role. This counts as role chaining and then limits the length to 1 hour.

The TLDR; is that when you assume a role and pass the MFA details on that operation then IAM conditions like "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} that check for the MFA authenticated flag will always fail. You have to pass the MFA details on a GetSessionToken first and then do the assumed role for that flag to persist. Here is a StackOverflow question that also covers it https://stackoverflow.com/questions/50659155/aws-assume-role-with-credentials-that-last-more-than-an-hour

I can see that I left a note in the code saying that I would rather play it safe and do it "properly" to cover all bases, so always first GetSessionToken (with MFA if provided) and then AssumeRole.

I can see two improvements:

  1. Do not do GetSessionToken if no MFA is provided.
  2. If MFA is provided, provide an extra check box, let's call it GetSessionToken before assume role for now and if that is selected then it does the current behavior of GetSessionToken and then AssumeRole which limits your RoleDuration to 1 hour. But if it is not selected, then it only does the AssumeRole and your RoleDuration can be much longer, but the consequence is that if there are IAM policies that check for the MFA flag, then you will get an error.

Do you know if your IAM policies check the MFA flag? If It does then there is no way to get around this, the new option mentioned above will help others though. Let me know what you think?


Blog Snippet

Here the AWS CLI does prompt for your MFA code if it detects the mfa_serial 🤷. But you get the error below if
you enforce the MultiFactorAuthPresent flag to be set in IAM policies.

An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

Example policy that only allows you to list buckets only if you have the MultiFactorAuthPresent flag set to true.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "s3:ListBucket"
    ],
    "Resource": ["*"],
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }]
}

It turns out that when the CLI assumes the role, it does not/can not place MultiFactorAuthPresent flag. You have to
first call STS with the MFA details like we did for the iam-user.js script and then use those temporary credentials
to assume the role.

This is also made clear if your really deep dive into IAM and is listed on the AWS documentation:

The temporary credentials returned by AssumeRole do not include MFA information in the context, so you cannot
check individual API operations for MFA. This is why you must use GetSessionToken to restrict access to resources
protected by resource-based policies.

This is why we rather play it safe and make the assumption that if you are requiring MFA, you have
set up your IAM policies correctly with the MultiFactorAuthPresent condition. It is very confusing why this
isn't the default for MFA assumed roles in the AWS CLI.

The next we need to talk about is the duration of the token. When you just assume the role, the maximum duration can be
12 hours. But this is not the case for when you assume the role with the temporary credentials you obtained from STS
that have been Multi Factor Authenticated. Then the maximum duration is now 1 hour because now we are role chaining.

We can read about role chaining in the AWS docs here

However, if you assume a role using role chaining and provide a DurationSeconds parameter value greater than one hour, the operation fails.

This is the error that you will get if you specify a duration longer than 1 hour even though the role has a longer maximum duration:

Error [ValidationError]: The requested DurationSeconds exceeds the 1 hour session limit for roles assumed by role chaining.

This is why the scrips below leave the Duration field as default so that your token will be valid for 1 hour.


Updated the broken link to the blog to be correct https://blog.cloudglance.dev/how-does-cloudglance-do-aws-auth/index.html#aws-iam-role

@thesuavehog
Copy link

FYI - aws:MultiFactorAuthPresent also fails if you use IAM Identify Center with an SSO IdP like Okta ... I have Okta and Google Workspace logins enforce MFA but AWS doesn't know that so it treats the session from IAM Identity Center via Okta as no MFA and those conditions fail.

I had to document it for a Security review to get a waiver on "must enforce MFA" Security Hub checks.

@rehanvdm
Copy link
Contributor

rehanvdm commented Apr 4, 2024

FYI I Updated the broken link to the blog to be correct https://blog.cloudglance.dev/how-does-cloudglance-do-aws-auth/index.html#aws-iam-role /

Yeah, I also found that one out the hard wy through experimentation. From all of this I concluded that:

  1. It is better to enforce MFA on your login portals, SSO or AWS Console if using IAM and then have no IAM policies that check for the MFA flag.
  2. Ban all AWS IAM Users Access Keys, because you can authenticate without MFA on the CLI even though it is specified on the user.

Or just ban IAM users altogether.

But before AWS SSO, having MFA conditions on IAM policies was the thing to do (as far as I know) and I didn't want users coming back to me saying that they logged in with MFA but were still denied. Hence I played it safe by first doing GetSessionToken then AssumeRole as was needed in the old days.

I think making that change will be better for the majority of people, and those that want/need the MFA flag present after assuming the role can just check that box.

@ldragone
Copy link
Author

ldragone commented Apr 5, 2024

Thanks rehanvdm for the valuable clarification on how IAM roles work with aws:MultiFactorAuthPresent. I really enjoyed the blog.

Regarding the proposed solution, it seems like an excellent idea to provide the user with the possibility to choose via the extra checkbox.

I currently have no conditions where the MultiFactorAuthPresent check is present, but in the future it may be an option, so the ability to use Cloudglance by activating the checkbox is fine!

@rehanvdm
Copy link
Contributor

rehanvdm commented Apr 7, 2024

Added in the new release v0.0.31 > https://github.com/Systanics/CloudGlance/releases/tag/v0.0.131. Description copied from there:

💫 Enhancements

  • Assume Role improvements, close Support longer token duration #31
    • You can now specify duration_seconds up to 43200 seconds (12 hours)
      image

    • When doing MFA, you have the option to either:

      1. Role chain by first using GetSessionToken (attached MFA here) then AssumeRole. This was the default up until now to ensure the aws:MultiFactorAuthPresent IAM flag is set. It limited the role duration to 1 hour.
      2. AssumeRole without first doing GetSessionToken. This does not limit the session duration but it also does not add the aws:MultiFactorAuthPresent IAM flag.

      The info text next to the new MFA Option describes it as:

      This option will attach the MFA details to GetSessionToken before calling AssumeRole so that IAM policies that checks the aws:MultiFactorAuthPresent condition passes. This is called role chaining and limits the session to a maximum of 1 hour.

      image

@rehanvdm rehanvdm closed this as completed Apr 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants