diff --git a/cmd/api/src/daemons/datapipe/agi.go b/cmd/api/src/daemons/datapipe/agi.go index 406cc85cf..4125e2f17 100644 --- a/cmd/api/src/daemons/datapipe/agi.go +++ b/cmd/api/src/daemons/datapipe/agi.go @@ -160,11 +160,13 @@ func TagActiveDirectoryTierZero(ctx context.Context, featureFlagProvider appcfg. if autoTagT0ParentObjectsFlag, err := featureFlagProvider.GetFlagByKey(ctx, appcfg.FeatureAutoTagT0ParentObjects); err != nil { return err + } else if autoTagMembersFlag, err := featureFlagProvider.GetFlagByKey(ctx, appcfg.FeatureAutoTagT0ADMembers); err != nil { + return err } else if domains, err := adAnalysis.FetchAllDomains(ctx, graphDB); err != nil { return err } else { for _, domain := range domains { - if roots, err := adAnalysis.FetchActiveDirectoryTierZeroRoots(ctx, graphDB, domain, autoTagT0ParentObjectsFlag.Enabled); err != nil { + if roots, err := adAnalysis.FetchActiveDirectoryTierZeroRoots(ctx, graphDB, domain, autoTagT0ParentObjectsFlag.Enabled, autoTagMembersFlag.Enabled); err != nil { return err } else { properties := graph.NewProperties() diff --git a/cmd/api/src/database/migration/migrations/v5.15.0.sql b/cmd/api/src/database/migration/migrations/v5.15.0.sql index e40d065c5..76ae57dbe 100644 --- a/cmd/api/src/database/migration/migrations/v5.15.0.sql +++ b/cmd/api/src/database/migration/migrations/v5.15.0.sql @@ -31,6 +31,7 @@ INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabl INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabled, user_updatable) VALUES (current_timestamp, current_timestamp, 'risk_exposure_new_calculation', 'Use new tier zero risk exposure calculation', 'Enables the use of new tier zero risk exposure metatree metrics.', false, false) ON CONFLICT DO NOTHING; INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabled, user_updatable) VALUES (current_timestamp, current_timestamp, 'fedramp_eula', 'FedRAMP EULA', 'Enables showing the FedRAMP EULA on every login. (Enterprise only)', false, false) ON CONFLICT DO NOTHING; INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabled, user_updatable) VALUES (current_timestamp, current_timestamp, 'auto_tag_t0_parent_objects', 'Automatically add parent OUs and containers of Tier Zero AD objects to Tier Zero', 'Parent OUs and containers of Tier Zero AD objects are automatically added to Tier Zero during analysis. Containers are only added if they have a Tier Zero child object with ACL inheritance enabled.', true, true) ON CONFLICT DO NOTHING; +INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabled, user_updatable) VALUES (current_timestamp, current_timestamp, 'auto_tag_t0_ad_members', 'Automatically add members of Tier Zero AD groups to Tier Zero', 'Members incl. nested members of AD Tier Zero groups are automatically added to Tier Zero during analysis.', true, true) ON CONFLICT DO NOTHING; -- Note - order matters permissions and roles ops must come before roles permissions ops -- Permissions diff --git a/cmd/api/src/model/appcfg/flag.go b/cmd/api/src/model/appcfg/flag.go index 6de2fafac..8d10784f2 100644 --- a/cmd/api/src/model/appcfg/flag.go +++ b/cmd/api/src/model/appcfg/flag.go @@ -37,6 +37,7 @@ const ( FeatureFedRAMPEULA = "fedramp_eula" FeatureDarkMode = "dark_mode" FeatureAutoTagT0ParentObjects = "auto_tag_t0_parent_objects" + FeatureAutoTagT0ADMembers = "auto_tag_t0_ad_members" ) // FeatureFlag defines the most basic details of what a feature flag must contain to be actionable. Feature flags should be diff --git a/packages/go/analysis/ad/queries.go b/packages/go/analysis/ad/queries.go index db2d9b87b..ecf295b79 100644 --- a/packages/go/analysis/ad/queries.go +++ b/packages/go/analysis/ad/queries.go @@ -109,7 +109,7 @@ func FetchAllDomains(ctx context.Context, db graph.Database) ([]*graph.Node, err }) } -func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, domain *graph.Node, autoTagT0ParentObjectsFlag bool) (graph.NodeSet, error) { +func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, domain *graph.Node, autoTagT0ParentObjectsFlag bool, autoTagMembersFlag bool) (graph.NodeSet, error) { defer log.LogAndMeasure(log.LevelInfo, "FetchActiveDirectoryTierZeroRoots")() if domainSID, err := domain.Properties.Get(common.ObjectID.String()).String(); err != nil { @@ -134,11 +134,13 @@ func FetchActiveDirectoryTierZeroRoots(ctx context.Context, db graph.Database, d attackPathRoots.AddSet(wellKnownTierZeroNodes) } - // Pull in all group members of attack path roots - if allGroupMembers, err := FetchAllGroupMembers(ctx, db, attackPathRoots); err != nil { - return nil, err - } else { - attackPathRoots.AddSet(allGroupMembers) + if autoTagMembersFlag { + // Pull in all group members of attack path roots + if allGroupMembers, err := FetchAllGroupMembers(ctx, db, attackPathRoots); err != nil { + return nil, err + } else { + attackPathRoots.AddSet(allGroupMembers) + } } // Add all enforced GPO nodes to the attack path roots