graphql-api-hardening

Hardens Apollo Server GraphQL mocks with server-owned identity, allow-listed responses, query budgets, and version pins.

1|Updated Jun 9, 2026
One-click install
npx skills add https://github.com/VilnaCRM-Org/claude-plugins --skill graphql-api-hardening-vilnacrm-org
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: graphql-api-hardening
Source: https://github.com/VilnaCRM-Org/claude-plugins/tree/main/plugins/react-frontend-sdlc/skills/graphql-api-hardening
Command: npx skills add https://github.com/VilnaCRM-Org/claude-plugins --skill graphql-api-hardening-vilnacrm-org

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Local Apollo Server mocks and GraphQL resolvers often ship with unsafe defaults—client-writable IDs, leaked internal error details, unbounded queries, and drifting upstream contract versions—that become unsafe assumptions in production client code. This Skill enforces four non-negotiable hardening patterns whenever resolvers, error formatters, validation rules, or version pins change. ## Core Features & Use Cases - Server-owned identity: Generate primary keys in the resolver, reject client-supplied IDs and clientMutationId derivation, and build stored entities from an explicit input allow-list to prevent mass assignment. - Allow-listed responses: Rebuild error responses field by field with stable codes, generic messages, and correlation IDs, keeping stacktraces and internal details out of client-visible output. - Query budget enforcement: Apply depth, cost, page-size, and parser token limits so oversized or expensive operations are rejected with client errors instead of crashing the server. - Single version pin: Keep the GraphQL schema, OpenAPI spec, and mock fixtures interpolated from one upstream version variable, refreshed through the repository's contract targets. - Use Case: When adding a createUser mutation to the mock under docker/apollo-server, apply this Skill to generate the ID server-side, create the record unconfirmed, extend depth and page-size guards, and add a server-side unit test asserting only allow-listed fields appear in the response. ## Quick Start Ask the AI to review the resolver and error formatter changes in docker/apollo-server using the graphql-api-hardening skill before committing.

Frequently Asked Questions about graphql-api-hardening

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I secure a GraphQL mutation resolver against client-supplied IDs?▼

Generate the primary key inside the resolver and never read it from input or derive it from clientMutationId. Build the stored entity from an explicit allow-list of input properties so fields like id or confirmed cannot be mass-assigned, and key the store by a normalized natural identifier.

How do I prevent GraphQL errors from leaking internal details?▼

Rebuild the error response field by field from an allow-list at both the error and extensions levels, exposing only a stable code, a generic message, a correlation ID, and an enumerated reason. Pin includeStacktraceInErrorResponses off and log the caught error internally against the correlation ID.

How do I limit GraphQL query depth and page size in Apollo Server?▼

Apply depth, cost, and page-size validation rules plus a parser token limit, since validation runs after parsing. Scope page-size checks per operation and re-check them after the operation resolves, because limits passed through variables are invisible during document validation.

Does this hardening apply to client-side Apollo cache or hook work?▼

No, the skill explicitly excludes client-side Apollo cache, link, and hook work. It targets server-side concerns: resolvers, error formatters, validation rules, parse options, and the pinned upstream API service version.

When should the GraphQL hardening checks be skipped?▼

Skip with a recorded note when the repository profile maps framework.graphql_mock to null, meaning there is no local mock to harden, or when make.test_unit_server maps to null and no server-side suite exists. Component-library shapes without a server are also out of scope.

Why should the upstream API version use a single pin variable?▼

One variable naming the upstream release lets the GraphQL schema, OpenAPI spec, and mock fixtures all interpolate the same value, so contract tests reflect something real. Drift between two pinned versions makes contract tests agree with nothing real.