-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(router): refactor complexity limits #1364
base: main
Are you sure you want to change the base?
fix(router): refactor complexity limits #1364
Conversation
dcf43fa
to
8f70c7a
Compare
1fa616d
to
ee032c8
Compare
}, | ||
"size": { | ||
"type": "integer", | ||
"default": 1024, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make this 101024=10240?
Also, can you make planner cache, validation cache, and normalization cache the same default amount?
We've seen with some customers that 1024 is too low and 101024 doesn't increase memory usage dramatically.
"depth_limit": { | ||
"type": "object", | ||
"description": "The configuration for adding a max depth limit for query (how many nested levels you can have in a query). This limit prevents infinite querying, and also limits the size of the data returned. If the limit is 0, this limit isn't applied.", | ||
"description": "DEPRECATED (move to complexity_limits.depth): The configuration for adding a max depth limit for query (how many nested levels you can have in a query).", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered following this spec?
https://www.learnjsonschema.com/2020-12/meta-data/deprecated/
@@ -36,7 +36,10 @@ const ( | |||
WgValidationCacheHit = attribute.Key("wg.engine.validation_cache_hit") | |||
WgVariablesValidationSkipped = attribute.Key("wg.engine.variables_validation_skipped") | |||
WgQueryDepth = attribute.Key("wg.operation.query_depth") | |||
WgQueryDepthCacheHit = attribute.Key("wg.operation.query_depth_cache_hit") | |||
WgQueryTotalFields = attribute.Key("wg.operation.total_fields") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@StarpTech is this fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should scope it further e.g. wg.operation.complexity.total_fields
because it is not a common attribute and only set when complexity limits are enabled.
@@ -334,6 +336,28 @@ type QueryDepthConfiguration struct { | |||
IgnorePersistedOperations bool `yaml:"ignore_persisted_operations,omitempty" envDefault:"false" env:"SECURITY_QUERY_DEPTH_IGNORE_PERSISTED_OPERATIONS"` | |||
} | |||
|
|||
type ComplexityCalculationCache struct { | |||
Enabled bool `yaml:"enabled" envDefault:"false" env:"SECURITY_COMPLEXITY_CACHE_ENABLED"` | |||
CacheSize int64 `yaml:"size,omitempty" envDefault:"1024" env:"SECURITY_COMPLEXITY_CACHE_SIZE"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update defaults here accordingly as discussed in the other thread.
} | ||
if complexityLimitConfig.RootFieldAliases != nil && complexityLimitConfig.RootFieldAliases.ApplyLimit(isPersisted) { | ||
testComparisons = append(testComparisons, | ||
comp{complexityLimitConfig.RootFieldAliases.Limit, cachedComplexity.RootFieldAliases, fmt.Sprintf("The number of root fields aliases %d exceeds the root field aliases limit allowed (%d)", cachedComplexity.RootFieldAliases, complexityLimitConfig.RootFieldAliases.Limit)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The number of root field aliases %d exceeds the root field aliases limit allowed (%d)
} | ||
if complexityLimitConfig.TotalFields != nil && complexityLimitConfig.TotalFields.ApplyLimit(isPersisted) { | ||
testComparisons = append(testComparisons, | ||
comp{complexityLimitConfig.TotalFields.Limit, cachedComplexity.TotalFields, fmt.Sprintf("The query total fields %d exceeds the max total fields allowed (%d)", cachedComplexity.TotalFields, complexityLimitConfig.TotalFields.Limit)}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The total number of fields %d exceeds the limit allowed (%d)
} | ||
|
||
func (o *OperationKit) runComplexityComparisons(complexityLimitConfig *config.ComplexityLimits, cachedComplexity ComplexityCacheEntry, isPersisted bool) error { | ||
type comp struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should discourage inline structs. Please place them at the top of the file.
failedRes, _ := xEnv.MakeGraphQLRequest(testenv.GraphQLRequest{ | ||
Query: `{ employee(id:1) { id details { forename surname } } }`, | ||
}) | ||
require.Equal(t, 400, failedRes.Response.StatusCode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the tests to the telemetry tests.
@@ -36,7 +36,10 @@ const ( | |||
WgValidationCacheHit = attribute.Key("wg.engine.validation_cache_hit") | |||
WgVariablesValidationSkipped = attribute.Key("wg.engine.variables_validation_skipped") | |||
WgQueryDepth = attribute.Key("wg.operation.query_depth") | |||
WgQueryDepthCacheHit = attribute.Key("wg.operation.query_depth_cache_hit") | |||
WgQueryTotalFields = attribute.Key("wg.operation.total_fields") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should scope it further e.g. wg.operation.complexity.total_fields
because it is not a common attribute and only set when complexity limits are enabled.
Motivation and Context
Previous work (#1153) added in the opportunity to limit allowed query depth, rejecting a query if it passes the acceptable limit. This PR moves that configuration into a newly created security.complexity_limits
section, while still maintaining the now deprecated
security. depth_limit` section for the next 60 daysIt will now be configured using:
Checklist