-
Notifications
You must be signed in to change notification settings - Fork 348
JWT authentication for gRPC transport #5916
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
JWT authentication for gRPC transport #5916
Conversation
74b20c6 to
d25e5eb
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5916 +/- ##
==========================================
+ Coverage 73.70% 73.77% +0.06%
==========================================
Files 437 439 +2
Lines 26749 26883 +134
Branches 3961 3979 +18
==========================================
+ Hits 19716 19832 +116
- Misses 5150 5160 +10
- Partials 1883 1891 +8
🚀 New features to boost your workflow:
|
nibix
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this. I have added a few comments.
I have one high level question regarding the configuration:
Is there any way I can configure JWT auth to be supported for gRPC but not for HTTP - or vice versa? It seems to be there is not such way.
Back when we supported authc for the internal transport protocol, it was possible to selectively enable certain methods for transport and for http (compare the http_enabled and transport_enabled flags in config.yml)
src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/filter/GrpcRequestChannel.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/filter/SecurityGrpcFilter.java
Outdated
Show resolved
Hide resolved
src/test/java/org/opensearch/security/auth/BackendRegistryGrpcAuthTest.java
Outdated
Show resolved
Hide resolved
|
Thanks for the feedback @nibix !
There is not currently. Unless security plugin is in ssl only mode if JWT is configured it will be utilized for gRPC requests. As I understand it this is mostly* the case for REST as well? There is this one setting which lets users disable auth entirely for REST under |
src/integrationTest/java/org/opensearch/security/grpc/GrpcHelpers.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/filter/SecurityGrpcFilter.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/auth/BackendRegistry.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/auth/BackendRegistry.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/auth/BackendRegistry.java
Outdated
Show resolved
Hide resolved
a6a0eac to
1ce66c0
Compare
In OpenSearch 1.0, you could do: This would only enable auth for transport requests, but not for HTTP requests. Maybe it would make sense to revive this concept? |
I see. I didn't realize you could selectively disable auth like this. Looking at this setting it seems to be a member of authc domain configuration object which is loaded by the dynamic config. The current design doesn't touch this part of the code since auth domains are not built and configured per transport, but created once and shared between gRPC and REST. The setting This means my earlier comment here is false:
If we want to allow users to disable auth on all client/server transports it looks like this should already be covered since To support something like |
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
1ce66c0 to
2c5f09e
Compare
…lightly. Signed-off-by: Finn Carroll <[email protected]>
… gRPC. Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
DarshitChanpura
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @finnegancarroll for adding this new authn mechanism. I didn't take a deeper look but at a glance they look good.
Left some clarification questions.
src/main/java/org/opensearch/security/auth/BackendRegistry.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/auth/BackendRegistry.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
|
Thanks @DarshitChanpura, updated with your suggestions. |
|
Testing I notice an additional change required for this PR. The gRPC interceptor does not respect Waiting on opensearch-project/OpenSearch#20493 to publish a new snapshot before adding the change to this branch. |
RyanL1997
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the change @finnegancarroll.
src/integrationTest/java/org/opensearch/security/grpc/JWTGrpcInterceptorTest.java
Outdated
Show resolved
Hide resolved
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
Signed-off-by: Finn Carroll <[email protected]>
DarshitChanpura
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good to me. Can you add a happy path for manual test cases you added in the PR description?
| @@ -1,16 +1,9 @@ | |||
| /* | |||
| * Copyright 2015-2018 _floragunn_ GmbH | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep this header in existing files. Please follow-up to add this back in.
| final String sslPrincipal = (String) threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_SSL_PRINCIPAL); | ||
|
|
||
| if (adminDns.isAdminDN(sslPrincipal)) { | ||
| if (!gRPC && adminDns.isAdminDN(sslPrincipal)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to actually check if its a gRPC request here? Would the value for sslPrincipal always be null for gRPC requests? If so the existing logic may work as intended.
| * Extracts security headers from the gRPC metadata and authenticates the user against the backend registry. | ||
| * Authenticated users are stashed in the thread context for authorization processing on the transport layer. | ||
| */ | ||
| private static class AuthNGrpcInterceptor implements ServerInterceptor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can extract this to a separate public class and using dependency injection (@Inject) to avoid having to modify the GuiceHolder. Can you please follow up this PR to see if dep injection can be used here?
dep injection doesn't work with private inner classes, private methods or private fields. Our fork of Guice in the core only works w/ public.
cwperks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving this PR as my comments are mostly organizational. Please follow-up and address in subsequent PRs.
|
This PR raises the existing bar for security for gRPC which is only encryption-in-transit (EIT). Its nice to see this rolled out with a first phase targeting JWT auth. Please post any perf gains that you've seen compared to HTTP for comparison. |
Description
These changes provide JWT authentication/authorization over the gRPC transport. All options for configuring JWT/User/Roles on a cluster remain the same with the gRPC transport sharing the auth domains of the REST API. As a result, users provide the same JWT HTTP headers over gRPC as they would on the REST API, with tokens being validated against the same authentication backend. This initial PR adds
HTTPJwtAuthenticatorsupport only over gRPC, but we expect to expand auth domain support to be in parity with the REST API.A couple features of REST authentication are excluded in this initial version:
Implementation
Authentication
The SecurityRestFilter is the security plugin component responsible for providing authentication on the REST layer. At a high level it provides a RestHandler which intercepts an incoming RestRequest, translates it to an internal SecurityRequestChannel object which stores relevant security metadata of the request, and invokes BackendRegistry.authenticate() to authenticate and extract the user from the request credentials. A successfully authenticated user is stashed in the thread context for later authorization.
This implementation mimics the above flow with gRPC. Implementing SecurityGrpcFilter, GrpcRequestChannel which utilize the same BackendRegistry.authenticate() to authenticate requests (with some authentication steps rejected over gRPC). Successfully authenticated users are similarly stashed in the thread context.
Authorization
OpenSearch evaluates authorization on the node-to-node transport layer, evaluating the user stashed in the thread context and their associated roles against the permissions associated with the transport action. As gRPC makes no changes to the transport layer behavior authorization remains unchanged for this transport.
Issues Resolved
#5812
Testing
Integration test suite and manual local cluster testing.
Script to build OpenSearch from Security plugin feature branch:
Case 1 - REST and gRPC with basic auth admin
With no JWT configured at all gRPC transport will fail to authenticate
Case 2 - REST and gRPC with security disabled
Minimal security plugin disabled settings with gRPC enabled
REST and gRPC should be available over plaintext with no auth required
Case 3 - REST and gRPC with TLS in WITHOUT SSL only mode
Default configuration as well as TLS configured for gRPC
with gRPC TLS settings
Expect failed authentication
Case 4 - REST and gRPC with TLS in WITH SSL only mode
Configure only TLS for REST and gRPC
TLS requests should not need auth due to ssl only mode