Skip to content

Commit

Permalink
fix: check required private log viewer permission
Browse files Browse the repository at this point in the history
  • Loading branch information
rahmatrhd committed Aug 7, 2023
1 parent b8452cd commit e47155b
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
4 changes: 4 additions & 0 deletions plugins/providers/bigquery/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ var (
ErrEmptyActivityPayload = errors.New("couldn't get payload from log entry")
)

const (
privateLogViewerPermission = "logging.privateLogEntries.list"
)

type auditLog struct {
*audit.AuditLog
}
Expand Down
19 changes: 19 additions & 0 deletions plugins/providers/bigquery/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
bq "cloud.google.com/go/bigquery"
"github.com/goto/guardian/domain"
bqApi "google.golang.org/api/bigquery/v2"
"google.golang.org/api/cloudresourcemanager/v1"
"google.golang.org/api/iam/v1"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
Expand All @@ -19,6 +20,7 @@ type bigQueryClient struct {
client *bq.Client
iamService *iam.Service
apiClient *bqApi.Service
crmService *cloudresourcemanager.Service
}

func NewBigQueryClient(projectID string, opts ...option.ClientOption) (*bigQueryClient, error) {
Expand All @@ -38,11 +40,17 @@ func NewBigQueryClient(projectID string, opts ...option.ClientOption) (*bigQuery
return nil, err
}

crmService, err := cloudresourcemanager.NewService(ctx, opts...)
if err != nil {
return nil, err
}

return &bigQueryClient{
projectID: projectID,
client: client,
iamService: iamService,
apiClient: apiClient,
crmService: crmService,
}, nil
}

Expand Down Expand Up @@ -346,6 +354,17 @@ func (c *bigQueryClient) ListRolePermissions(ctx context.Context, roleIDs []stri
return permissions, nil
}

func (c *bigQueryClient) CheckGrantedPermission(ctx context.Context, permissions []string) ([]string, error) {
res, err := c.crmService.Projects.TestIamPermissions(c.projectID, &cloudresourcemanager.TestIamPermissionsRequest{
Permissions: permissions,
}).Context(ctx).Do()
if err != nil {
return nil, err
}

return res.Permissions, nil
}

func (c *bigQueryClient) getGrantableRolesForTables() ([]string, error) {
var resourceName string
ctx := context.Background()
Expand Down
1 change: 1 addition & 0 deletions plugins/providers/bigquery/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ var (
ErrCannotVerifyTablePermission = errors.New("cannot verify the table permissions since this bigquery project does not have any tables")

ErrActivityLogRetentionPeriodExceeded = errors.New("activity log retention period exceeded")
ErrPrivateLogViewerAccessNotGranted = errors.New("private log viewer access not granted")
)
55 changes: 55 additions & 0 deletions plugins/providers/bigquery/mocks/BigQueryClient.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 16 additions & 1 deletion plugins/providers/bigquery/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/goto/guardian/core/provider"
"github.com/goto/guardian/domain"
"github.com/goto/guardian/pkg/slices"
"github.com/goto/guardian/utils"
"github.com/goto/salt/log"
"github.com/mitchellh/mapstructure"
"github.com/patrickmn/go-cache"
Expand Down Expand Up @@ -52,6 +53,7 @@ type BigQueryClient interface {
ListAccess(ctx context.Context, resources []*domain.Resource) (domain.MapResourceAccess, error)
GetRolePermissions(context.Context, string) ([]string, error)
ListRolePermissions(context.Context, []string) (map[string][]string, error)
CheckGrantedPermission(context.Context, []string) ([]string, error)
}

//go:generate mockery --name=cloudLoggingClientI --exported --with-expecter
Expand Down Expand Up @@ -379,6 +381,14 @@ func (p *Provider) ListActivities(ctx context.Context, pd domain.Provider, filte
if pd.Type != p.typeName {
return nil, ErrProviderTypeMismatch
}
creds, err := ParseCredentials(pd.Config.Credentials, p.encryptor)
if err != nil {
return nil, fmt.Errorf("parsing credentials: %w", err)
}
bqClient, err := p.getBigQueryClient(*creds)
if err != nil {
return nil, fmt.Errorf("initializing bigquery client: %w", err)
}
logClient, err := p.getCloudLoggingClient(ctx, *pd.Config)
if err != nil {
return nil, fmt.Errorf("initializing cloud logging client: %w", err)
Expand Down Expand Up @@ -413,7 +423,12 @@ func (p *Provider) ListActivities(ctx context.Context, pd domain.Provider, filte
filter.TimestampGte = &t
}

// TODO: check private log viewer access is granted
// check private log viewer access is granted
if grantedPermissions, err := bqClient.CheckGrantedPermission(ctx, []string{privateLogViewerPermission}); err != nil {
return nil, fmt.Errorf("checking granted permission: %w", err)
} else if !utils.ContainsString(grantedPermissions, privateLogViewerPermission) {
return nil, fmt.Errorf("%w: %q permissions is required", ErrPrivateLogViewerAccessNotGranted, privateLogViewerPermission)
}

filters := []string{
`protoPayload.serviceName="bigquery.googleapis.com"`,
Expand Down

0 comments on commit e47155b

Please sign in to comment.