From 9a8802f945f28524649fc741d062bbf55d33c941 Mon Sep 17 00:00:00 2001 From: Henning Perl Date: Thu, 21 Sep 2023 19:39:07 +0200 Subject: [PATCH] fix: limit expands that are too wide --- embedx/config.schema.json | 8 ++++++++ internal/check/engine.go | 15 +++++++++++++-- internal/driver/config/provider.go | 14 ++++++++++---- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 71436fa41..184c135fd 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -372,6 +372,14 @@ "description": "The global maximum depth on all read operations. Note that this does not affect how deeply nested the tuples can be. This value can be decreased for a request by a value specified on the request, only if the request-specific value is greater than 1 and less than the global maximum depth.", "minimum": 1, "maximum": 65535 + }, + "max_read_width": { + "type": "integer", + "default": 100, + "title": "Global maximum read width", + "description": "The global maximum width on all read operations. Note that this does not affect how deeply nested the tuples can be. This value can be decreased for a request by a value specified on the request, only if the request-specific value is greater than 1 and less than the global maximum width.", + "minimum": 1, + "maximum": 65535 } }, "additionalProperties": false diff --git a/internal/check/engine.go b/internal/check/engine.go index 0cd213723..8eea393bb 100644 --- a/internal/check/engine.go +++ b/internal/check/engine.go @@ -6,11 +6,12 @@ package check import ( "context" - "github.com/ory/herodot" - "github.com/ory/x/otelx" "github.com/pkg/errors" "go.opentelemetry.io/otel/trace" + "github.com/ory/herodot" + "github.com/ory/x/otelx" + "github.com/ory/keto/x/events" "github.com/ory/keto/internal/check/checkgroup" @@ -137,6 +138,16 @@ func (e *Engine) checkExpandSubject(r *relationTuple, restDepth int) checkgroup. } // If not, we must go another hop: + maxWidth := e.d.Config(ctx).MaxReadWidth() + if len(results) > maxWidth { + e.d.Logger(). + WithField("method", "checkExpandSubject"). + WithField("request", r.String()). + WithField("max_width", maxWidth). + WithField("results", len(results)). + Debug("too many results, truncating") + results = results[:maxWidth-1] + } for _, result := range results { sub := &relationtuple.SubjectSet{ Namespace: result.To.Namespace, diff --git a/internal/driver/config/provider.go b/internal/driver/config/provider.go index 9e2350676..40fb04406 100644 --- a/internal/driver/config/provider.go +++ b/internal/driver/config/provider.go @@ -10,21 +10,23 @@ import ( "fmt" "sync" + "go.opentelemetry.io/otel/trace" + "github.com/ory/x/fetcher" "github.com/ory/x/httpx" - "go.opentelemetry.io/otel/trace" "github.com/ory/keto/embedx" + "github.com/pkg/errors" + "github.com/rs/cors" + "github.com/spf13/pflag" + "github.com/ory/herodot" _ "github.com/ory/jsonschema/v3/httploader" "github.com/ory/x/configx" "github.com/ory/x/logrusx" "github.com/ory/x/otelx" "github.com/ory/x/watcherx" - "github.com/pkg/errors" - "github.com/rs/cors" - "github.com/spf13/pflag" "github.com/ory/keto/internal/namespace" ) @@ -40,6 +42,7 @@ const ( KeyDSN = "dsn" KeyLimitMaxReadDepth = "limit.max_read_depth" + KeyLimitMaxReadWidth = "limit.max_read_width" KeyReadAPIHost = "serve." + string(EndpointRead) + ".host" KeyReadAPIPort = "serve." + string(EndpointRead) + ".port" @@ -181,6 +184,9 @@ func (k *Config) OPLSyntaxAPIListenOn() string { return k.addressFor(EndpointOPL func (k *Config) MaxReadDepth() int { return k.p.Int(KeyLimitMaxReadDepth) } +func (k *Config) MaxReadWidth() int { + return k.p.Int(KeyLimitMaxReadWidth) +} func (k *Config) CORS(iface string) (cors.Options, bool) { switch iface {