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

SSO authentication not working #2295

Closed
multimeric opened this issue Sep 7, 2021 · 12 comments · Fixed by #4045
Closed

SSO authentication not working #2295

multimeric opened this issue Sep 7, 2021 · 12 comments · Fixed by #4045

Comments

@multimeric
Copy link

multimeric commented Sep 7, 2021

Bug report

AWS recently added a new method of authentication: https://aws.amazon.com/single-sign-on/. However almost none of the methods AWS provides to authenticate work with Nextflow

Expected behavior and actual behavior

  • If you login using the SSO URL in your browser, you are provided with 3 options. When using "Option 1: Set AWS environment variables", I get The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: XXXXXXXXXXXXXX; S3 Extended Request ID: XXXXXXXXXXXXXXXX)
  • When using "Option 2: Add a profile to your AWS credentials file", everything works as it should, I think because this actually sets the aws_access_key_id and aws_secret_access_key in the credentials file
  • Using aws configure sso, which creates a kind of special AWS profile that does not have an access key or id in this form, but instead has the field sso_start_url. Here nextflow gives me Missing AWS security credentials -- Provide access/security keys pair or define a IAM instance profile (suggested)
  • nextflow also doesn't let you provide the credentials on the command line for some reason I don't understand. e.g. nextflow run foo.nf -aws.accessKey XXXXXXXX -aws.secretKey YYYYYYYYY. This gives Unknown option: -aws.accessKey.

Steps to reproduce the problem

  • Ensure you have a nextflow pipeline configured for AWS Batch
  • Setup SSO: https://console.aws.amazon.com/singlesignon/home
  • Create a new User
  • Create a new Permission Set that is allowed to run batch jobs and edit S3 files
  • Assign the new user to the permission set
  • Log in as that user using either the browser or the CLI, and then follow the 3 above options

Program output

See above.

Environment

  • Nextflow version: 21.04.0
  • Java version: 1.8.0_152-release-1056-b12
  • Operating system: Ubuntu Linux 21.04
  • Bash version: 5.1.4
@multimeric
Copy link
Author

It seems that this is an issue caused by the way we create an AWS client:

AmazonClientFactory(Map config) {
// -- get the aws credentials
List credentials
if( config.accessKey && config.secretKey ) {
this.accessKey = config.accessKey
this.secretKey = config.secretKey
if (config.sessionToken){
this.sessionToken = config.sessionToken
}
}
else if( (credentials= Global.getAwsCredentials()) ) {
this.accessKey = credentials[0]
this.secretKey = credentials[1]
if (credentials.size() == 3){
this.sessionToken = credentials[2]
}
}
if( !accessKey && !fetchIamRole() )
throw new AbortOperationException("Missing AWS security credentials -- Provide access/security keys pair or define a IAM instance profile (suggested)")
// -- get the aws default region
region = config.region ?: Global.getAwsRegion() ?: fetchRegion()
if( !region )
throw new AbortOperationException('Missing AWS region -- Make sure to define in your system environment the variable `AWS_DEFAULT_REGION`')
}

I'm sure there's a better way to do this by just deferring to the default AWS library for this, but I'm not 100% sure how to go about this.

@pditommaso
Copy link
Member

A java based example showing how AWS SSO is expected to work could be useful in this context.

@pditommaso
Copy link
Member

But this does not use AWS keys at all!

@multimeric
Copy link
Author

No it doesn't, I think that's kind of the point. It's like OAuth wherein each user signs in using the browser and then it gives you back a token which is stored in ~/.aws/sso/, which is just automatically used until it expires. The application itself shouldn't have to deal with the keys directly.

@multimeric
Copy link
Author

I would say this can be solved in two steps.

The first, easier step is just getting nextflow to understand SSO credentials obtained from the web console. These are regular credential sets, with an access key, secret key and session token. This corresponds to my first dot point. I'm a bit surprised this doesn't work already, actually, and I think it might relate to the fact that we're only using the 1.X SDK instead of 2.X which likely supports this kind of auth:

api ('io.nextflow:nxf-s3fs:1.1.1') { transitive = false }
api ('com.amazonaws:aws-java-sdk-s3:1.11.1034')
api ('com.amazonaws:aws-java-sdk-ec2:1.11.1034')
api ('com.amazonaws:aws-java-sdk-batch:1.11.1034')
api ('com.amazonaws:aws-java-sdk-iam:1.11.1034')
api ('com.amazonaws:aws-java-sdk-ecs:1.11.1034')

However these credentials will expire very rapidly, which is annoying for users, so as the second step it is worth considering a full SSO auth client which is demonstrated in the above links.

@stale
Copy link

stale bot commented Feb 11, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Feb 11, 2022
@rmarable
Copy link

Are there any plans to address this?

@stale
Copy link

stale bot commented Dec 21, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@siims
Copy link

siims commented Apr 19, 2023

I have some interest in adding this feature. Would it be ok to pick it up? or someone already has it in their todo?

@pditommaso
Copy link
Member

We recently improved a lot the auth logic for AWS, but SSO is still missing (unless it's included in the default credentials chain)

protected AWSCredentialsProvider getCredentialsProvider0() {
if( accessKey && secretKey ) {
final creds = new BasicAWSCredentials(accessKey, secretKey)
return new AWSStaticCredentialsProvider(creds)
}
if( profile ) {
return new ProfileCredentialsProvider(configFile(), profile)
}
return new AWSCredentialsProviderChain(List.of(new EnvironmentVariableCredentialsProvider(),
new SystemPropertiesCredentialsProvider(),
WebIdentityTokenCredentialsProvider.create(),
new ProfileCredentialsProvider(configFile(), null),
new EC2ContainerCredentialsProviderWrapper()))
}

Feel free to provide a PR

@pditommaso pditommaso added this to the 23.10.0 milestone Jun 16, 2023
@pditommaso
Copy link
Member

This may be doable using the AWS SDK v2 to sign-in and writing an adapter to authenticate the AWS client based on SDK v1, as described here

aws/aws-sdk-java#2434 (comment)

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

Successfully merging a pull request may close this issue.

5 participants