GraphQL surface review
GraphQL Surface Review V1 is a non-default, anonymous protocol review for an
explicit web-review scan. Both termivar-scanner and termivar-cli use the
graphql-review feature, and the operator must also pass --graphql-review.
The feature is absent from default builds; a feature-enabled CLI rejects the
flag without an explicit web-review profile or with baseline.
This runtime does not change decision-scan/v1, the default scan, or the
transport-neutral API reasoner. It adds one separately authorized scanner child
that uses the existing request broker, RuntimeBudget, cancellation, exact
origin, and redirect-disabled policy.
Authority and endpoint selection
V1 is anonymous only. Its requests do not read or replay authorization values, cookies, or other credential sources, even when the independent authorization-context comparison is enabled in the same assessment.
At most one endpoint is selected deterministically. Candidate evidence is
ranked from an exact application/graphql-response+json media type, an exact
graphql path segment, or an exact-origin discovered reference. Because the
operator explicitly enabled the review, /graphql may be used as the bounded
V1 runtime fallback. The closed selector models /api/graphql for a future
explicit fallback policy, but this runtime does not probe both conventional
paths. Cross-origin, credential-bearing, fragment-bearing, query-bearing,
redirect-derived, or oversized candidates are rejected.
Fixed request protocol
The strategy is web.review.graphql.introspection-pair@1. It sends up to
three anonymous POST requests with bounded JSON bodies to the selected
endpoint:
- A scanner-owned control operation requests only an aliased
__typename. - A distinct candidate requests its aliased
__typenameand__schemaroot metadata:queryType { name },mutationType { name }, andsubscriptionType { name }. - A replay uses a distinct scanner-owned operation name and alias while requesting the same bounded root metadata.
Operation names and aliases follow the GraphQL Name grammar and are entirely scanner-owned. The request plan has a hard maximum of one selected endpoint, three requests, and one active verification. It sends no variables, fragments, directives, application fields, mutations, subscriptions, batches, alias fan-out, or full schema enumeration.
The candidate and replay have different request-body digests and both must be broker-dispatched. Locally cached candidate evidence cannot satisfy replay.
Response and evidence contract
The bounded classifier distinguishes an exact control envelope, an exact schema-root introspection envelope, structured GraphQL errors, generic JSON, HTML, unsupported media, malformed or ambiguous JSON, truncation, and other incomplete states. Checked ceilings cover retained response bytes, JSON depth, nodes, object members, arrays, strings, and error count.
A correlated control envelope may produce one GraphQL surface observed item. Anonymous root introspection is reported only when both the candidate and distinct replay contain the exact expected aliases and equivalent bounded schema-root structure. Public evidence retains only whether query, mutation, and subscription roots are present; it does not retain their names, raw request bodies, raw response bodies, or GraphQL error messages.
Both item types are Informational under KnowledgeOnly authority.
Introspection availability may be intentional and is not a vulnerability,
authorization bypass, schema leak, or data-exposure conclusion. Restricted
introspection can retain the endpoint observation but not the introspection
item. Generic JSON, HTML, a replay mismatch, ambiguous structure, truncation,
or exhausted parser limits cannot become a completed positive result.
Deliberately absent in V1
Only bounded schema-root introspection is executable. GET queries, JSON-array batching, full schema enumeration, detailed-error review, field suggestions, alias amplification, depth/complexity testing, persisted queries, multipart uploads, subscriptions, mutation/CSRF review, and authenticated GraphQL review remain metadata-only. Catalog breadth creates no request obligation.
V1 performs no mutation, application-record enumeration, authorization test, denial-of-service probe, WebSocket connection, external callback, redirect follow, or cross-origin request.
Conformance evidence
Sanitized security-assessment-fixture/v1 cases exercise exact control and
introspection envelopes, restricted introspection, malformed and partial
responses, parser-limit incompleteness, generic JSON, and GraphQL-like HTML.
Batch-shaped and GET-query cases remain metadata-only. These fixtures prove
deterministic contract conformance; they do not establish empirical scanner
accuracy or real-world GraphQL coverage. See the
scanner conformance corpus.