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

feat: implements AWS signature version 4 for signing requests #1047

Merged
merged 15 commits into from Aug 28, 2020
Merged

feat: implements AWS signature version 4 for signing requests #1047

merged 15 commits into from Aug 28, 2020

Conversation

bojeil-google
Copy link
Contributor

This is based on:
https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

It will be used to generate signed requests to AWS GetCallerIdentity API.
https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html

This API is used to return details about the IAM user or role whose
credentials are used to call the operation.

grayside and others added 14 commits August 7, 2020 16:32
* chore: updated samples/package.json [ci skip]

* chore: updated CHANGELOG.md [ci skip]

* chore: updated package.json

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
This PR was generated using Autosynth. 🌈

Synth log will be available here:
https://source.cloud.google.com/results/invocations/5f7f9c6d-c75a-4c60-8bb8-0026a14cead7/targets

- [ ] To automatically regenerate this PR, check this box.

Source-Link: googleapis/synthtool@94421c4
This PR was generated using Autosynth. 🌈

Synth log will be available here:
https://source.cloud.google.com/results/invocations/b742586e-df31-4aac-8092-78288e9ea8e7/targets

- [ ] To automatically regenerate this PR, check this box.

Source-Link: googleapis/synthtool@bd0deaa
This PR was generated using Autosynth. 🌈



- [ ] To automatically regenerate this PR, check this box.

Source-Link: googleapis/synthtool@5747555
* chore: updated samples/package.json [ci skip]

* chore: updated CHANGELOG.md [ci skip]

* chore: updated package.json

Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com>
Minor change that fixes a spelling error. I don't think an issue needed to be opened for this. Thanks!
Add await

Co-authored-by: Justin Beckwith <justin.beckwith@gmail.com>
Co-authored-by: sofisl <55454395+sofisl@users.noreply.github.com>
Co-authored-by: Benjamin E. Coe <bencoe@google.com>
This PR was generated using Autosynth. 🌈

Synth log will be available here:
https://source.cloud.google.com/results/invocations/7a1b0b96-8ddb-4836-a1a2-d2f73b7e6ffe/targets

- [ ] To automatically regenerate this PR, check this box.
This PR was generated using Autosynth. 🌈

Synth log will be available here:
https://source.cloud.google.com/results/invocations/ba2d388f-b3b2-4ad7-a163-0c6b4d86894f/targets

- [ ] To automatically regenerate this PR, check this box.

Source-Link: googleapis/synthtool@05de3e1
This is based on:
https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

It will be used to generate signed requests to AWS GetCallerIdentity API.
https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html

This API is used to return details about the IAM user or role whose
credentials are used to call the operation.
@bojeil-google bojeil-google requested a review from a team as a code owner August 24, 2020 21:31
@codecov
Copy link

codecov bot commented Aug 24, 2020

Codecov Report

❗ No coverage uploaded for pull request base (byoid@26ab5e3). Click here to learn what that means.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff            @@
##             byoid    #1047   +/-   ##
========================================
  Coverage         ?   92.90%           
========================================
  Files            ?       26           
  Lines            ?     5528           
  Branches         ?      613           
========================================
  Hits             ?     5136           
  Misses           ?      392           
  Partials         ?        0           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 26ab5e3...80e3f92. Read the comment docs.

@google-cla
Copy link

google-cla bot commented Aug 24, 2020

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added the cla: no This human has *not* signed the Contributor License Agreement. label Aug 24, 2020
Copy link
Contributor

@bcoe bcoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading through this, I definitely am left wishing there was less complexity 😆

But I also think the implementation is sound, and doesn't introduce any unnecessary complexity.

import {Headers} from './oauth2client';
import {Crypto, createCrypto, fromArrayBufferToHex} from '../crypto/crypto';

type HttpMethod =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if we use a similar type anywhere else in the codebase, or if gaxios exposes it? If not, no objection to having it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that gaxios does not export a dedicated type for this.

I couldn't find any similar type in the current repo.

const dateStamp = now.toISOString().replace(/[-]/g, '').replace(/T.*/, '');

// Change all additional headers to be lower case.
const reformattedAdditionalAmzHeaders: Headers = {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic is definitely the most complex I think I've bumped into during this review, I believe OAuth 1.0 worked similarly, with regards to needing to sort and sign parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree. The crypto they use is not trivial and it is not standard. You are right on the similarities with OAuth 1.0 but at least the latter is a standard and there is sufficient documentation on it.
We had to follow the AWS documentation in order to generate these (step by step). They do provide reference input/outputs for each step which helped.

I think the bulk of the logic is documented in generateAuthenticationHeaderMap. I provided links to the 4 steps and some comments to clarify intermediate steps. I hope this makes it easier for contributors to follow. One possibility that was floated around in the early stages was to pull in AWS SDK as a dependency. However, I think it would be too expensive for serverless and low memory environments like GCF, IOT devices, etc. The auth library is a dependency for a lot of other libraries where this feature is not used so it could be very taxing to these users.

// List of various requests and their expected signatures.
// Examples source:
// https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
const getRequestOptionsTests: AwsRequestSignerTest[] = [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this DSL you've built out for exercising the the fairly complex logic in the AWS request signer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I think this simplifies adding and removing new tests for this logic. It also makes it easier to replace the existing canonical request/signatures we are using. So it should not be expensive to maintain and build on in the future.

@bcoe bcoe added cla: yes This human has signed the Contributor License Agreement. and removed cla: no This human has *not* signed the Contributor License Agreement. labels Aug 27, 2020
@google-cla
Copy link

google-cla bot commented Aug 28, 2020

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@google-cla google-cla bot added cla: no This human has *not* signed the Contributor License Agreement. and removed cla: yes This human has signed the Contributor License Agreement. labels Aug 28, 2020
@bcoe bcoe added cla: yes This human has signed the Contributor License Agreement. and removed cla: no This human has *not* signed the Contributor License Agreement. labels Aug 28, 2020
headers: {
Authorization:
'AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20110909/us-east-1/host/' +
`aws4_request, SignedHeaders=date;host;zoo, Signature=${signature}`,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for pulling these tests over from boto 👍 sorry for being a pain.

@bcoe bcoe merged commit 3020c6f into googleapis:byoid Aug 28, 2020
bcoe added a commit that referenced this pull request Feb 6, 2021
feat: implements the OAuth token exchange spec based on rfc8693 (#1026)
feat: defines ExternalAccountClient abstract class for external_account credentials (#1030)
feat: adds service account impersonation to `ExternalAccountClient` (#1041)
feat: defines `IdentityPoolClient` used for K8s and Azure workloads (#1042)
feat: implements AWS signature version 4 for signing requests (#1047)
feat: defines `ExternalAccountClient` used to instantiate external account clients (#1050)
feat!: integrates external_accounts with `GoogleAuth` and ADC (#1052)
feat: adds text/json credential_source support to IdentityPoolClients (#1059)
feat: get AWS region from environment variable (#1067)
Co-authored-by: Wilfred van der Deijl <wilfred@vanderdeijl.com>
Co-authored-by: Benjamin E. Coe <bencoe@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants