Skip to content

Commit

Permalink
Merge pull request #591 from typeid/fix_permission_denied
Browse files Browse the repository at this point in the history
OSD-24351: permission denied command should also evaluate read-only events
  • Loading branch information
openshift-merge-bot[bot] authored Jul 2, 2024
2 parents 548e565 + fe19fb1 commit b30d722
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 27 deletions.
11 changes: 4 additions & 7 deletions cmd/cloudtrail/cloudtrail_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ func TestIgnoreListFilter(t *testing.T) {

func TestPermissonDeniedFilter(t *testing.T) {

var (
permissionDeniedErrorStr = ".*Client.UnauthorizedOperation.*"
)
// Test Case 1 (Ignored)
testUsername1 := "RH-SRE-xxx.openshift"
testCloudTrailEvent1 := `{"eventVersion": "1.08","userIdentity": {"sessionContext": {"sessionIssuer": {"arn": "arn:aws:iam::123456789012:user/test-12345-6-a7b8-kube-system-capa-controller-manager/RH-SRE-xxx.openshift"}}}, "errorCode": "Client.UnauthorizedOperation"}`
Expand All @@ -123,7 +120,7 @@ func TestPermissonDeniedFilter(t *testing.T) {

filtered, err := ctUtil.ApplyFilters(TestEvents,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
assert.Nil(t, err)
Expand All @@ -143,7 +140,7 @@ func TestPermissonDeniedFilter(t *testing.T) {

filtered, err := ctUtil.ApplyFilters(edgeCaseEvents,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
assert.Nil(t, err)
Expand All @@ -162,7 +159,7 @@ func TestPermissonDeniedFilter(t *testing.T) {

filtered, err := ctUtil.ApplyFilters(edgeCaseEvents,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
assert.Nil(t, err)
Expand All @@ -181,7 +178,7 @@ func TestPermissonDeniedFilter(t *testing.T) {
expected := []types.Event{}
filtered, err := ctUtil.ApplyFilters(edgeCaseEvents,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
assert.EqualErrorf(t, err, "[ERROR] failed to extract raw CloudTrail event details: cannot parse a nil input", "")
Expand Down
23 changes: 8 additions & 15 deletions cmd/cloudtrail/permission-denied.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ import (
"github.com/spf13/cobra"
)

var (
permissionDeniedErrorStr = ".*Client.UnauthorizedOperation.*"
)

type permissionDeniedEventsOptions struct {
ClusterID string
StartTime string
Expand All @@ -39,20 +35,17 @@ func newCmdPermissionDenied() *cobra.Command {
},
}
permissionDeniedCmd.Flags().StringVarP(&opts.ClusterID, "cluster-id", "C", "", "Cluster ID")
permissionDeniedCmd.Flags().StringVarP(&opts.StartTime, "since", "", "1h", "Specifies that only events that occur within the specified time are returned.Defaults to 1h. Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
permissionDeniedCmd.Flags().StringVarP(&opts.StartTime, "since", "", "5m", "Specifies that only events that occur within the specified time are returned.Defaults to 5m. Valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
permissionDeniedCmd.Flags().BoolVarP(&opts.PrintUrl, "url", "u", false, "Generates Url link to cloud console cloudtrail event")
permissionDeniedCmd.Flags().BoolVarP(&opts.PrintRaw, "raw-event", "r", false, "Prints the cloudtrail events to the console in raw json format")
permissionDeniedCmd.MarkFlagRequired("cluster-id")
return permissionDeniedCmd
}

func isforbiddenEvent(event types.Event, value string) (bool, error) {

if value == "" {
return false, nil
}
func isforbiddenEvent(event types.Event) (bool, error) {
permissionDeniedErrorRegexp := ".*Client.UnauthorizedOperation.*"

check, err := regexp.Compile(value)
check, err := regexp.Compile(permissionDeniedErrorRegexp)
if err != nil {
return false, fmt.Errorf("failed to compile regex: %w", err)
}
Expand Down Expand Up @@ -106,14 +99,14 @@ func (p *permissionDeniedEventsOptions) run() error {
fmt.Printf("[INFO] Checking Permission Denied History since %v for AWS Account %v as %v \n", startTime, accountId, arn)
cloudTrailclient := cloudtrail.NewFromConfig(cfg)
fmt.Printf("[INFO] Fetching %v Event History...", cfg.Region)
lookupOutput, err := ctAws.GetEvents(cloudTrailclient, startTime)
lookupOutput, err := ctAws.GetEvents(cloudTrailclient, startTime, false)
if err != nil {
return err
}

filteredEvents, err := ctUtil.ApplyFilters(lookupOutput,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
if err != nil {
Expand All @@ -136,13 +129,13 @@ func (p *permissionDeniedEventsOptions) run() error {
HTTPClient: cfg.HTTPClient,
})
fmt.Printf("[INFO] Fetching Cloudtrail Global Permission Denied Event History from %v Region...", defaultConfig.Region)
lookupOutput, err := ctAws.GetEvents(defaultCloudtrailClient, startTime)
lookupOutput, err := ctAws.GetEvents(defaultCloudtrailClient, startTime, false)
if err != nil {
return err
}
filteredEvents, err := ctUtil.ApplyFilters(lookupOutput,
func(event types.Event) (bool, error) {
return isforbiddenEvent(event, permissionDeniedErrorStr)
return isforbiddenEvent(event)
},
)
if err != nil {
Expand Down
9 changes: 6 additions & 3 deletions cmd/cloudtrail/pkg/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,19 @@ func Whoami(stsClient sts.Client) (accountArn string, accountId string, err erro

// getWriteEvents retrieves cloudtrail events since the specified time
// using the provided cloudtrail client and starttime from since flag.
func GetEvents(cloudtailClient *cloudtrail.Client, startTime time.Time) ([]types.Event, error) {
func GetEvents(cloudtailClient *cloudtrail.Client, startTime time.Time, writeOnly bool) ([]types.Event, error) {

alllookupEvents := []types.Event{}
input := cloudtrail.LookupEventsInput{
StartTime: &startTime,
EndTime: aws.Time(time.Now()),
LookupAttributes: []types.LookupAttribute{
}

if writeOnly {
input.LookupAttributes = []types.LookupAttribute{
{AttributeKey: "ReadOnly",
AttributeValue: aws.String("false")},
},
}
}

paginator := cloudtrail.NewLookupEventsPaginator(cloudtailClient, &input, func(c *cloudtrail.LookupEventsPaginatorOptions) {})
Expand Down
4 changes: 2 additions & 2 deletions cmd/cloudtrail/write-events.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (o *writeEventsOptions) run() error {
fmt.Printf("[INFO] Checking write event history since %v for AWS Account %v as %v \n", startTime, accountId, arn)
cloudTrailclient := cloudtrail.NewFromConfig(cfg)
fmt.Printf("[INFO] Fetching %v Event History...", cfg.Region)
queriedEvents, err := ctAws.GetEvents(cloudTrailclient, startTime)
queriedEvents, err := ctAws.GetEvents(cloudTrailclient, startTime, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -180,7 +180,7 @@ func (o *writeEventsOptions) run() error {
HTTPClient: cfg.HTTPClient,
})
fmt.Printf("[INFO] Fetching Cloudtrail Global Event History from %v Region...", defaultConfig.Region)
lookupOutput, err := ctAws.GetEvents(defaultCloudtrailClient, startTime)
lookupOutput, err := ctAws.GetEvents(defaultCloudtrailClient, startTime, true)
if err != nil {
return err
}
Expand Down

0 comments on commit b30d722

Please sign in to comment.