|
|
|
@@ -10,6 +10,7 @@ import (
|
|
|
|
|
"github.com/fullstorydev/grpchan/inprocgrpc"
|
|
|
|
|
grpcAuth "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/auth"
|
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
|
|
|
"go.opentelemetry.io/otel/trace"
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
@@ -21,6 +22,7 @@ import (
|
|
|
|
|
authzv1 "github.com/grafana/authlib/authz/proto/v1"
|
|
|
|
|
"github.com/grafana/authlib/cache"
|
|
|
|
|
authlib "github.com/grafana/authlib/types"
|
|
|
|
|
"github.com/grafana/dskit/grpcclient"
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
|
|
|
@@ -69,7 +71,7 @@ func ProvideAuthZClient(
|
|
|
|
|
|
|
|
|
|
switch authCfg.mode {
|
|
|
|
|
case clientModeCloud:
|
|
|
|
|
rbacClient, err := newRemoteRBACClient(authCfg, tracer)
|
|
|
|
|
rbacClient, err := newRemoteRBACClient(authCfg, tracer, reg)
|
|
|
|
|
if features.IsEnabledGlobally(featuremgmt.FlagZanzana) {
|
|
|
|
|
return zanzana.WithShadowClient(rbacClient, zanzanaClient, reg)
|
|
|
|
|
}
|
|
|
|
@@ -128,7 +130,7 @@ func ProvideAuthZClient(
|
|
|
|
|
// ProvideStandaloneAuthZClient provides a standalone AuthZ client, without registering the AuthZ service.
|
|
|
|
|
// You need to provide a remote address in the configuration
|
|
|
|
|
func ProvideStandaloneAuthZClient(
|
|
|
|
|
cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer trace.Tracer,
|
|
|
|
|
cfg *setting.Cfg, features featuremgmt.FeatureToggles, tracer trace.Tracer, reg prometheus.Registerer,
|
|
|
|
|
) (authlib.AccessClient, error) {
|
|
|
|
|
if !features.IsEnabledGlobally(featuremgmt.FlagAuthZGRPCServer) {
|
|
|
|
|
return nil, nil
|
|
|
|
@@ -139,10 +141,10 @@ func ProvideStandaloneAuthZClient(
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newRemoteRBACClient(authCfg, tracer)
|
|
|
|
|
return newRemoteRBACClient(authCfg, tracer, reg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newRemoteRBACClient(clientCfg *authzClientSettings, tracer trace.Tracer) (authlib.AccessClient, error) {
|
|
|
|
|
func newRemoteRBACClient(clientCfg *authzClientSettings, tracer trace.Tracer, reg prometheus.Registerer) (authlib.AccessClient, error) {
|
|
|
|
|
tokenClient, err := authnlib.NewTokenExchangeClient(authnlib.TokenExchangeConfig{
|
|
|
|
|
Token: clientCfg.token,
|
|
|
|
|
TokenExchangeURL: clientCfg.tokenExchangeURL,
|
|
|
|
@@ -159,13 +161,26 @@ func newRemoteRBACClient(clientCfg *authzClientSettings, tracer trace.Tracer) (a
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn, err := grpc.NewClient(
|
|
|
|
|
clientCfg.remoteAddress,
|
|
|
|
|
authzRequestDuration := promauto.With(reg).NewHistogramVec(prometheus.HistogramOpts{
|
|
|
|
|
Name: "authz_server_client_request_duration_seconds",
|
|
|
|
|
Help: "Time spent executing requests to authz server.",
|
|
|
|
|
NativeHistogramBucketFactor: 1.1,
|
|
|
|
|
NativeHistogramMaxBucketNumber: 160,
|
|
|
|
|
NativeHistogramMinResetDuration: time.Hour,
|
|
|
|
|
}, []string{"operation", "status_code"})
|
|
|
|
|
|
|
|
|
|
unaryInterceptors, streamInterceptors := grpcclient.Instrument(authzRequestDuration)
|
|
|
|
|
|
|
|
|
|
opts := []grpc.DialOption{
|
|
|
|
|
grpc.WithTransportCredentials(transportCreds),
|
|
|
|
|
grpc.WithPerRPCCredentials(
|
|
|
|
|
NewGRPCTokenAuth(AuthzServiceAudience, clientCfg.tokenNamespace, tokenClient),
|
|
|
|
|
),
|
|
|
|
|
)
|
|
|
|
|
grpc.WithChainUnaryInterceptor(unaryInterceptors...),
|
|
|
|
|
grpc.WithChainStreamInterceptor(streamInterceptors...),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
conn, err := grpc.NewClient(clientCfg.remoteAddress, opts...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("failed to create authz client to remote server: %w", err)
|
|
|
|
|
}
|
|
|
|
|