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

Unable to assume web identity inside EC2 when no region is set in the environment. #515

Closed
3 tasks done
ereOn opened this issue Mar 25, 2020 · 7 comments · Fixed by #523 or #539
Closed
3 tasks done

Unable to assume web identity inside EC2 when no region is set in the environment. #515

ereOn opened this issue Mar 25, 2020 · 7 comments · Fixed by #523 or #539
Labels
bug This issue is a bug.

Comments

@ereOn
Copy link

ereOn commented Mar 25, 2020

Describe the bug
All requests fail when executed on an EC2 (EKS) instance trying to use AssumeWebIdentity and AWS_REGION wasn't set.

Version of AWS SDK for Go?
v0.20.0

Version of Go (go version)?
go1.14

To Reproduce (observed behavior)
The following code snippet exhibits the problem:

package main

import (
	"github.com/aws/aws-sdk-go-v2/aws/external"
	"github.com/aws/aws-sdk-go-v2/service/sts"
)

func () main() {
    awsCfg, err := external.LoadDefaultAWSConfig()

    if err != nil {
        panic(fmt.Errorf("unable to load AWS SDK config: %s", err))
    }

    if awsCfg.Region == "" {
        awsCfg.Region = "us-east-1"
    }

    stsClient := sts.New(awsCfg)
    _, err := stsClient.GetCallerIdentityRequest(&sts.GetCallerIdentityInput{}).Send(ctx)

    // This call fails even though the region was set manually. If set before hand via `AWS_REGION`, it works as expected.
    if err != nil {
        panic(fmt.Errorf("failed to fetch AWS STS caller identity: %s", err))
    }
}

Expected behavior
The code should work but doesn't when running on an EC2 instance assuming a web identity.

Additional context
I debugged the situation a bit, and it seems the internal AssumeRole call is performed using a default AWS config. Since the default config on EC2 doesn't fetch the EC2 metadata region (yet? #244), the call fails with UnknownEndpointError, even though a region was set on the configuration. From my understanding, the underlying provider in charge of performing the assume-role call doesn't get the manually set region, and uses an empty one instead.

I could find no way of setting the region on the provider itself.

If I set AWS_REGION from inside the process and reload the default configuration once more, the code starts working again. However, this seems overcomplicated and I assume it is not intentional.

@RedbackThomson
Copy link

RedbackThomson commented Mar 30, 2020

It appears to me that the ResolveCredentials resolver, which is called in LoadDefaultAWSConfig in the ResolveAWSConfig function already uses the region that is required to have been set previously, or is not being copied across.

This ResolveCredentials provider redirects through the ResolveCredentialChain function to call NewWebIdentityRoleProvider. Here the provider client is initialised, passing a COPY of the configuration aws.Config which has no default region assumed. This is the client that sts uses later to authenticate all requests. Therefore, the override does not make a difference to the authentication provider.

One such method I am attempting is to override the configuration region before calling external.LoadDefaultAWSConfig, so that in the case where no region override is found in any files or environment variables, it was provided previously. However, I have not been able to get this to work.

@meshuga
Copy link

meshuga commented Mar 31, 2020

I think the answer #492 (comment) might be related with this issue: AWS has multiple partitions, so global endpoint must always be referred in a context of a partition.

@RedbackThomson
Copy link

RedbackThomson commented Mar 31, 2020

I think the answer #492 (comment) might be related with this issue: AWS has multiple partitions, so global endpoint must always be referred in a context of a partition.

I'm not sure if this is entirely correct. Because sts does not care about regionality, the provider is getting confused when we are passing it the aws partition. However, the regions it lists that the endpoint provides are all regionalised. -

WebIdentityErr: failed to retrieve credentials
caused by: unknown endpoint, could not resolve endpoint, partition: \"aws\", service: \"sts\", region: \"\", known: [eu-north-1 eu-west-2 me-south-1 us-east-1-fips us-west-1-fips us-west-2 ap-south-1 ap-southeast-1 eu-west-1 sa-east-1 us-west-1 us-west-2-fips ap-northeast-2 ap-northeast-1 aws-global ca-central-1 us-east-1 us-east-2 us-east-2-fips ap-east-1 eu-central-1 eu-west-3 ap-southeast-2]

@RedbackThomson
Copy link

All new documentation for STS recommends using a regionalised endpoint, and therefore I think there may be an issue within this implementation. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html

@jasdel jasdel added the bug This issue is a bug. label Mar 31, 2020
@jasdel
Copy link
Contributor

jasdel commented Mar 31, 2020

Thanks for reporting this issue. This looks to be a bug in the SDK's implementation of the updated STS endpoint resolving and web identity support.

The STS client used by the web identity token credential provider will use the configured region, if one is set. Though the STS client endpoint lookup no longer allows no region to be specified. This was a bug that was fixed in v0.18.0, and a region must be specified for all clients.

This was missed for STS credential providers though. Those credential provider probably should default to aws-global as the region. But we should investigate if this default behavior would be correct.

@RedbackThomson
Copy link

Are you able to suggest a temporary workaround for this issue? I would be able to provide the region at time of configuration. Is there either some way I can pass this through to the resolver, or to force it to use the global region?

@jasdel
Copy link
Contributor

jasdel commented Apr 1, 2020

Specifying the region either via environment or shared config is the best workaround for this issue at the moment. When investigating this we're also going to see if it makes sense to allow a "default" fallback region to be passed into the LoadAWSDefaultConfig, if one cannot be determined from the environment or shared config.

you can also specify a region when calling LoadAWSDefaultConfig directly

// Sets the region the configuration will be loaded with. Ignoring any environment,
// or shared config specified region.
cfg, err := external.LoadAWSDefaultConfig(external.WithRegion("us-west-2"))

If the SDK were to add support for a "default" region to fallback to, that would probably look like the following. (Note this is not implemented currently).

// Sets the region to be used if the region cannot be determined via the environment,
// shared config, or some other means.
cfg, err := external.LoadAWSDefaultConfig(external.WithDefaultRegion("us-west-2"))

jasdel added a commit that referenced this issue Apr 21, 2020
===

Breaking Change
---
* `aws/endpoints`: Several functions and types have been removed
  * Removes `DecodeModel` and `DecodeModelOptions` from the package ([#509](#509))
  * Remove Region Constants, Partition Constants, and types use for exploring the endpoint data model ([#512](#512))
* `service/s3/s3crypto`: Package and associated encryption/decryption clients have been removed from the SDK ([#511](#511))
* `aws/external`: Removes several export constants and types ([#508](#508))
  * No longer exports AWS environment constants used by the external environment configuration loader
  * `DefaultSharedConfigProfile` is now defined an exported constant
* `aws`: `ErrMissingRegion`, `ErrMissingEndpoint`, `ErrStaticCredentialsEmpty` are now concrete error types ([#510](#510))

Services
---
* Synced the V2 SDK with latest AWS service API definitions.

SDK Features
---
* `aws/signer/v4`: New methods `SignHTTP` and `PresignHTTP` have been added ([#519](#519))
  * `SignHTTP` replaces `Sign`, and usage of `Sign` should be migrated before it's removal at a later date
  * `PresignHTTP` replaces `Presign`, and usage of `Presign` should be migrated before it's removal at a later date
  * `DisableRequestBodyOverwrite` and `UnsignedPayload` are now deprecated options and have no effect on `SignHTTP` or `PresignHTTP`. These options will be removed at a later date.
* `aws/external`: Add Support for setting a default fallback region and resolving region from EC2 IMDS ([#523](#523))
  * `WithDefaultRegion` helper has been added which can be passed to `LoadDefaultAWSConfig`
    * This helper can be used to configure a default fallback region in the event a region fails to be resolved from other sources
  * Support has been added to resolve region using EC2 IMDS when available
    * The IMDS region will be used if region as not found configured in either the shared config or the process environment.
  * Fixes [#244](#244)
  * Fixes [#515](#515)
SDK Enhancements
---
* `service/dynamodb/expression`: Add IsSet helper for ConditionBuilder and KeyConditionBuilder ([#494](#494))
  * Adds a IsSet helper for ConditionBuilder and KeyConditionBuilder to make it easier to determine if the condition builders have any conditions added to them.
  * Implements [#493](#493).
* `internal/ini`: Normalize Section keys to lowercase ([#495](#495))
  * Update's SDK's ini utility to store all keys as lowercase. This brings the SDK inline with the AWS CLI's behavior.

SDK Bugs
---
* `internal/sdk`: Fix SDK's UUID utility to handle partial read ([#536](#536))
  * Fixes the SDK's UUID utility to correctly handle partial reads from its crypto rand source. This error was sometimes causing the SDK's InvocationID value to fail to be obtained, due to a partial read from crypto.Rand.
  * Fix [#534](#534)
* `aws/defaults`: Fix request metadata headers causing signature errors ([#536](#536))
    * Fixes the SDK's adding the request metadata headers in the wrong location within the request handler stack. This created a situation where a request that was retried would sign the new attempt using the old value of the header. The header value would then be changed before sending the request.
    * Fix [#533](#533)
    * Fix [#521](#521)
jasdel added a commit that referenced this issue Apr 22, 2020
Breaking Change
---
* `aws/endpoints`: Several functions and types have been removed
  * Removes `DecodeModel` and `DecodeModelOptions` from the package ([#509](#509))
  * Remove Region Constants, Partition Constants, and types use for exploring the endpoint data model ([#512](#512))
* `service/s3/s3crypto`: Package and associated encryption/decryption clients have been removed from the SDK ([#511](#511))
* `aws/external`: Removes several export constants and types ([#508](#508))
  * No longer exports AWS environment constants used by the external environment configuration loader
  * `DefaultSharedConfigProfile` is now defined an exported constant
* `aws`: `ErrMissingRegion`, `ErrMissingEndpoint`, `ErrStaticCredentialsEmpty` are now concrete error types ([#510](#510))

Services
---
* Synced the V2 SDK with latest AWS service API definitions.

SDK Features
---
* `aws/signer/v4`: New methods `SignHTTP` and `PresignHTTP` have been added ([#519](#519))
  * `SignHTTP` replaces `Sign`, and usage of `Sign` should be migrated before it's removal at a later date
  * `PresignHTTP` replaces `Presign`, and usage of `Presign` should be migrated before it's removal at a later date
  * `DisableRequestBodyOverwrite` and `UnsignedPayload` are now deprecated options and have no effect on `SignHTTP` or `PresignHTTP`. These options will be removed at a later date.
* `aws/external`: Add Support for setting a default fallback region and resolving region from EC2 IMDS ([#523](#523))
  * `WithDefaultRegion` helper has been added which can be passed to `LoadDefaultAWSConfig`
    * This helper can be used to configure a default fallback region in the event a region fails to be resolved from other sources
  * Support has been added to resolve region using EC2 IMDS when available
    * The IMDS region will be used if region as not found configured in either the shared config or the process environment.
  * Fixes [#244](#244)
  * Fixes [#515](#515)

SDK Enhancements
---
* `service/dynamodb/expression`: Add IsSet helper for ConditionBuilder and KeyConditionBuilder ([#494](#494))
  * Adds a IsSet helper for ConditionBuilder and KeyConditionBuilder to make it easier to determine if the condition builders have any conditions added to them.
  * Implements [#493](#493).
* `internal/ini`: Normalize Section keys to lowercase ([#495](#495))
  * Update's SDK's ini utility to store all keys as lowercase. This brings the SDK inline with the AWS CLI's behavior.


SDK Bugs
---
* `internal/sdk`: Fix SDK's UUID utility to handle partial read ([#536](#536))
  * Fixes the SDK's UUID utility to correctly handle partial reads from its crypto rand source. This error was sometimes causing the SDK's InvocationID value to fail to be obtained, due to a partial read from crypto.Rand.
  * Fix [#534](#534)
* `aws/defaults`: Fix request metadata headers causing signature errors ([#536](#536))
    * Fixes the SDK's adding the request metadata headers in the wrong location within the request handler stack. This created a situation where a request that was retried would sign the new attempt using the old value of the header. The header value would then be changed before sending the request.
    * Fix [#533](#533)
    * Fix [#521](#521)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug.
Projects
None yet
4 participants