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: Support querying S2A Addresses from MDS #1400

Merged
merged 49 commits into from
Oct 29, 2024

Conversation

rmehta19
Copy link
Contributor

@rmehta19 rmehta19 commented May 9, 2024

Add utility to get S2A address from MDS MTLS autoconfiguration endpoint.

This utility will be used when creating mTLS channel using S2A Java Client, which takes S2A Address as input to create S2AChannelCredentials.

Parallel change in go: googleapis/google-api-go-client#1874
S2A Java client: grpc/grpc-java#11113

Resolving b/376258193 means that S2A.java is no longer experimental

@rmehta19 rmehta19 requested a review from a team as a code owner May 9, 2024 00:20
@product-auto-label product-auto-label bot added the size: l Pull request size is large. label May 9, 2024
@rmehta19 rmehta19 force-pushed the s2a-java-integration branch from 0f96e86 to ddac7aa Compare May 9, 2024 00:24
@clundin25 clundin25 requested a review from westarle May 13, 2024 18:36
@rmehta19
Copy link
Contributor Author

cc: @xmenxk

oauth2_http/java/com/google/auth/oauth2/S2A.java Outdated Show resolved Hide resolved
oauth2_http/java/com/google/auth/oauth2/S2A.java Outdated Show resolved Hide resolved
oauth2_http/java/com/google/auth/oauth2/S2A.java Outdated Show resolved Hide resolved
oauth2_http/java/com/google/auth/oauth2/S2A.java Outdated Show resolved Hide resolved
Copy link

@rmehta19
Copy link
Contributor Author

@westarle, friendly ping :). Please review when you get a chance.

Copy link
Contributor

@lqiu96 lqiu96 left a comment

Choose a reason for hiding this comment

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

Thanks for working with us to address the comments. I think this mostly looks good to me given the context.

Can you also do two additional things:

  1. Run mvn fmt:format on this PR?
  2. Update the title to be feat: {title}? Something that describes the functionality feat: Support querying S2A Addresses from MDS or whatever you think aptly describes it.

@rmehta19 rmehta19 changed the title Query S2A Address from MDS feat: Support querying S2A Addresses from MDS Oct 25, 2024
@rmehta19
Copy link
Contributor Author

@lqiu96 , I've addressed your latest round of comments -- thanks for the feedback!

Run mvn fmt:format on this PR?

Done in 16fd964

Update the title to be feat: {title}? Something that describes the functionality feat: Support querying S2A Addresses from MDS or whatever you think aptly describes it.

Done.

Comment on lines 53 to 58
transportFactory.transport.setS2AContentMap(
"plaintextS2AAddressJsonKey", S2A.S2A_PLAINTEXT_ADDRESS_JSON_KEY);
transportFactory.transport.setS2AContentMap("plaintextS2AAddress", S2A_PLAINTEXT_ADDRESS);
transportFactory.transport.setS2AContentMap(
"mtlsS2AAddressJsonKey", S2A.S2A_MTLS_ADDRESS_JSON_KEY);
transportFactory.transport.setS2AContentMap("mtlsS2AAddress", S2A_MTLS_ADDRESS);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I was going to suggest something like:
For valid data:

transportFactory.transport.setS2AContentMap(
  ImmutableMap.of(S2A.S2A_PLAINTEXT_ADDRESS_JSON_KEY, S2A_PLAINTEXT_ADDRESS,
                  S2A.S2A_MTLS_ADDRESS_JSON_KEY, S2A_MTLS_ADDRESS));

For invalid data:

transportFactory.transport.setS2AContentMap(
  ImmutableMap.of(INVALID_JSON_KEY, S2A_PLAINTEXT_ADDRESS,
                  S2A.S2A_MTLS_ADDRESS_JSON_KEY, S2A_MTLS_ADDRESS));

And the content would be populated via iteration through tkey k/v's of the map. Something like:

if (requestStatusCode == 200) {
  for (Map.Entry<String, String> entrySet: content.entrySet()) {
    content.put(entrySet.getKey(), entrySet.getValue())
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is more succinct -- thanks. Done in 1e6c058

Copy link
Contributor

@lqiu96 lqiu96 left a comment

Choose a reason for hiding this comment

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

LGTM. Added a few nits. Please do let @zhumin8 to review and give an approval as well

@rmehta19
Copy link
Contributor Author

LGTM. Added a few nits. Please do let @zhumin8 to review and give an approval as well

Thanks for the review @lqiu96 ! @zhumin8 , please let me know if there is anything else to address, thanks!

return new Builder();
}

public String getPlaintextAddress() {

Choose a reason for hiding this comment

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

I'd like Javadocs for all these public things, pointing to public docs for MDS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't have this documented in public MDS docs (e.g. https://cloud.google.com/compute/docs/metadata/predefined-metadata-keys). We do have an AIP: https://google.aip.dev/auth/4115 which discusses this autconfig endpoint and how it fits in the mTLS via S2A + bound tokens story. WDYT about 934679c?

Choose a reason for hiding this comment

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

Please include the documentation for each public method here. The AIP isn't a great landing place -- can you please look into improving the public MDS docs at least with a bug to the metadata service team?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 8ca8d69

The AIP isn't a great landing place -- can you please look into improving the public MDS docs at least with a bug to the metadata service team?

Agreed that public MDS docs will need to be updated to document this auto-mtls-configuration MDS endpoint that is being queried to learn where S2A is running. The endpoint is currently still experimental. I created a bug to track this internally, will share it with you in our meeting later today.

Copy link
Contributor

@zhumin8 zhumin8 left a comment

Choose a reason for hiding this comment

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

Added two minor comments below, otherwise LGTM.

OAuth2Utils.validateString(
responseData, S2A_PLAINTEXT_ADDRESS_JSON_KEY, PARSE_ERROR_S2A);
} catch (IOException ignore) {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add comment on why these are ignored?

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 added a comment in 6644d50. In general, if there is any error in this function, we ignore, and populate empty addresses in the S2AConfig.

Comment on lines +165 to +166
HttpResponse response = request.execute();
InputStream content = response.getContent();
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe do try/catch block around these to be more specific about the exceptions catching? Nested try/catch blocks are a bit hard to read.

Copy link
Contributor

@lqiu96 lqiu96 Oct 28, 2024

Choose a reason for hiding this comment

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

Ah, I think I was the one that suggested this, but am open to having the try-catch blocks be more specific or a different implementation.

I suggested just have one try-catch block since this code doesn't catch or return the error message back to the user. It just catches any IO error and returns an empty S2AConfig back. Unfortunately, this doesn't provide any useful feedback to the user. Given that this is how it behaves already in Go, I thought it would just be simpler to have a catch-all (one big try block) for this logic.

Ideally, we would have more specific try-catch blocks which could tell the user exactly what went wrong (i.e. failed to build the request because x, or the request failed because of y).

I believe there are two spots where we potentially would need to add try-catches:

  1. parseAs (Ah, thanks for the correction below)
  2. request.execute()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are a few places in this block that throw an IOException (the parseAs and buildGetRequest also throw IOException), so I removed the current nested try/catch block structure and added two separate try/catch blocks around the lines that throw an exception. Because we are getting rid of the big block, I also moved around variable definitions closer to where they are used.

6644d50

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lqiu96 , I think my changes and your comment happened at same time. Reading through your comment, the changes I just push match your suggestion. I removed the big try/catch and just did 2 smaller ones around building the request and executing it.

@zhumin8 , @lqiu96: I am fine with either option -- let me know if you prefer reverting to the 1 big/try catch block, or if you prefer the current state which has no nesting, but a few smaller try/catch blocks

Copy link
Contributor

Choose a reason for hiding this comment

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

I am fine with splitting it up to reduce nesting.

@rmehta19
Copy link
Contributor Author

@zhumin8 , @lqiu96, please leave any additional feedback, and let me know if anything else is blocking submission, thanks!

@rmehta19
Copy link
Contributor Author

kokoro integration test is failing, but looks like an unrelated failure in PluggableAuthHandlerTest.java getExecutableResponse_oidcResponse

cc: @zhumin8 @lqiu96

Copy link
Contributor

@lqiu96 lqiu96 left a comment

Choose a reason for hiding this comment

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

I think the test may be flaky. Can you re-run it to confirm?

Copy link

Copy link
Contributor

@zhumin8 zhumin8 left a comment

Choose a reason for hiding this comment

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

LGTM

@lqiu96 lqiu96 merged commit df06bd1 into googleapis:main Oct 29, 2024
17 checks passed
blakeli0 added a commit to googleapis/sdk-platform-java that referenced this pull request Nov 14, 2024
…port (#3326)

Modify the Client Libraries gRPC Channel builder to use mTLS via S2A if
the experimental environment variable is set, S2A is available (We check
this by using utility added in
googleapis/google-auth-library-java#1400), and a
few more conditions (see `shouldUseS2A`).

Following https://google.aip.dev/auth/4115, Only attempt to use S2A
after DirectPath and DCA (https://google.aip.dev/auth/4114) are ruled
out as options. If conditions to use S2A are not met (env variable not
set, or S2A is not running in environment, etc (`shouldUseS2A` returns
false)), fall back to default TLS connection.

When we are creating S2A-enabled Grpc Channel Credentials, we first try
to secure the connection between the client and the S2A via MTLS, using
[MTLS-MDS](https://cloud.google.com/compute/docs/metadata/overview#https-mds)
credentials. If MTLS-MDS credentials can't be loaded, then we fallback
to a plaintext connection between the client and S2A.

The parallel go implementation : googleapis/google-api-go-client#1874
(now lives here:
https://github.com/googleapis/google-cloud-go/blob/main/auth/internal/transport/cba.go)

S2A Java client: https://github.com/grpc/grpc-java/tree/master/s2a

Resolving b/376258193 means that S2A.java is no longer experimental

---------

Co-authored-by: blakeli <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: l Pull request size is large.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants