Add read only mode to block all the queries with mutations.

This commit is contained in:
2023-10-10 19:26:36 +01:00
parent 917ee1a431
commit 7de1cf7cc7
4 changed files with 18 additions and 1 deletions
+7 -1
View File
@@ -24,7 +24,7 @@ I wanted to monitor the queries and responses of our graphql endpoint, but we di
* MONITORING: Extracting user id from JWT token and adding it as a label to the metrics
* MONITORING: Extracting the query name and type and adding it as a label to the metrics
* MONITORING: Calculating the query duration and adding it to the metrics
* SPEED: Caching the queries
* SPEED: Caching the queries, together with per-query cache and TTL
* SECURITY: Blocking schema introspection
* SECURITY: Rate limiting queries based on user role
@@ -41,6 +41,7 @@ I wanted to monitor the queries and responses of our graphql endpoint, but we di
* `LOG_LEVEL` - the log level (default: `info`)
* `BLOCK_SCHEMA_INTROSPECTION` - blocks the schema introspection (default: `false`)
* `ENABLE_ACCESS_LOG` - enable the access log (default: `false`)
* `READ_ONLY_MODE` - enable the read only mode (default: `false`)
### Caching
@@ -85,6 +86,11 @@ If you'd like to change it - mount your configmap as `/app/ratelimit.json` file.
Remember to include the `-` role, which is used for unauthenticated users or when claim can't be found for any reason.
If rate limit has been reached - the proxy will return `429 Too Many Requests` error.
### Read only mode
You can enable the read only mode by setting the `READ_ONLY_MODE` environment variable to `true` - which will block all the `mutation` queries.
### Monitoring endpoint
Example metrics produced by the proxy:
+9
View File
@@ -2,6 +2,7 @@ package main
import (
"strconv"
"strings"
fiber "github.com/gofiber/fiber/v2"
"github.com/graphql-go/graphql/language/ast"
@@ -62,6 +63,14 @@ func parseGraphQLQuery(c *fiber.Ctx) (operationType, operationName string, cache
for _, d := range p.Definitions {
if oper, ok := d.(*ast.OperationDefinition); ok {
operationType = oper.Operation
if strings.ToLower(operationType) == "mutation" && cfg.Server.ReadOnlyMode {
cfg.Logger.Warning("Mutation blocked", m)
cfg.Monitoring.Increment(libpack_monitoring.MetricsSkipped, nil)
c.Status(403).SendString("The server is in read-only mode")
should_block = true
return
}
if oper.Name != nil {
operationName = oper.Name.Value
} else {
+1
View File
@@ -31,6 +31,7 @@ func parseConfig() {
c.Client.GQLClient = graphql.NewConnection()
c.Client.GQLClient.SetEndpoint(c.Server.HostGraphQL)
c.Server.AccessLog = envutil.GetBool("ENABLE_ACCESS_LOG", false)
c.Server.ReadOnlyMode = envutil.GetBool("READ_ONLY_MODE", false)
cfg = &c
enableCache() // takes close to no resources, but can be used with dynamic query cache
loadRatelimitConfig()
+1
View File
@@ -18,6 +18,7 @@ type config struct {
PortMonitoring int
HostGraphQL string
AccessLog bool
ReadOnlyMode bool
}
Client struct {