Skip to content

Commit ac9f4c8

Browse files
authored
Merge pull request #20 from grepplabs/oauthbearer
OAuth Authentication via SASL/OAUTHBEARER
2 parents f3f0b40 + d93a8b4 commit ac9f4c8

File tree

32 files changed

+1098
-295
lines changed

32 files changed

+1098
-295
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sudo: false
33
language: go
44

55
go:
6-
- "1.10.x"
6+
- "1.11.x"
77

88
env:
99
global:

Dockerfile.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.10 as builder
1+
FROM golang:1.11 as builder
22

33
ARG GOOS=linux
44
ARG GOARCH=amd64

Makefile

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ VERSION ?= $(shell git describe --tags --always --dirty)
88
GOPKGS = $(shell go list ./... | grep -v /vendor/)
99
BUILD_FLAGS ?=
1010
LDFLAGS ?= -X github.com/grepplabs/kafka-proxy/config.Version=$(VERSION) -w -s
11-
TAG ?= "v0.0.8"
11+
TAG ?= "v0.1.0"
1212
GOARCH ?= amd64
1313
GOOS ?= linux
1414

@@ -46,11 +46,11 @@ release: clean
4646
protoc.local-auth:
4747
protoc -I plugin/local-auth/proto/ plugin/local-auth/proto/auth.proto --go_out=plugins=grpc:plugin/local-auth/proto/
4848

49-
protoc.gateway-client:
50-
protoc -I plugin/gateway-client/proto/ plugin/gateway-client/proto/token-provider.proto --go_out=plugins=grpc:plugin/gateway-client/proto/
49+
protoc.token-provider:
50+
protoc -I plugin/token-provider/proto/ plugin/token-provider/proto/token-provider.proto --go_out=plugins=grpc:plugin/token-provider/proto/
5151

52-
protoc.gateway-server:
53-
protoc -I plugin/gateway-server/proto/ plugin/gateway-server/proto/token-info.proto --go_out=plugins=grpc:plugin/gateway-server/proto/
52+
protoc.token-info:
53+
protoc -I plugin/token-info/proto/ plugin/token-info/proto/token-info.proto --go_out=plugins=grpc:plugin/token-info/proto/
5454

5555
plugin.auth-user:
5656
CGO_ENABLED=0 go build -o build/auth-user $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" cmd/plugin-auth-user/main.go
@@ -64,7 +64,14 @@ plugin.google-id-provider:
6464
plugin.google-id-info:
6565
CGO_ENABLED=0 go build -o build/google-id-info $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" cmd/plugin-googleid-info/main.go
6666

67-
all: build plugin.auth-user plugin.auth-ldap plugin.google-id-provider plugin.google-id-info
67+
plugin.unsecured-jwt-info:
68+
CGO_ENABLED=0 go build -o build/unsecured-jwt-info $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" cmd/plugin-unsecured-jwt-info/main.go
69+
70+
plugin.unsecured-jwt-provider:
71+
CGO_ENABLED=0 go build -o build/unsecured-jwt-provider $(BUILD_FLAGS) -ldflags "$(LDFLAGS)" cmd/plugin-unsecured-jwt-provider/main.go
72+
73+
74+
all: build plugin.auth-user plugin.auth-ldap plugin.google-id-provider plugin.google-id-info plugin.unsecured-jwt-info plugin.unsecured-jwt-provider
6875

6976
clean:
7077
@rm -rf build

README.md

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ See:
3434

3535
Linux
3636

37-
curl -Ls https://github.com/grepplabs/kafka-proxy/releases/download/v0.0.8/kafka-proxy_0.0.8_linux_amd64.tar.gz | tar xz
37+
curl -Ls https://github.com/grepplabs/kafka-proxy/releases/download/v0.1.0/kafka-proxy_0.1.0_linux_amd64.tar.gz | tar xz
3838

3939
macOS
4040

41-
curl -Ls https://github.com/grepplabs/kafka-proxy/releases/download/v0.0.8/kafka-proxy_0.0.8_darwin_amd64.tar.gz | tar xz
41+
curl -Ls https://github.com/grepplabs/kafka-proxy/releases/download/v0.1.0/kafka-proxy_0.1.0_darwin_amd64.tar.gz | tar xz
4242

4343
2. Move the binary in to your PATH.
4444

@@ -75,6 +75,7 @@ See:
7575
--auth-local-command string Path to authentication plugin binary
7676
--auth-local-enable Enable local SASL/PLAIN authentication performed by listener - SASL handshake will not be passed to kafka brokers
7777
--auth-local-log-level string Log level of the auth plugin (default "trace")
78+
--auth-local-mechanism string SASL mechanism used for local authentication: PLAIN or OAUTHBEARER (default "PLAIN")
7879
--auth-local-param stringArray Authentication plugin parameter
7980
--auth-local-timeout duration Authentication timeout (default 10s)
8081
--bootstrap-server-mapping stringArray Mapping of Kafka bootstrap server address to local address (host:port,host:port(,advhost:advport))
@@ -84,7 +85,7 @@ See:
8485
--dynamic-listeners-disable Disable dynamic listeners.
8586
--external-server-mapping stringArray Mapping of Kafka server address to external address (host:port,host:port). A listener for the external address is not started
8687
--forbidden-api-keys intSlice Forbidden Kafka request types. The restriction should prevent some Kafka operations e.g. 20 - DeleteTopics
87-
--forward-proxy string URL of the forward proxy. Supported schemas are http and socks5
88+
--forward-proxy string URL of the forward proxy. Supported schemas are socks5 and http
8889
-h, --help help for server
8990
--http-disable Disable HTTP endpoints
9091
--http-health-path string Path on which to health endpoint (default "/health")
@@ -112,9 +113,15 @@ See:
112113
--proxy-listener-write-buffer-size int Sets the size of the operating system's transmit buffer associated with the connection. If zero, system default is used
113114
--proxy-request-buffer-size int Request buffer size pro tcp connection (default 4096)
114115
--proxy-response-buffer-size int Response buffer size pro tcp connection (default 4096)
115-
--sasl-enable Connect using SASL/PLAIN
116+
--sasl-enable Connect using SASL
116117
--sasl-jaas-config-file string Location of JAAS config file with SASL username and password
117118
--sasl-password string SASL user password
119+
--sasl-plugin-command string Path to authentication plugin binary
120+
--sasl-plugin-enable Use plugin for SASL authentication
121+
--sasl-plugin-log-level string Log level of the auth plugin (default "trace")
122+
--sasl-plugin-mechanism string SASL mechanism used for proxy authentication: PLAIN or OAUTHBEARER (default "OAUTHBEARER")
123+
--sasl-plugin-param stringArray Authentication plugin parameter
124+
--sasl-plugin-timeout duration Authentication timeout (default 10s)
118125
--sasl-username string SASL user name
119126
--tls-ca-chain-cert-file string PEM encoded CA's certificate file
120127
--tls-client-cert-file string PEM encoded file with client certificate
@@ -123,8 +130,6 @@ See:
123130
--tls-enable Whether or not to use TLS when connecting to the broker
124131
--tls-insecure-skip-verify It controls whether a client verifies the server's certificate chain and host name
125132
126-
127-
128133
### Usage example
129134
130135
kafka-proxy server --bootstrap-server-mapping "192.168.99.100:32400,0.0.0.0:32399"
@@ -144,14 +149,29 @@ See:
144149
--external-server-mapping "192.168.99.100:32402,127.0.0.1:32403" \
145150
--forbidden-api-keys 20
146151
152+
153+
export BOOTSTRAP_SERVER_MAPPING="192.168.99.100:32401,0.0.0.0:32402 192.168.99.100:32402,0.0.0.0:32403" && kafka-proxy server
154+
155+
### SASL authentication initiated by proxy example
156+
157+
SASL authentication is initiated by the proxy. SASL authentication is disabled on the clients and enabled on the Kafka brokers.
158+
147159
kafka-proxy server --bootstrap-server-mapping "kafka-0.grepplabs.com:9093,0.0.0.0:32399" \
148160
--tls-enable --tls-insecure-skip-verify \
149161
--sasl-enable --sasl-username myuser --sasl-password mysecret
150162
151-
export BOOTSTRAP_SERVER_MAPPING="192.168.99.100:32401,0.0.0.0:32402 192.168.99.100:32402,0.0.0.0:32403" && kafka-proxy server
163+
make clean build plugin.unsecured-jwt-provider && build/kafka-proxy server \
164+
--sasl-enable \
165+
--sasl-plugin-enable \
166+
--sasl-plugin-mechanism "OAUTHBEARER" \
167+
--sasl-plugin-command build/unsecured-jwt-provider \
168+
--sasl-plugin-param "--claim-sub=alice" \
169+
--bootstrap-server-mapping "192.168.99.100:32400,127.0.0.1:32400"
152170
153171
### Proxy authentication example
154172
173+
SASL authentication is performed by the proxy. SASL authentication is enabled on the clients and disabled on the Kafka brokers.
174+
155175
make clean build plugin.auth-user && build/kafka-proxy server --proxy-listener-key-file "server-key.pem" \
156176
--proxy-listener-cert-file "server-cert.pem" \
157177
--proxy-listener-ca-chain-cert-file "ca.pem" \
@@ -169,6 +189,14 @@ See:
169189
--auth-local-param "--user-attr=uid" \
170190
--bootstrap-server-mapping "192.168.99.100:32400,127.0.0.1:32400"
171191
192+
make clean build plugin.unsecured-jwt-info && build/kafka-proxy server \
193+
--auth-local-enable \
194+
--auth-local-command build/unsecured-jwt-info \
195+
--auth-local-mechanism "OAUTHBEARER" \
196+
--auth-local-param "--claim-sub=alice" \
197+
--auth-local-param "--claim-sub=bob" \
198+
--bootstrap-server-mapping "192.168.99.100:32400,127.0.0.1:32400"
199+
172200
### Kafka Gateway example
173201
174202
Authentication between Kafka Proxy Client and Kafka Proxy Server with Google-ID (service account JWT)

cmd/kafka-proxy/server.go

Lines changed: 114 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ import (
2121

2222
"errors"
2323
"github.com/grepplabs/kafka-proxy/pkg/apis"
24-
gatewayclient "github.com/grepplabs/kafka-proxy/plugin/gateway-client/shared"
25-
gatewayserver "github.com/grepplabs/kafka-proxy/plugin/gateway-server/shared"
2624
localauth "github.com/grepplabs/kafka-proxy/plugin/local-auth/shared"
25+
tokeninfo "github.com/grepplabs/kafka-proxy/plugin/token-info/shared"
26+
tokenprovider "github.com/grepplabs/kafka-proxy/plugin/token-provider/shared"
2727
"github.com/hashicorp/go-hclog"
2828
"github.com/hashicorp/go-plugin"
2929
"strings"
@@ -101,6 +101,7 @@ func initFlags() {
101101
// local authentication plugin
102102
Server.Flags().BoolVar(&c.Auth.Local.Enable, "auth-local-enable", false, "Enable local SASL/PLAIN authentication performed by listener - SASL handshake will not be passed to kafka brokers")
103103
Server.Flags().StringVar(&c.Auth.Local.Command, "auth-local-command", "", "Path to authentication plugin binary")
104+
Server.Flags().StringVar(&c.Auth.Local.Mechanism, "auth-local-mechanism", "PLAIN", "SASL mechanism used for local authentication: PLAIN or OAUTHBEARER")
104105
Server.Flags().StringArrayVar(&c.Auth.Local.Parameters, "auth-local-param", []string{}, "Authentication plugin parameter")
105106
Server.Flags().StringVar(&c.Auth.Local.LogLevel, "auth-local-log-level", "trace", "Log level of the auth plugin")
106107
Server.Flags().DurationVar(&c.Auth.Local.Timeout, "auth-local-timeout", 10*time.Second, "Authentication timeout")
@@ -142,12 +143,20 @@ func initFlags() {
142143
Server.Flags().StringVar(&c.Kafka.TLS.ClientKeyPassword, "tls-client-key-password", "", "Password to decrypt rsa private key")
143144
Server.Flags().StringVar(&c.Kafka.TLS.CAChainCertFile, "tls-ca-chain-cert-file", "", "PEM encoded CA's certificate file")
144145

145-
// SASL
146-
Server.Flags().BoolVar(&c.Kafka.SASL.Enable, "sasl-enable", false, "Connect using SASL/PLAIN")
146+
// SASL by Proxy
147+
Server.Flags().BoolVar(&c.Kafka.SASL.Enable, "sasl-enable", false, "Connect using SASL")
147148
Server.Flags().StringVar(&c.Kafka.SASL.Username, "sasl-username", "", "SASL user name")
148149
Server.Flags().StringVar(&c.Kafka.SASL.Password, "sasl-password", "", "SASL user password")
149150
Server.Flags().StringVar(&c.Kafka.SASL.JaasConfigFile, "sasl-jaas-config-file", "", "Location of JAAS config file with SASL username and password")
150151

152+
// SASL by Proxy plugin
153+
Server.Flags().BoolVar(&c.Kafka.SASL.Plugin.Enable, "sasl-plugin-enable", false, "Use plugin for SASL authentication")
154+
Server.Flags().StringVar(&c.Kafka.SASL.Plugin.Command, "sasl-plugin-command", "", "Path to authentication plugin binary")
155+
Server.Flags().StringVar(&c.Kafka.SASL.Plugin.Mechanism, "sasl-plugin-mechanism", "OAUTHBEARER", "SASL mechanism used for proxy authentication: PLAIN or OAUTHBEARER")
156+
Server.Flags().StringArrayVar(&c.Kafka.SASL.Plugin.Parameters, "sasl-plugin-param", []string{}, "Authentication plugin parameter")
157+
Server.Flags().StringVar(&c.Kafka.SASL.Plugin.LogLevel, "sasl-plugin-log-level", "trace", "Log level of the auth plugin")
158+
Server.Flags().DurationVar(&c.Kafka.SASL.Plugin.Timeout, "sasl-plugin-timeout", 10*time.Second, "Authentication timeout")
159+
151160
// Web
152161
Server.Flags().BoolVar(&c.Http.Disable, "http-disable", false, "Disable HTTP endpoints")
153162
Server.Flags().StringVar(&c.Http.ListenAddress, "http-listen-address", "0.0.0.0:9080", "Address that kafka-proxy is listening on")
@@ -172,47 +181,115 @@ func initFlags() {
172181
func Run(_ *cobra.Command, _ []string) {
173182
logrus.Infof("Starting kafka-proxy version %s", config.Version)
174183

175-
var passwordAuthenticator apis.PasswordAuthenticator
184+
var localPasswordAuthenticator apis.PasswordAuthenticator
185+
var localTokenAuthenticator apis.TokenInfo
176186
if c.Auth.Local.Enable {
177-
var err error
178-
factory, ok := registry.GetComponent(new(apis.PasswordAuthenticatorFactory), c.Auth.Local.Command).(apis.PasswordAuthenticatorFactory)
179-
if ok {
180-
logrus.Infof("Using built-in PasswordAuthenticator")
181-
passwordAuthenticator, err = factory.New(c.Auth.Local.Parameters)
182-
if err != nil {
183-
logrus.Fatal(err)
184-
}
185-
} else {
186-
client := NewPluginClient(localauth.Handshake, localauth.PluginMap, c.Auth.Local.LogLevel, c.Auth.Local.Command, c.Auth.Local.Parameters)
187-
defer client.Kill()
188-
189-
rpcClient, err := client.Client()
190-
if err != nil {
191-
logrus.Fatal(err)
187+
switch c.Auth.Local.Mechanism {
188+
case "PLAIN":
189+
var err error
190+
factory, ok := registry.GetComponent(new(apis.PasswordAuthenticatorFactory), c.Auth.Local.Command).(apis.PasswordAuthenticatorFactory)
191+
if ok {
192+
logrus.Infof("Using built-in '%s' PasswordAuthenticator for local PasswordAuthenticator", c.Auth.Local.Command)
193+
localPasswordAuthenticator, err = factory.New(c.Auth.Local.Parameters)
194+
if err != nil {
195+
logrus.Fatal(err)
196+
}
197+
} else {
198+
client := NewPluginClient(localauth.Handshake, localauth.PluginMap, c.Auth.Local.LogLevel, c.Auth.Local.Command, c.Auth.Local.Parameters)
199+
defer client.Kill()
200+
201+
rpcClient, err := client.Client()
202+
if err != nil {
203+
logrus.Fatal(err)
204+
}
205+
raw, err := rpcClient.Dispense("passwordAuthenticator")
206+
if err != nil {
207+
logrus.Fatal(err)
208+
}
209+
localPasswordAuthenticator, ok = raw.(apis.PasswordAuthenticator)
210+
if !ok {
211+
logrus.Fatal(errors.New("unsupported PasswordAuthenticator plugin type"))
212+
}
192213
}
193-
raw, err := rpcClient.Dispense("passwordAuthenticator")
194-
if err != nil {
195-
logrus.Fatal(err)
214+
case "OAUTHBEARER":
215+
var err error
216+
factory, ok := registry.GetComponent(new(apis.TokenInfoFactory), c.Auth.Local.Command).(apis.TokenInfoFactory)
217+
if ok {
218+
logrus.Infof("Using built-in '%s' TokenInfo for local TokenAuthenticator", c.Auth.Local.Command)
219+
220+
localTokenAuthenticator, err = factory.New(c.Auth.Local.Parameters)
221+
if err != nil {
222+
logrus.Fatal(err)
223+
}
224+
} else {
225+
client := NewPluginClient(tokeninfo.Handshake, tokeninfo.PluginMap, c.Auth.Local.LogLevel, c.Auth.Local.Command, c.Auth.Local.Parameters)
226+
defer client.Kill()
227+
228+
rpcClient, err := client.Client()
229+
if err != nil {
230+
logrus.Fatal(err)
231+
}
232+
raw, err := rpcClient.Dispense("tokenInfo")
233+
if err != nil {
234+
logrus.Fatal(err)
235+
}
236+
localTokenAuthenticator, ok = raw.(apis.TokenInfo)
237+
if !ok {
238+
logrus.Fatal(errors.New("unsupported TokenInfo plugin type"))
239+
}
196240
}
197-
passwordAuthenticator, ok = raw.(apis.PasswordAuthenticator)
198-
if !ok {
199-
logrus.Fatal(errors.New("unsupported PasswordAuthenticator plugin type"))
241+
default:
242+
logrus.Fatal(errors.New("unsupported local auth mechanism"))
243+
}
244+
}
245+
246+
var saslTokenProvider apis.TokenProvider
247+
if c.Kafka.SASL.Plugin.Enable {
248+
switch c.Kafka.SASL.Plugin.Mechanism {
249+
case "OAUTHBEARER":
250+
var err error
251+
factory, ok := registry.GetComponent(new(apis.TokenProviderFactory), c.Kafka.SASL.Plugin.Command).(apis.TokenProviderFactory)
252+
if ok {
253+
logrus.Infof("Using built-in '%s' TokenProvider for sasl authentication", c.Kafka.SASL.Plugin.Command)
254+
255+
saslTokenProvider, err = factory.New(c.Kafka.SASL.Plugin.Parameters)
256+
if err != nil {
257+
logrus.Fatal(err)
258+
}
259+
} else {
260+
client := NewPluginClient(tokenprovider.Handshake, tokenprovider.PluginMap, c.Kafka.SASL.Plugin.LogLevel, c.Kafka.SASL.Plugin.Command, c.Kafka.SASL.Plugin.Parameters)
261+
defer client.Kill()
262+
263+
rpcClient, err := client.Client()
264+
if err != nil {
265+
logrus.Fatal(err)
266+
}
267+
raw, err := rpcClient.Dispense("tokenProvider")
268+
if err != nil {
269+
logrus.Fatal(err)
270+
}
271+
saslTokenProvider, ok = raw.(apis.TokenProvider)
272+
if !ok {
273+
logrus.Fatal(errors.New("unsupported TokenProvider plugin type"))
274+
}
200275
}
276+
default:
277+
logrus.Fatal(errors.New("unsupported sasl auth mechanism"))
201278
}
202279
}
203280

204-
var tokenProvider apis.TokenProvider
281+
var gatewayTokenProvider apis.TokenProvider
205282
if c.Auth.Gateway.Client.Enable {
206283
var err error
207284
factory, ok := registry.GetComponent(new(apis.TokenProviderFactory), c.Auth.Gateway.Client.Command).(apis.TokenProviderFactory)
208285
if ok {
209-
logrus.Infof("Using built-in TokenProvider")
210-
tokenProvider, err = factory.New(c.Auth.Gateway.Client.Parameters)
286+
logrus.Infof("Using built-in '%s' TokenProvider for Gateway Client", c.Auth.Gateway.Client.Command)
287+
gatewayTokenProvider, err = factory.New(c.Auth.Gateway.Client.Parameters)
211288
if err != nil {
212289
logrus.Fatal(err)
213290
}
214291
} else {
215-
client := NewPluginClient(gatewayclient.Handshake, gatewayclient.PluginMap, c.Auth.Gateway.Client.LogLevel, c.Auth.Gateway.Client.Command, c.Auth.Gateway.Client.Parameters)
292+
client := NewPluginClient(tokenprovider.Handshake, tokenprovider.PluginMap, c.Auth.Gateway.Client.LogLevel, c.Auth.Gateway.Client.Command, c.Auth.Gateway.Client.Parameters)
216293
defer client.Kill()
217294

218295
rpcClient, err := client.Client()
@@ -223,26 +300,26 @@ func Run(_ *cobra.Command, _ []string) {
223300
if err != nil {
224301
logrus.Fatal(err)
225302
}
226-
tokenProvider, ok = raw.(apis.TokenProvider)
303+
gatewayTokenProvider, ok = raw.(apis.TokenProvider)
227304
if !ok {
228305
logrus.Fatal(errors.New("unsupported TokenProvider plugin type"))
229306
}
230307
}
231308
}
232309

233-
var tokenInfo apis.TokenInfo
310+
var gatewayTokenInfo apis.TokenInfo
234311
if c.Auth.Gateway.Server.Enable {
235312
var err error
236313
factory, ok := registry.GetComponent(new(apis.TokenInfoFactory), c.Auth.Gateway.Server.Command).(apis.TokenInfoFactory)
237314
if ok {
238-
logrus.Infof("Using built-in TokenInfo")
315+
logrus.Infof("Using built-in '%s' TokenInfo for Gateway Server", c.Auth.Gateway.Server.Command)
239316

240-
tokenInfo, err = factory.New(c.Auth.Gateway.Server.Parameters)
317+
gatewayTokenInfo, err = factory.New(c.Auth.Gateway.Server.Parameters)
241318
if err != nil {
242319
logrus.Fatal(err)
243320
}
244321
} else {
245-
client := NewPluginClient(gatewayserver.Handshake, gatewayserver.PluginMap, c.Auth.Gateway.Server.LogLevel, c.Auth.Gateway.Server.Command, c.Auth.Gateway.Server.Parameters)
322+
client := NewPluginClient(tokeninfo.Handshake, tokeninfo.PluginMap, c.Auth.Gateway.Server.LogLevel, c.Auth.Gateway.Server.Command, c.Auth.Gateway.Server.Parameters)
246323
defer client.Kill()
247324

248325
rpcClient, err := client.Client()
@@ -253,7 +330,7 @@ func Run(_ *cobra.Command, _ []string) {
253330
if err != nil {
254331
logrus.Fatal(err)
255332
}
256-
tokenInfo, ok = raw.(apis.TokenInfo)
333+
gatewayTokenInfo, ok = raw.(apis.TokenInfo)
257334
if !ok {
258335
logrus.Fatal(errors.New("unsupported TokenInfo plugin type"))
259336
}
@@ -273,7 +350,7 @@ func Run(_ *cobra.Command, _ []string) {
273350
if err != nil {
274351
logrus.Fatal(err)
275352
}
276-
proxyClient, err := proxy.NewClient(connset, c, listeners.GetNetAddressMapping, passwordAuthenticator, tokenProvider, tokenInfo)
353+
proxyClient, err := proxy.NewClient(connset, c, listeners.GetNetAddressMapping, localPasswordAuthenticator, localTokenAuthenticator, saslTokenProvider, gatewayTokenProvider, gatewayTokenInfo)
277354
if err != nil {
278355
logrus.Fatal(err)
279356
}

0 commit comments

Comments
 (0)