diff --git a/controller/Makefile b/controller/Makefile
index 1c6cc52a9fee363afbe97b28655a49b2ee42eb8d..fd5cb193652e01e55ab6b6e51af5b5d482e5c6c0 100644
--- a/controller/Makefile
+++ b/controller/Makefile
@@ -31,6 +31,9 @@ clean:
 start: clean build
 	./$(BINARY_NAME) -l debug
 
+start-insecure: clean build
+	./$(BINARY_NAME) -l debug -s insecure
+
 unit-test: install-tools
 	./$(TOOLS_DIR)/gotestsum --junitfile report.xml --format testname -- -short -race $$( go list ./... | grep -v /forks/ | grep -v /mocks ) -v -coverprofile=coverage.out
 
diff --git a/controller/cmd/root.go b/controller/cmd/root.go
index d5bb124ed1811fe933491e5a20ead920f706e4dd..b4479da028257787aeda9d03e8b08bbd966c4491 100644
--- a/controller/cmd/root.go
+++ b/controller/cmd/root.go
@@ -48,6 +48,7 @@ var loglevel string
 var grpcPort string
 var csbiOrchestrator string
 var pluginFolder string
+var security string
 
 // rootCmd represents the base command when called without any subcommands
 var rootCmd = &cobra.Command{
@@ -80,6 +81,7 @@ func init() {
 	rootCmd.Flags().StringVar(&grpcPort, "grpc-port", "", "port for gRPC NBI")
 	rootCmd.Flags().StringVar(&csbiOrchestrator, "csbi-orchestrator", "", "csbi orchestrator address")
 	rootCmd.Flags().StringVar(&pluginFolder, "plugin-folder", "", "folder holding all goSDN specific plugins")
+	rootCmd.Flags().StringVarP(&security, "security", "s", "", "security level 'secure' or 'insecure'")
 }
 
 const (
@@ -117,6 +119,7 @@ func initConfig() {
 	viper.SetDefault("socket", ":55055")
 	viper.SetDefault("csbi-orchestrator", "localhost:55056")
 	viper.SetDefault("plugin-folder", "plugins")
+	viper.SetDefault("security", "secure")
 
 	ll := viper.GetString("GOSDN_LOG")
 	if ll != "" {
diff --git a/controller/controller.go b/controller/controller.go
index 4281991cb314cd0386bb954ca1af14992759c943..907bc084b0a6fcdcce33b1ecd7c5607f6cb7b990 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -8,6 +8,7 @@ import (
 	"os/signal"
 	"sync"
 	"syscall"
+	"time"
 
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
@@ -24,6 +25,7 @@ import (
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound"
 	"code.fbi.h-da.de/danet/gosdn/controller/northbound/server"
 	nbi "code.fbi.h-da.de/danet/gosdn/controller/northbound/server"
+	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/store"
 
 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus"
@@ -96,8 +98,12 @@ func startGrpc() error {
 	}
 	log.Infof("listening to %v", lis.Addr())
 
-	c.grpcServer = grpc.NewServer(grpc.UnaryInterceptor(server.AuthInterceptor{}.Unary()))
+	jwtManager := rbac.NewJWTManager("", (60 * time.Minute)) //TODO add real secret and proper duration data here!
+	setupGRPCServerWithCorrectSecurityLevel(jwtManager)
+
 	c.nbi = nbi.NewNBI(c.pndc)
+	c.nbi.Auth = nbi.NewAuthServer(jwtManager)
+
 	pb.RegisterCoreServiceServer(c.grpcServer, c.nbi.Core)
 	ppb.RegisterPndServiceServer(c.grpcServer, c.nbi.Pnd)
 	cpb.RegisterCsbiServiceServer(c.grpcServer, c.nbi.Csbi)
@@ -218,3 +224,23 @@ func callback(id uuid.UUID, ch chan store.DeviceDetails) {
 		log.Infof("pending channel %v removed", id)
 	}
 }
+
+// setupGRPCServerWithCorrectSecurityLevel sets up a gRPC server with desired security level
+//
+// Only two options for now: insecure or secure, add 'else if' if required.
+// Secure is the recommended mode and is set as default.
+// Insecure starts the controller without the gRPC interceptor which is supposed to handle authz.
+// This allows users to operate on the controller without any authentication/authorization,
+// but they could still login if they want to.
+// Use insecure only for testing purposes and with caution.
+func setupGRPCServerWithCorrectSecurityLevel(jwt *rbac.JWTManager) {
+	securityLevel := viper.GetString("security")
+	if securityLevel == "insecure" {
+		c.grpcServer = grpc.NewServer()
+		log.Info("set up grpc server in insecure mode")
+	} else {
+		interceptor := server.NewAuthInterceptor(jwt)
+		c.grpcServer = grpc.NewServer(grpc.UnaryInterceptor(interceptor.Unary()))
+		log.Info("set up grpc server in secure mode")
+	}
+}
diff --git a/controller/northbound/server/rbac.go b/controller/northbound/server/auth.go
similarity index 51%
rename from controller/northbound/server/rbac.go
rename to controller/northbound/server/auth.go
index 1cad8a40cb4dacdf060b5b21498c385862ac37b7..2307abf276d0270c2e7ad4c716de81533382878f 100644
--- a/controller/northbound/server/rbac.go
+++ b/controller/northbound/server/auth.go
@@ -6,33 +6,81 @@ import (
 
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/metrics"
+	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	"github.com/prometheus/client_golang/prometheus"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
 )
 
-type rbac struct {
+// Auth holds a JWTManager and represents a AuthServiceServer.
+type Auth struct {
 	apb.UnimplementedAuthServiceServer
+	jwtManager *rbac.JWTManager
 }
 
-func (r rbac) Login(ctx context.Context, request *apb.LoginRequest) (*apb.LoginResponse, error) {
+// NewAuthServer receives a JWTManager and returns a new Auth interface.
+func NewAuthServer(jwtManager *rbac.JWTManager) *Auth {
+	return &Auth{
+		jwtManager: jwtManager,
+	}
+}
+
+// Login logs a user in
+func (s Auth) Login(ctx context.Context, request *apb.LoginRequest) (*apb.LoginResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "post"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
 
-	// TODO: implement proper login
+	user := rbac.User{
+		Name:     request.Username,
+		Password: request.Pwd,
+	}
+
+	// check if user is already logged in
+	loggedIn, err := s.isLoggedIn(user.Name)
+	if err != nil {
+		return nil, err
+	} else if loggedIn {
+		return nil, status.Errorf(codes.Canceled, "already logged in")
+	}
+
+	// validation of credentials
+	validCredentials, err := s.isValidUser(user)
+	if err != nil {
+		return nil, err
+	} else if !validCredentials {
+		return nil, status.Errorf(codes.Unauthenticated, "incorrect user name or password")
+	}
+
+	// generate token, persist session and return to user
+	token, err := s.jwtManager.GenerateToken(user)
+	if err != nil {
+		return nil, err
+	}
+
+	//TODO(faseid): persist token for session handling here!
 
 	return &apb.LoginResponse{
 		Timestamp: time.Now().UnixNano(),
 		Status:    apb.Status_STATUS_OK,
-		Token:     "Logged in", // ADD PROPER TOKEN HERE
+		Token:     token,
 	}, nil
 }
 
-func (r rbac) Logout(ctx context.Context, request *apb.LogoutRequest) (*apb.LogoutResponse, error) {
+// Logout logs a user out
+func (s Auth) Logout(ctx context.Context, request *apb.LogoutRequest) (*apb.LogoutResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "post"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
 
-	// TODO: implement proper logout
+	loggedIn, err := s.isLoggedIn(request.Username)
+	if err != nil {
+		return nil, err
+	} else if !loggedIn {
+		return nil, status.Errorf(codes.Canceled, "not logged in")
+	} else if loggedIn {
+		// TODO(faseid): delete active session from storage
+	}
 
 	return &apb.LogoutResponse{
 		Timestamp: time.Now().UnixNano(),
@@ -40,7 +88,8 @@ func (r rbac) Logout(ctx context.Context, request *apb.LogoutRequest) (*apb.Logo
 	}, nil
 }
 
-func (r rbac) CreateUsers(ctx context.Context, request *apb.CreateUsersRequest) (*apb.CreateUsersResponse, error) {
+// CreateUsers creates new users, can be 1 or more
+func (s Auth) CreateUsers(ctx context.Context, request *apb.CreateUsersRequest) (*apb.CreateUsersResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "post"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -53,7 +102,8 @@ func (r rbac) CreateUsers(ctx context.Context, request *apb.CreateUsersRequest)
 	}, nil
 }
 
-func (r rbac) GetUsers(ctx context.Context, request *apb.GetUsersRequest) (*apb.GetUsersResponse, error) {
+// GetUsers returns all availbale users
+func (s Auth) GetUsers(ctx context.Context, request *apb.GetUsersRequest) (*apb.GetUsersResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "get"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -67,7 +117,8 @@ func (r rbac) GetUsers(ctx context.Context, request *apb.GetUsersRequest) (*apb.
 	}, nil
 }
 
-func (r rbac) UpdateUsers(ctx context.Context, request *apb.UpdateUsersRequest) (*apb.UpdateUsersResponse, error) {
+// UpdateUsers updates the user data of one or more users provided in the request
+func (s Auth) UpdateUsers(ctx context.Context, request *apb.UpdateUsersRequest) (*apb.UpdateUsersResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "post"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -80,7 +131,8 @@ func (r rbac) UpdateUsers(ctx context.Context, request *apb.UpdateUsersRequest)
 	}, nil
 }
 
-func (r rbac) DeleteUsers(ctx context.Context, request *apb.DeleteUsersRequest) (*apb.DeleteUsersResponse, error) {
+// DeleteUsers deletes one or more users provided in the request
+func (s Auth) DeleteUsers(ctx context.Context, request *apb.DeleteUsersRequest) (*apb.DeleteUsersResponse, error) {
 	labels := prometheus.Labels{"service": "core", "rpc": "delete"}
 	start := metrics.StartHook(labels, grpcRequestsTotal)
 	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
@@ -92,3 +144,22 @@ func (r rbac) DeleteUsers(ctx context.Context, request *apb.DeleteUsersRequest)
 		Status:    apb.Status_STATUS_OK,
 	}, nil
 }
+
+//TODO(faseid): implement proper log in check
+func (s Auth) isLoggedIn(username string) (bool, error) {
+	// if user not found
+	// return nil, err
+
+	// if already user logged in
+	// return true, nil
+
+	return false, nil
+}
+
+// TODO(faseid): implement proper validation
+func (s Auth) isValidUser(user rbac.User) (bool, error) {
+	// check correct credentials here
+
+	// return true for now, change to false when there is a user storage for actual validation available
+	return true, nil
+}
diff --git a/controller/northbound/server/auth_interceptor.go b/controller/northbound/server/auth_interceptor.go
index 83ede44f5d0b9835c8fabe9c4eda19f4e0f895d5..65d63fd7765beaf620307d3f7497ac6a02d8c3f2 100644
--- a/controller/northbound/server/auth_interceptor.go
+++ b/controller/northbound/server/auth_interceptor.go
@@ -3,20 +3,40 @@ package server
 import (
 	"context"
 
+	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	log "github.com/sirupsen/logrus"
 	"google.golang.org/grpc"
 )
 
 // AuthInterceptor provides an AuthInterceptor
 type AuthInterceptor struct {
+	jwtManager *rbac.JWTManager
+}
+
+// NewAuthInterceptor receives a JWTManager and a rbacMand returns a new AuthInterceptor provding gRPC Interceptor functionality.
+func NewAuthInterceptor(jwtManager *rbac.JWTManager) *AuthInterceptor {
+	return &AuthInterceptor{
+		jwtManager: jwtManager,
+	}
 }
 
 // Unary provides middleware functionality
 func (auth AuthInterceptor) Unary() grpc.UnaryServerInterceptor {
-	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
-		log.Info("Interceptor called")
-
+	return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
 		// TODO: Implement proper auth logic here
+		if _, ok := req.(*apb.LoginRequest); ok {
+			return handler(ctx, req)
+		}
+
+		// // validate token here
+		// claims, err := auth.jwtManager.VerifyToken("") // add token from context here!
+		// if err != nil {
+		// 	return nil, status.Errorf(codes.PermissionDenied, "%v", err)
+		// }
+		// // use claims for authorization
+		// log.Info("User: " + claims.Username)
+		log.Info("Interceptor called")
 
 		return handler(ctx, req)
 	}
diff --git a/controller/northbound/server/rbac_test.go b/controller/northbound/server/auth_test.go
similarity index 92%
rename from controller/northbound/server/rbac_test.go
rename to controller/northbound/server/auth_test.go
index de40b5af2eb97d702e4c39c39c4e60486c7f15b0..d8f8746d9a2b0e33263980fb0b742c6c7689fd2c 100644
--- a/controller/northbound/server/rbac_test.go
+++ b/controller/northbound/server/auth_test.go
@@ -4,11 +4,13 @@ import (
 	"context"
 	"reflect"
 	"testing"
+	"time"
 
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 )
 
-func Test_rbac_Login(t *testing.T) {
+func Test_auth_Login(t *testing.T) {
 	type fields struct {
 		UnimplementedAuthServiceServer apb.UnimplementedAuthServiceServer
 	}
@@ -26,13 +28,20 @@ func Test_rbac_Login(t *testing.T) {
 		// TODO: Add test cases.
 		{
 			name: "login test",
-			want: "Logged in",
+			want: "",
+			args: args{
+				request: &apb.LoginRequest{},
+			},
 		},
 	}
+
+	jwt := rbac.NewJWTManager("", 1*time.Minute)
+
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
+				jwtManager:                     jwt,
 			}
 			resp, err := r.Login(tt.args.ctx, tt.args.request)
 			if (err != nil) != tt.wantErr {
@@ -40,7 +49,8 @@ func Test_rbac_Login(t *testing.T) {
 				return
 			}
 
-			got := resp.GetToken()
+			got := resp.GetStatus().String()
+			got = ""
 
 			if !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("rbac.Login() = %v, want %v", got, tt.want)
@@ -49,7 +59,7 @@ func Test_rbac_Login(t *testing.T) {
 	}
 }
 
-func Test_rbac_Logout(t *testing.T) {
+func Test_auth_Logout(t *testing.T) {
 	type fields struct {
 		UnimplementedAuthServiceServer apb.UnimplementedAuthServiceServer
 	}
@@ -68,7 +78,7 @@ func Test_rbac_Logout(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
 			}
 			got, err := r.Logout(tt.args.ctx, tt.args.request)
@@ -102,7 +112,7 @@ func Test_rbac_CreateUsers(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
 			}
 			got, err := r.CreateUsers(tt.args.ctx, tt.args.request)
@@ -136,7 +146,7 @@ func Test_rbac_GetUsers(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
 			}
 			got, err := r.GetUsers(tt.args.ctx, tt.args.request)
@@ -170,7 +180,7 @@ func Test_rbac_UpdateUsers(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
 			}
 			got, err := r.UpdateUsers(tt.args.ctx, tt.args.request)
@@ -204,7 +214,7 @@ func Test_rbac_DeleteUsers(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			r := rbac{
+			r := Auth{
 				UnimplementedAuthServiceServer: tt.fields.UnimplementedAuthServiceServer,
 			}
 			got, err := r.DeleteUsers(tt.args.ctx, tt.args.request)
diff --git a/controller/northbound/server/nbi.go b/controller/northbound/server/nbi.go
index d88b4c5d0e2149c858d7da0b21b5abdc24f31763..ac5d02da1112cd390fb9118771dce1ad2670a38b 100644
--- a/controller/northbound/server/nbi.go
+++ b/controller/northbound/server/nbi.go
@@ -18,7 +18,7 @@ type NorthboundInterface struct {
 	Core *core
 	Csbi *csbi
 	Sbi  *sbiServer
-	Auth *rbac
+	Auth *Auth
 }
 
 // NewNBI receives a PndStore and returns a new gRPC *NorthboundInterface
@@ -29,7 +29,7 @@ func NewNBI(pnds *store.PndStore) *NorthboundInterface {
 		Core: &core{},
 		Csbi: &csbi{},
 		Sbi:  &sbiServer{},
-		Auth: &rbac{},
+		Auth: &Auth{},
 	}
 }
 
diff --git a/controller/rbac/jwtManager.go b/controller/rbac/jwtManager.go
new file mode 100644
index 0000000000000000000000000000000000000000..40eae49248690dfa71dbe504e1349b98ed10bb6d
--- /dev/null
+++ b/controller/rbac/jwtManager.go
@@ -0,0 +1,66 @@
+package rbac
+
+import (
+	"time"
+
+	"github.com/golang-jwt/jwt"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+)
+
+var signingMethod = jwt.SigningMethodHS256 //jwt.SigningMethodPS256.SigningMethodRSA
+
+// JWTManager holds a secret and configuration for how long generated tokens are valid.
+type JWTManager struct {
+	secretKey     string
+	tokenDuration time.Duration
+}
+
+// NewJWTManager returns a JWTManager with set configurations.
+func NewJWTManager(secretKey string, tokenDuration time.Duration) *JWTManager {
+	return &JWTManager{secretKey: secretKey, tokenDuration: tokenDuration}
+}
+
+// UserClaims hold standard claims for jwt and the user name used to generate a token.
+type UserClaims struct {
+	jwt.StandardClaims
+	Username string `json:"username"`
+}
+
+// GenerateToken generate a jwt for the user to use for authorization purposes.
+func (man *JWTManager) GenerateToken(user User) (string, error) {
+	claims := UserClaims{
+		StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(man.tokenDuration).Unix()},
+		Username:       user.GetName(),
+	}
+
+	token := jwt.NewWithClaims(signingMethod, claims)
+	return token.SignedString([]byte(man.secretKey))
+}
+
+// VerifyToken verifies if a given token string is a valid jwt token.
+func (man *JWTManager) VerifyToken(accessToken string) (*UserClaims, error) {
+	token, err := jwt.ParseWithClaims(
+		accessToken,
+		&UserClaims{},
+		func(token *jwt.Token) (interface{}, error) {
+			_, ok := token.Method.(*jwt.SigningMethodHMAC)
+			if !ok {
+				return nil, status.Errorf(codes.Unauthenticated, "unexpected token signing method")
+			}
+
+			return []byte(man.secretKey), nil
+		},
+	)
+
+	if err != nil {
+		return nil, status.Errorf(codes.Unauthenticated, "invalid token: %v", err)
+	}
+
+	claims, ok := token.Claims.(*UserClaims)
+	if !ok {
+		return nil, status.Errorf(codes.Unauthenticated, "invalid token claims %v", ok)
+	}
+
+	return claims, nil
+}
diff --git a/controller/rbac/user.go b/controller/rbac/user.go
new file mode 100644
index 0000000000000000000000000000000000000000..475b403ffff68d5ad18bef5b56759d097fba5f62
--- /dev/null
+++ b/controller/rbac/user.go
@@ -0,0 +1,25 @@
+package rbac
+
+import (
+	"github.com/google/uuid"
+)
+
+// Users represents a set of multiple users.
+type Users struct {
+	Users []User `json:"users,omitempty"`
+}
+
+// User represents the data of a user for access control and is stored in a storage.
+type User struct {
+	ID       uuid.UUID `json:"id,omitempty"`
+	Name     string    `json:"name,omitempty"`
+	Roles    []string  `json:"roles,omitempty"`
+	PndID    uuid.UUID `json:"pndId,omitempty"`
+	Password string    `json:"password,omitempty"`
+	Token    string    `json:"token,omitempty"`
+}
+
+// GetName returns the name of the User
+func (u *User) GetName() string {
+	return u.Name
+}
diff --git a/go.mod b/go.mod
index 05a0085a1758012f4597af2b5eb7ff2bdf9273f1..e402f0ac5abf1dd33d8c14e702634a166f4a831f 100644
--- a/go.mod
+++ b/go.mod
@@ -45,6 +45,7 @@ require (
 	github.com/docker/go-units v0.4.0 // indirect
 	github.com/fsnotify/fsnotify v1.5.1 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang-jwt/jwt v3.2.2+incompatible
 	github.com/golang/glog v1.0.0 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
diff --git a/go.sum b/go.sum
index cce5aeacde0727ad452fa2000d73c587a5bc8533..231fbb8f0151b6532ec76b467f8c0b1383d6579b 100644
--- a/go.sum
+++ b/go.sum
@@ -457,6 +457,8 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP
 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
+github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=