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 for AWS Single Sign-on (SSO) #1402

Open
sentience opened this issue Jan 24, 2023 · 7 comments
Open

Support for AWS Single Sign-on (SSO) #1402

sentience opened this issue Jan 24, 2023 · 7 comments
Assignees

Comments

@sentience
Copy link

Is your feature request related to a problem? Please describe.
My company uses AWS Single Sign-on (SSO) (recently relaunched as IAM Identity Center) to require our engineers to log into AWS and assume roles using the same credentials that we use to access our other internal services and systems.

Currently, Architect does not support this form of authentication, requiring a clumsy work-around (see below).

Architect currently complains that AWS_PROFILE is not configured when it is configured for SSO:

$ aws sso login --profile <ProfileName>

$ AWS_PROFILE=<ProfileName> npx arc deploy
      App - appName
   Region - us-west-2
  Profile - @aws profile / AWS_PROFILE not configured
  Version - Architect 10.8.4
      Cwd - /path/to/app

deploy failed! Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1

Describe the solution you'd like
I'd like Architect transparently to support AWS SSO:

aws sso login --profile <ProfileName>
AWS_PROFILE=<ProfileName> npx arc deploy

Describe alternatives you've considered
The work-around I'm currently using is to set up a shell alias (thanks to @monken) that lets me convert my AWS SSO session into legacy credentials (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY). I've added this to my .zshrc:

function awscreds() {
    export AWS_PAGER=""
    aws sts get-caller-identity --profile $1 || aws sso login --profile $1
    FILE=~/.aws/cli/cache/$(ls -t ~/.aws/cli/cache | head -n 1)

    export AWS_ACCESS_KEY_ID="$(jq -r '.Credentials.AccessKeyId' $FILE)" AWS_SECRET_ACCESS_KEY="$(jq -r '.Credentials.SecretAccessKey' $FILE)" AWS_SESSION_TOKEN="$(jq -r '.Credentials.SessionToken' $FILE)"
}

…and then I can use Architect like this:

aws sso login --profile <ProfileName>
awscreds <ProfileName>
npx arc deploy

This is workable, but significantly more cumbersome to scale to a team, and it leaves the shell environment "polluted" with the temporary SSO-generated credentials that I need to remember to remove or replace when I'm done working with this profile.

Additional context or notes
Actual screenshot of this affecting me:

image

@ryanblock
Copy link
Member

ryanblock commented Mar 1, 2023

Ok, good news, I took a look at this tonight and have some answers (and questions). First, a bit of technical background:

Architect assumes that its users may (or may not) have a ~/.aws/credentials file, and if so, it may contain one or more profiles. If no @aws profile setting is specified in their app.arc manifest, default is used. If one is specified in app.arc, it will be attempted to be used.

Users can also set credentials via standard AWS env vars (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, handy for CI).

Using aws sso login --profile <profile name> does not write temporary credentials to ~/.aws/credentials or add them to the environment via AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY env vars. (This is probably the correct behavior.)

An AWS credentials object instantiated via SSO can be loaded programmatically (by Architect) via the AWS.SsoCredentials({ profile }) method. However, this method was not introduced until I believe a minimum of 2.1093.0, and it didn't really appear to begin to take advantage of the new SSO config file format until 2.1253.0 (late 2022).

Architect uses SDK v2.1055.0 because that's what Lambda uses. Specifically: nodejs16.x uses 2.1083.0, while nodejs12.x + nodejs14.x use 2.1055.0 (which is the AWS SDK version currently pinned in Architect:

"aws-sdk": "2.1055.0",
). A long time ago we used to use the latest version of the SDK, and then folks started developing with methods that weren't available in globally installed version found in Lambda, and they were broken. So we vowed to solve this for them by making sure the Architect environment was as close to Lambda as possible in this (and, well, every other feasible) way.

So the primary technical challenge here is: how to instantiate these credentials programmatically, quickly, without resorting to shenanigans like having two installations of AWS SDK v2 (which clocks in at thousands of files and ~90MB). Yes, we could just upgrade the SDK to a version that supports AWS.SsoCredentials, but that leaves us open to the issues we had before where Sandbox's Lambda emulation diverges from AWS.

Ok, so assuming we solve that¹, now what does the ideal solution look like in Arc-land? Some related questions:

  • Does specifying the profile in @arc profile now attempt to fall back to attempting to load via AWS.SsoCredentials?
    • Can teams collaborating on an Architect project be counted on to all use the same profile name, such that it makes sense to commit to app.arc as @arc profile? I assume so, as they would with the credentials file, but I don't use SSO so I don't know.
  • What if you specify @arc profile foo and foo is found in your credentials file, in addition to being the SSO profile name you logged in with?
  • I'm sure I'll come up with a few more after I step away with the machine here, so stay tuned...

/cc @Ankcorn

¹ I'm open to ideas on how. This module looks promising, but at best it'd probably have to be forked, as it is pretty massive due to all its CLI tooling.

  • Update: I tried a quick bundle of this module and it's over 17MB, so without a fair amount of work that probably won't be a workable solution.
  • Update: I got the size down, but this codebase would require a huge refactor or possible rewrite to make it sync. It's a non-starter, and would probably be easier to author from scratch, which is a pretty heavy lift tbh. The simpler approach is to just use the AWS SDK, but it has the issues noted above. Additionally, @aws-sdk/credential-providers and @aws-sdk/credential-provider-sso are both very, very large, so they should be ruled out as well.

@sentience
Copy link
Author

Can teams collaborating on an Architect project be counted on to all use the same profile name

For the record, our team does not necessarily use the same profile names, so we would not want to commit a profile name in app.arc (but if Architect required this, we could probably make it would by having our setup guide explain to our engineers that they must use a specific profile name).

@sentience
Copy link
Author

sentience commented Mar 1, 2023

Our typical engineer setup is to have all profiles configured in our ~/.aws/config file. Our engineers generally do not have a ~/.aws/credentials file. Is this unusual?

A typical entry in our ~/.aws/config file:

[profile 747126643643:CampFoundationsRole]
; alias = cultureamp-staging-eu
region = eu-west-1
sso_start_url = https://cultureamp.awsapps.com/start
sso_region = us-west-2
sso_account_id = 747126643643
sso_role_name = CampFoundationsRole

@ryanblock
Copy link
Member

Our engineers generally do not have a ~/.aws/credentials file. Is this unusual?

While I'm definitely not qualified to say what's usual or unusual, given what I've learned about SSO thus far, if that's what you're expected to use, that seems normal. However, any dev with a personal / side-project AWS accounts will probably have a credentials file, so I think we should assume both may be found.

@ryanblock
Copy link
Member

Discussed further this morning with @brianleroux and we're coming around to the idea of enabling this by upgrading aws-sdk to a more recent version to support SSO credential loading. As mentioned, this comes at the cost of opening up a fairly big bug vector for users developing locally with aws-sdk. Curious what everyone's thoughts are on this specific tradeoff!

@ryanblock ryanblock added this to the 10.12 milestone Apr 23, 2023
@ryanblock ryanblock self-assigned this Apr 23, 2023
@ryanblock ryanblock linked a pull request Apr 23, 2023 that will close this issue
10 tasks
@ryanblock ryanblock removed a link to a pull request Apr 25, 2023
10 tasks
@ryanblock ryanblock modified the milestones: 10.12, 10.13 Apr 25, 2023
@andybee
Copy link

andybee commented May 10, 2023

Just want to add that I've recently started working on a project that uses SSO, but I am in that situation identified by @ryanblock that I have both an SSO profile in ~/.aws/config and other accounts creds in ~/.aws/credentials.

I think the tradeoff with AWS SDK version is reasonable. Presumably anyone who is targeting a Node.js version and related AWS SDK version below that which Arc internals require could include that locally in their project package.json (bloat and all)?

@clovis1122
Copy link

In my case I also needed to add ARC_AWS_CREDS=env after adding the environment variables to the shell for it to work.

@ryanblock ryanblock removed this from the 10.x milestone Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants