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

awskms unseal: UnrecognizedClientException: The security token included in the request is invalid. #5965

Closed
jhmartin opened this issue Dec 17, 2018 · 7 comments
Milestone

Comments

@jhmartin
Copy link
Contributor

jhmartin commented Dec 17, 2018

Describe the bug
Vault does not consume the AWS_SESSION_TOKEN environmental variable used to pass credentials to the awskms autounseal logic.

When using temporary AWS credentials provided in the environment to perform awskms unsealing, Vault fails with:

Error parsing Seal configuration: error fetching AWS KMS sealkey information: UnrecognizedClientException: The security token included in the request is invalid.
	status code: 400, request id: REDACTED

https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html describes the three variables that may need to be consumed:

$ export AWS_ACCESS_KEY_ID=YOUR_AKID
$ export AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
$ export AWS_SESSION_TOKEN=TOKEN

k.accessKey = os.Getenv("AWS_ACCESS_KEY_ID")
shows it is only consuming the access and secret key, instead of additionally checking for the session token.

I'm able to utilize the awscli with the same set of variables so I am confident my credentials are correctly set.

Expected behavior
Temporary credentials may be passed in via the environment. This is useful when testing Vault on a desktop and using federated SAML-based logins to AWS.

Environment:
Vault v1.0.0 ('c19cef14891751a23eaa9b41fd456d1f99e7e856')
Darwin xxx 17.7.0 Darwin Kernel Version 17.7.0: Thu Jun 21 22:53:14 PDT 2018; root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64

Variables:

VAULT_SEAL_TYPE=awskms
AWS_SESSION_TOKEN=REDACTED
AWS_ACCESS_KEY_ID=REDACTED
AWS_SECRET_ACCESS_KEY=REDACTED
VAULT_AWSKMS_SEAL_KEY_ID=REDACTED

Vault server configuration file(s):

ui = true

storage "file" {
  path = "/some/path/vault.dat"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  cluster_address     = "0.0.0.0:8201"

  tls_disable = 1
}
@jefferai
Copy link
Member

jefferai commented Dec 17, 2018

We actually use AWS SDK's credential chain with the default credential chain, in this order:

Static creds
Env vars
Shared file
IAM

This matches the order via the official SDK's default chain, with the exception of static creds being on top. My guess is that by configuring static creds, you are causing the credential chain to bail after it finds those as being valid, so it never actually looks at the env vars.

@jhmartin
Copy link
Contributor Author

jhmartin commented Dec 17, 2018

@jefferai

k.accessKey = os.Getenv("AWS_ACCESS_KEY_ID")
The above really looks to me like you are overriding the SDK's Env-var functionality, otherwise I'd expect this to work (like it does w/the awscli). I'm not specifying static credentials in the config file.

Similarly,

func (k *AWSKMSSeal) getAWSKMSClient() (*kms.KMS, error) {
passes just the access/secret key then calls the credential chain.

sessionToken := os.Getenv("AWS_SESSION_TOKEN")
is an example of this done correctly.

@jefferai
Copy link
Member

It'd be useful if you can test if it works if you remove those lines reading the env from awskms.go. That way we can know whether we need to add checking AWS_SESSION_TOKEN, like the dynamodb code does, or whether we should actually be stripping all of them out entirely in favor of only using what the SDK provides.

@jhmartin
Copy link
Contributor Author

jhmartin commented Dec 17, 2018

It looks like stripping the custom aws auth logic is the right answer. Commenting out the following two lines worked:

credsConfig.AccessKey = k.accessKey
credsConfig.SecretKey = k.secretKey

I then unset my AWS_SESSION_TOKEN env variable and tried again, and received the expected UnrecognizedClientException error.

(I tested this off of master)

jefferai added a commit that referenced this issue Dec 18, 2018
Let AWS SDK env cred chain provider do it for us

Fixes #5965
@jefferai
Copy link
Member

Any chance I can have you test out #5974?

@jhmartin
Copy link
Contributor Author

jhmartin commented Dec 19, 2018

@jefferai It failed to build until I commented out

var accessKey, secretKey, sessionToken string
if os.Getenv("AWS_ACCESS_KEY_ID") == "" {
accessKey = config["access_key"]
}
if os.Getenv("AWS_SECRET_ACCESS_KEY") == "" {
secretKey = config["secret_key"]
}
if os.Getenv("AWS_SESSION_TOKEN") == "" {
sessionToken = config["session_token"]
}

After that modification it successfully unsealed w/the 3 ENV variables.

Stderr: # github.com/hashicorp/vault/vault/seal/awskms
../../../../../GO/src/github.com/hashicorp/vault/vault/seal/awskms/awskms.go:103:6: accessKey declared and not used
../../../../../GO/src/github.com/hashicorp/vault/vault/seal/awskms/awskms.go:103:17: secretKey declared and not used
../../../../../GO/src/github.com/hashicorp/vault/vault/seal/awskms/awskms.go:103:28: sessionToken declared and not used

@jefferai
Copy link
Member

You don't need to comment on two issues :-) It's already fixed via the other one.

jefferai added a commit that referenced this issue Jan 4, 2019
Let AWS SDK env cred chain provider do it for us

Fixes #5965
jefferai added a commit that referenced this issue Jan 4, 2019
* Don't read AWS env vars

Let AWS SDK env cred chain provider do it for us

Fixes #5965
@jefferai jefferai added this to the 1.0.2 milestone Jan 4, 2019
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

2 participants