GraphQL lets a client request named fields through a typed schema. A schema describes available types and fields; it is not a permission grant. In the supplied schema, Note has id, title and owner, and Query exposes note(id). A query selects a note and asks for some of its fields.
A resolver is application code that obtains a field's value. The rule here permits returning a private note only to its owner. Authorization can be enforced in shared business logic used by resolvers, so every route to the data follows the same rule. Merely listing a field in the schema cannot establish who may receive it.
Before you begin
- Recommended first
- Notes: scope, command, result, time, HTTP methods, headers, status codes, cookies, How a web app is put together, Same-origin policy, JWT
- Estimated time
- 18 min reading, 16 min activity. Setup and optional practice may take longer.
- Where you work
- Read the original fictional source, object tables, token claims and policy models in any current desktop or mobile browser. No loader, template engine, provider registration, service or network request is required.
- Without a lab
- Follow the printed data through each stated rule on paper. Record the decision, its supporting fact and a limit, then compare with the guided rubric. Model reasoning does not establish a live tool result. Reading works without JavaScript. Checking requires JavaScript and a secure context; saving also requires usable storage.
After this lesson you can:
- Allow the activity query for note 7 because the caller is the owner.
- Keep a schema line from standing in for the permission.
01Example
This fresh field-level example shows that a valid query can still be restricted by policy. The activity applies an ownership rule to notes instead.
Schema: Query includes serviceHealth.
Policy: serviceHealth is public.
Caller: guest
Decision: may return serviceHealth.
The schema describes the field; the public policy grants this read.02Shape is not permission
Read note(id: 7) as choosing the note with identifier 7, and { title } as requesting its title field. The activity trace supplies caller A and owner A, so the ownership rule can be applied from those facts. The separate note-42 trace shows the same schema with a different caller/owner relationship.
The boundary is a requested field reaching protected data. Enforce identity and object permissions in the resolver's data-access path. Depth and cost limits address resource consumption; they do not decide ownership. Introspection reveals schema structure, but revealing structure and returning someone else's private record are different concerns. These traces are original models, not observed service responses.
Read a schema as the shape of a note, and let the resolver decide whether this caller may see it.Model. A teaching model drawn by hand. It shows the idea, not real tool output.
Read the full explanation below.
Schema: Query includes serviceHealth.
met · The field exists in Query.Policy: serviceHealth is public.
met · serviceHealth is explicitly public.The public policy grants this read; schema alone supplies shape.
A schema describes possible data; the field's policy grants this particular read.
The public policy grants this read; schema alone supplies shape.
Follow the explanation
- The public policy grants this read; schema alone supplies shape.
- Retain the separate policy line when explaining the supplied guest decision.
Read every state and value
1. The public policy grants this read; schema alone supplies shape.
- Case
- guest
- Conditions inspected
- shape · Public-read policy
- Decision shown
- Yes
2. Retain the separate policy line when explaining the supplied guest decision.
- Case
- shape
- Conditions inspected
- shape · Public-read policy
- Decision shown
- Yes
03Trace the activity query
Read the evidence before comparing with the activity rubric. Do not start a service.
type Note {
id: ID
title: String
owner: String
}
type Query {
note(id: ID): Note
}
Activity query. Caller A. Note 7 is owned by A.
{
note(id: "7") {
title
}
}
Original fictional resolver evidence. No query was sent.
Rule: return a private note only when caller equals owner.
Unworked checkpoint-style evidence
caller A
note 42
owner B
Use the rule to decide this case independently.
Guided activity
caller A
note 7
owner A
Model decision: the matching caller/owner permits returning the requested title.
The schema lists title regardless of the caller. Schema shape does not grant permission.
- Write the caller, the note, and the owner on the activity trace.
- Apply the rule that a note is returned only to its owner.
- Rubric: the activity caller and owner match, so the private-owner rule permits returning the requested title. The schema describes the field, while the ownership evidence supplies this decision.
- Stop. Do not send the query to a real endpoint.
04Stage case
Allow about twenty minutes for the final self-review. Connect each fresh case to its boundary, possible harm, fitting defense and evidence limit. The byte counts are symbolic, the claims are synthetic and the resolver decisions are modeled. Completing browser checks records understanding here; it does not establish hands-on reproduction or security proficiency. Advanced topics remain part of the full stage while later stages stay available.
Original fictional stage case. Self-review. About twenty minutes.
1. Frontend end byte 40, backend end byte 28. Explain why agreeing on a boundary matters before either peer accepts another request.
2. Claims issuer is other-lab and audience notes. Signature verification succeeds. The notes policy expects issuer lab. State the remaining failed condition.
3. Caller A requests note 7, owned by A. Apply the private-owner rule separately from schema shape.
4. A public debug setting reveals internal configuration. Find the matching 2025 category and its identifier.
5. Write four limits: the byte positions are symbolic; no signature was computed here; the resolver is a policy model; the category does not establish the absence of other weaknesses.
Rubric: reject the modeled framing disagreement; the issuer condition fails; the same-owner note may be returned; Security Misconfiguration A02:2025; retain all four evidence limits.
Core readiness uses server/client topics and the map. Advanced lessons remain part of full-stage completion, and later stages remain available.
05Optional challenge
Contrast an overly wide query with an ownership failure. The rubric is: width is how much the query asks, and ownership is whether this caller may receive the note. About ten minutes.
06Fresh cases for the checks
Use these fictional cases for the checks below. They have different inputs from the worked examples. Read them here or make notes; no installation or external service is needed.
Query case A: fresh schema and queryOwned fixture. An original file made for this course. Follow the activity's instructions in your own lab.
Schema: type Note { id: ID, title: String, owner: String }
Schema: Query has note(id: ID): Note
Query: { note(id: "91") { title } }
The query selects only title; a listed schema field does not itself grant access.
Query case B: independent resolver policyOwned fixture. An original file made for this course. Follow the activity's instructions in your own lab.
Rule: return a private note’s requested title only when authenticated caller equals stored owner.
P: caller Lina, note 92, owner Lina.
Q: caller Oren, note 93, owner Lina.
R: caller Oren, note 94, owner Oren.
No query was sent and no service response was captured.
07Explain your evidence
Optional written self-check: explain one decision using the supplied case. No tool run is required.
Check your explanation: read arguments and selected fields separately from schema availability; compare caller with stored owner; locate authorization in the resolver data path; distinguish query resource limits from object permission and preserve model provenance.
08Common mistakes
If a field in the schema seems automatically readable, find the separate policy governing its data.
If note 7 seems forbidden, compare activity caller A with owner A instead of using the other trace's owner.
A query limit constrains resource use; it does not grant permission to receive a private record.
References
- GraphQL specification, October 2021
Defines type-system and query syntax. The private-note policy is original application logic, separate from schema shape.
- PortSwigger: GraphQL
Further explanation of this mechanism and its defenses. The original printed model supplies the required evidence.
- GraphQL: Authorization
Explains authorization in business logic so consistent permission rules protect data reached through resolvers.
Next is the first lesson of Crypto and files.