diff --git a/CHANGELOG.md b/CHANGELOG.md index 31a835d..83ce165 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file. ## Added - Adding more audit points for better visibility from [vivekhiwarkar](https://github.com/vivekhiwarkar) +- Added audit point for kubeconfig download [meain](https://github.com/meain) ## [0.1.2] - 2022-08-12 diff --git a/main.go b/main.go index cbb685b..d488c3d 100644 --- a/main.go +++ b/main.go @@ -40,6 +40,7 @@ import ( "github.com/uptrace/bun/dialect/pgdialect" "github.com/uptrace/bun/driver/pgdriver" "github.com/uptrace/bun/extra/bundebug" + "go.uber.org/zap" _grpc "google.golang.org/grpc" "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" @@ -121,6 +122,7 @@ var ( esIndexPrefix string relayAuditsESIndexPrefix string relayCommandsESIndexPrefix string + auditLogger *zap.Logger // cd relay coreCDRelayUserHost string @@ -309,7 +311,7 @@ func setup() { MaxBackups: 10, // Should we let sidecar do rotation? MaxAgeDays: 10, // Make these configurable via env } - auditLogger := audit.GetAuditLogger(&ao) + auditLogger = audit.GetAuditLogger(&ao) // authz services gormDb, err := gorm.Open(postgres.New(postgres.Config{ @@ -557,7 +559,7 @@ func runRPC(wg *sync.WaitGroup, ctx context.Context) { projectServer := server.NewProjectServer(pps) bootstrapServer := server.NewBootstrapServer(bs, kekFunc, cs) - kubeConfigServer := server.NewKubeConfigServer(bs, aps, gps, kss, krs, kekFunc, ks, os, ps) + kubeConfigServer := server.NewKubeConfigServer(bs, aps, gps, kss, krs, kekFunc, ks, os, ps, auditLogger) auditInfoServer := server.NewAuditInfoServer(bs, aps) clusterAuthzServer := server.NewClusterAuthzServer(bs, aps, gps, krs, kcs, kss, ns) kubectlClusterSettingsServer := server.NewKubectlClusterSettingsServer(bs, kcs) diff --git a/pkg/sentry/kubeconfig/kubeconfig.go b/pkg/sentry/kubeconfig/kubeconfig.go index 1cb715a..ed6a541 100644 --- a/pkg/sentry/kubeconfig/kubeconfig.go +++ b/pkg/sentry/kubeconfig/kubeconfig.go @@ -16,6 +16,7 @@ import ( rpcv3 "github.com/paralus/paralus/proto/rpc/user" commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3" sentry "github.com/paralus/paralus/proto/types/sentry" + "go.uber.org/zap" clientcmdapiv1 "k8s.io/client-go/tools/clientcmd/api/v1" "sigs.k8s.io/yaml" @@ -111,7 +112,7 @@ func getProjectsForAccount(ctx context.Context, accountID, orgID, partnerID stri } // GetConfigForUser returns YAML encoding of kubeconfig -func GetConfigForUser(ctx context.Context, bs service.BootstrapService, aps service.AccountPermissionService, gps service.GroupPermissionService, req *sentryrpc.GetForUserRequest, pf cryptoutil.PasswordFunc, kss service.KubeconfigSettingService, ksvc service.ApiKeyService, os service.OrganizationService, ps service.PartnerService) ([]byte, error) { +func GetConfigForUser(ctx context.Context, bs service.BootstrapService, aps service.AccountPermissionService, gps service.GroupPermissionService, req *sentryrpc.GetForUserRequest, pf cryptoutil.PasswordFunc, kss service.KubeconfigSettingService, ksvc service.ApiKeyService, os service.OrganizationService, ps service.PartnerService, al *zap.Logger) ([]byte, error) { opts := req.Opts if opts.Selector != "" { opts.Selector = fmt.Sprintf("%s,!paralus.dev/cdRelayAgent", opts.Selector) @@ -331,16 +332,7 @@ func GetConfigForUser(ctx context.Context, bs service.BootstrapService, aps serv return nil, err } - /* TODO: as part of event handling - partnerID := opts.Partner - orgID := opts.Organization - - message := fmt.Sprintf("%s downloaded kubeconfig for: %s", sessionUserName, username) - - - kubeconfigDownloadEvent(ctx, "user.kubeconfig.download", orgID, partnerID, sessionUserName, sessionAccountID, - message, groups) - */ + service.DownloadKubeconfigAuditEvent(ctx, al, username) return yaml.JSONToYAML(jb) } diff --git a/pkg/service/audit_utils.go b/pkg/service/audit_utils.go index 51556c8..5d21d81 100644 --- a/pkg/service/audit_utils.go +++ b/pkg/service/audit_utils.go @@ -408,6 +408,24 @@ func DownloadCliConfigAuditEvent(ctx context.Context, al *zap.Logger, action str } } +func DownloadKubeconfigAuditEvent(ctx context.Context, al *zap.Logger, user string) { + sd, ok := GetSessionDataFromContext(ctx) + if !ok { + _log.Warn("unable to create audit event: could not fetch info from context") + return + } + + detail := &audit.EventDetail{ + Message: fmt.Sprintf("Kubeconfig downloaded for %s", user), + Meta: map[string]string{ + "user": user, + }, + } + if err := audit.CreateV1Event(al, sd, detail, "user.kubeconfig.download", ""); err != nil { + _log.Warn("unable to create audit event", err) + } +} + func RevokeKubeconfigAuditEvent(ctx context.Context, al *zap.Logger, user string) { sd, ok := GetSessionDataFromContext(ctx) if !ok { diff --git a/server/kubeconfig.go b/server/kubeconfig.go index 3051b71..dca31a0 100644 --- a/server/kubeconfig.go +++ b/server/kubeconfig.go @@ -15,6 +15,7 @@ import ( sentryrpc "github.com/paralus/paralus/proto/rpc/sentry" commonv3 "github.com/paralus/paralus/proto/types/commonpb/v3" sentry "github.com/paralus/paralus/proto/types/sentry" + "go.uber.org/zap" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -28,6 +29,7 @@ type kubeConfigServer struct { ks service.ApiKeyService os service.OrganizationService ps service.PartnerService + al *zap.Logger } var _ sentryrpc.KubeConfigServer = (*kubeConfigServer)(nil) @@ -55,7 +57,7 @@ func (s *kubeConfigServer) GetForClusterWebSession(ctx context.Context, in *sent } func (s *kubeConfigServer) GetForUser(ctx context.Context, in *sentryrpc.GetForUserRequest) (*commonv3.HttpBody, error) { - config, err := kubeconfig.GetConfigForUser(ctx, s.bs, s.aps, s.gps, in, s.pf, s.kss, s.ks, s.os, s.ps) + config, err := kubeconfig.GetConfigForUser(ctx, s.bs, s.aps, s.gps, in, s.pf, s.kss, s.ks, s.os, s.ps, s.al) if err != nil { _log.Errorw("error generating kubeconfig", "error", err.Error()) return nil, err @@ -202,8 +204,8 @@ func (s *kubeConfigServer) UpdateUserSetting(ctx context.Context, req *sentryrpc // NewKubeConfigServer returns new kube config server func NewKubeConfigServer(bs service.BootstrapService, aps service.AccountPermissionService, gps service.GroupPermissionService, kss service.KubeconfigSettingService, - krs service.KubeconfigRevocationService, pf cryptoutil.PasswordFunc, ksvc service.ApiKeyService, os service.OrganizationService, ps service.PartnerService) sentryrpc.KubeConfigServer { - return &kubeConfigServer{bs, aps, gps, kss, krs, pf, ksvc, os, ps} + krs service.KubeconfigRevocationService, pf cryptoutil.PasswordFunc, ksvc service.ApiKeyService, os service.OrganizationService, ps service.PartnerService, al *zap.Logger) sentryrpc.KubeConfigServer { + return &kubeConfigServer{bs, aps, gps, kss, krs, pf, ksvc, os, ps, al} } func checkOrgAdmin(groups []string) bool {