Skip to content

xds: Implement GcpAuthenticationFilter #11638

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

Merged
merged 10 commits into from
Nov 6, 2024

Conversation

shivaspeaks
Copy link
Member

@shivaspeaks shivaspeaks commented Oct 24, 2024

This is a step towards gRFC A83.
When enabled for a listener, GcpAuthenticationFilter fetches JWT tokens from GCE Metadata Server for the cluster audience, creates Google Cloud CallCredentials using the token and attaches them to outgoing RPCs.

@shivaspeaks
Copy link
Member Author

@ejona86 I see there's one more mistake in this PR,

GcpAuthenticationFilter.java and LruCache.java both are in package io.grpc.xds.internal which is not what I intended to do. Probably it slipped in track-pad while refactoring.

I wanted to put GcpAuthenticationFilter.java in package io.grpc.xds where all other Filters are residing. And LruCache.java in package io.grpc.xds.internal.
Makes sense? What do you think?

@ejona86
Copy link
Member

ejona86 commented Oct 25, 2024

I suggest putting both in the same package (io.grpc.xds) and both being package-private. LruCache is small and only used by the Filter, having it close to the filter is helpful.

(Personally, I'd generally put LruCache as a nested class of the Filter. Yes, you can think it can be reused, but reusable code is reusable when it is reused. Until then "reusable" is a lie and can be harmful if you make the wrong thing complex to make some code generic. We can always move the code out of the class. Even in this case, the long of maxSize "pollutes" the LruCache with random Filter logic.)

@ejona86
Copy link
Member

ejona86 commented Oct 25, 2024

(Although I'll also mention that in cases like this where it doesn't matter, it's mostly up to the author of the code to decide these sorts of things.)

@shivaspeaks
Copy link
Member Author

shivaspeaks commented Oct 25, 2024

we no longer need to return-an-error/NAK if the value is too large; we'd only NAK on zero. Other cases we just clamp to our maximum.

Alright, so we do check for <=0 values in our parseFilterConfig() and in LRUCache we do clamp to the minimum of our max or provided size. I think we're good with this implementation. But I want to know more about the downsides of limiting the size to our maximum.

FYI, the highlighted message in this comment is from grpc/proposal#438 (comment)

@ejona86
Copy link
Member

ejona86 commented Oct 25, 2024

Well, <0 for a uint is "very large", so those should get clamped instead of fail. You can use UnsignedLongs from Guava to help do the comparisons.

There's no real downside to our limit. A thousand would be a heck of a lot and a million is outrageous. A billion is well beyond the realm of legitimate.

@shivaspeaks shivaspeaks requested a review from ejona86 October 25, 2024 21:10
Copy link
Member

@ejona86 ejona86 left a comment

Choose a reason for hiding this comment

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

The Bazel build will need fixing. It looks like it needs a newer version of the protos. See MODULE.bazel and repositories.bzl (those duplicate each other's functionality, because of a Bazel ecosystem migration to bzlmod).

static final String TYPE_URL =
"type.googleapis.com/envoy.extensions.filters.http.gcp_authn.v3.GcpAuthnFilterConfig";

public GcpAuthenticationFilter() {
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to have this constructor. public qualifier in a package private class is also not useful.

cacheSize = cacheConfig.getCacheSize().getValue();
if (cacheSize == 0) {
return ConfigOrError.fromError(
"cache_config.cache_size must be in the range (0, INT64_MAX)");
Copy link
Member

Choose a reason for hiding this comment

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

Remove the part about int64_max. That's out-of-date.

@Test
public void testParseFilterConfig_withInvalidMessageType() {
GcpAuthenticationFilter filter = new GcpAuthenticationFilter();
Message invalidMessage = Mockito.mock(Message.class);
Copy link
Member

Choose a reason for hiding this comment

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

Don't mock a Message. That won't behave correctly in many cases. A well-known type would be convenient for this test, like Empty.getInstance().

}

@Test
public void testBuildClientInterceptor() {
Copy link
Member

Choose a reason for hiding this comment

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

This test could use a better name. It seems to do more than the name suggests.


assertNull(result.config);
assertNotNull(result.errorDetail);
assertTrue(result.errorDetail.contains("Invalid config type"));
Copy link
Member

Choose a reason for hiding this comment

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

assertTrue() produces particularly unhelpful error messages. Prefer Truth. assertThat(result.errorDetail).contains("Invalid config type") produces much better results. You also then don't need the assertNotNull() check.

@Test
public void testParseFilterConfig_withValidConfig() {
GcpAuthnFilterConfig config = GcpAuthnFilterConfig.newBuilder()
.setCacheConfig(TokenCacheConfig.newBuilder().setCacheSize(UInt64Value.of(10)))
Copy link
Member

Choose a reason for hiding this comment

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

Use a value other than the default? How else do you know the config was used?

assertNull(result.errorDetail);
assertEquals(10L,
((GcpAuthenticationFilter.GcpAuthenticationConfig)
result.config).getCacheSize());
Copy link
Member

Choose a reason for hiding this comment

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

Unwrap some? It seems this will fit on the line above just fine, and then would be more readable.

@shivaspeaks shivaspeaks merged commit 76705c2 into grpc:master Nov 6, 2024
14 of 15 checks passed
@shivaspeaks shivaspeaks deleted the gcp-authn-filter branch November 7, 2024 06:55
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 6, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants