graphql
GraphQL query parsing and analysis for authorization policies.
GraphQL Function Library for SAPL
Parses GraphQL queries and extracts security metrics for authorization policy decisions.
Basic Usage
var gql = graphql.validateQuery(resource.query, resource."schema");
// Access properties directly
gql.valid // boolean - query validity
gql.fields // array - all field names
gql.depth // integer - maximum nesting depth
gql.operation // string - operation type (query/mutation/subscription)
gql.complexity // integer - complexity score
// Security metrics
gql.security.aliasCount // integer - aliased field count
gql.security.batchingScore // integer - batching attack indicator
gql.security.maxPaginationLimit // integer - highest pagination limit
gql.security.hasCircularFragments // boolean - circular fragment detection
gql.security.isIntrospection // boolean - introspection query
gql.security.directiveCount // integer - directive count
gql.security.directivesPerField // number - average directives per field
// AST details
gql.ast.operationName // string - operation name
gql.ast.types // array - types used
gql.ast.variables // object - variable definitions
gql.ast.arguments // object - field arguments
gql.ast.fragments // object - fragment definitions
gql.ast.directives // array - directive details
Functions
validateQuery
graphql.validateQuery(TEXT query, TEXT schema) -> OBJECT
Parses and validates a GraphQL query against a schema. Returns object with all security metrics.
Example:
policy "validate-graphql-query"
permit action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.valid && gql.depth <= 5 && !("ssn" in gql.fields);
analyzeQuery
graphql.analyzeQuery(TEXT query) -> OBJECT
Parses a GraphQL query without schema validation. Returns same metrics as validateQuery() but valid only checks syntax.
Example:
policy "analyze-query-structure"
permit action == "execute";
var gql = graphql.analyzeQuery(resource.query);
gql.depth <= 5 && gql.security.aliasCount <= 10;
complexity
graphql.complexity(OBJECT parsed, OBJECT fieldWeights) -> NUMBER
Calculates weighted complexity using custom field weights. Unweighted fields default to 1.
Example:
var gql = graphql.validateQuery(resource.query, resource."schema");
var weights = {"posts": 5, "comments": 3, "user": 1};
graphql.complexity(gql, weights) <= 200;
parseSchema
graphql.parseSchema(TEXT schema) -> OBJECT
Parses and validates a GraphQL schema definition.
Common Use Cases
Field-Level Access Control
policy "restrict-pii-fields"
deny action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
var piiFields = ["ssn", "creditCard", "taxId"];
array.containsAny(gql.fields, piiFields);
Depth and Complexity Limiting
policy "enforce-limits"
permit action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.valid && gql.depth <= 5 && gql.complexity <= 100;
Operation Type Control
policy "mutations-require-admin"
permit action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.operation != "mutation" || subject.role == "admin";
Batching Attack Prevention
policy "prevent-batching"
deny action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.security.aliasCount > 10 || gql.security.batchingScore > 50;
Comprehensive Security
policy "comprehensive-security"
permit action == "execute";
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.valid &&
gql.depth <= 5 &&
gql.fieldCount <= 50 &&
gql.security.aliasCount <= 10 &&
gql.security.maxPaginationLimit <= 100 &&
!gql.security.hasCircularFragments &&
!gql.security.isIntrospection &&
!("ssn" in gql.fields);
Multiple operations
A document may declare several named operations; the one executed is chosen at request time by the
operationName parameter, which this analysis does not observe. The security metrics (depth, fields,
complexity, security.*) therefore describe the worst case across every operation in the document: the
maximum depth and pagination limit, the union of all field names, and the logical OR of the introspection
and circular-fragment flags. The descriptive operation, ast.operationName and ast.variables fields
reflect the first operation in source order. When a document may carry more than one operation, gate on the
aggregate security metrics rather than on the descriptive operation fields.
Error Handling
Invalid queries set valid to false with errors in errors array. Check valid before using other metrics.
Limits
To bound memory and computation on untrusted input, the following limits apply:
- Reported query depth is capped at 100. The
depthmetric never exceeds this value regardless of how deeply the query or its operations nest, so depth comparisons in policies saturate at 100. - A schema passed to
validateQueryorparseSchemamay be at most 512 KB (524288 bytes). A larger schema is rejected with an error.
These limits apply because this input may originate from the authorization subscription or from policy information points, which are not vetted to the same degree as the policies and variables shipped with the PDP configuration.
complexity
graphql.complexity(OBJECT parsed, OBJECT fieldWeights) -> NUMBER
Calculates weighted complexity with custom field weights.
Example:
var gql = graphql.validateQuery(resource.query, resource."schema");
var weights = {"posts": 5, "comments": 3};
graphql.complexity(gql, weights) <= 200;
validateQuery
graphql.validateQuery(TEXT query, TEXT schema) -> OBJECT
Parses and validates a GraphQL query against a schema.
Returns comprehensive security analysis including validation, field extraction, complexity metrics, and potential security concerns.
Example:
var gql = graphql.validateQuery(resource.query, resource."schema");
gql.valid && gql.depth <= 5 && !("ssn" in gql.fields);
analyzeQuery
graphql.analyzeQuery(TEXT query) -> OBJECT
Parses a GraphQL query without schema validation. Only validates syntax.
Example:
var gql = graphql.analyzeQuery(resource.query);
gql.depth <= 5 && gql.security.aliasCount <= 10;
parseSchema
graphql.parseSchema(TEXT schema) -> OBJECT
Parses and validates a GraphQL schema definition.
Example:
var schemaResult = graphql.parseSchema(resource."schema");
schemaResult.valid;