What does an open introspection query on a GraphQL endpoint expose to any caller?
answer
- The endpoint answers questions about itself
- Shape travels, values do not
- One response, the whole SDL
- Descriptions survive; source comments do not
- Reconnaissance, not access
basics
~10 sThe whole type system. One introspection result is enough to print the schema back out as SDL: every type, field, argument, enum value, interface and deprecation reason. It exposes shape, never data.
solid answer
~40 sIntrospection answers the `__schema` and `__type` meta-fields on the query root, and a single walk of them yields the complete type system: every object, input, interface, union, enum and scalar; every field with its argument names, types, nullability and printed default values; every directive definition; and the human-written descriptions. Anyone can reprint that as SDL. On a legal case-file graph it hands a stranger `sealCase`, `purgePrivilegedNote` and the members of a `RedactionStatus` enum without a single guess. Note what it does **not** give: no data, no resolver code, and no statement of what this caller is allowed to run. Deprecated fields are left out of a field listing unless the caller explicitly asks for them, and `#` comments from the schema source are lost while descriptions survive verbatim. Introspection is reconnaissance, not access.
code
graphql · 12 linestype Mutation {
sealCase(caseId: ID!, reason: String!): Case!
purgePrivilegedNote(noteId: ID!): Boolean!
reopenMatter(matterId: ID!, justification: String): Matter
}
"Grading applied by the conflicts team before a filing is released."
enum RedactionStatus {
NONE
PARTIAL
ATTORNEY_EYES_ONLY
}go deeper
Be ready to say in one sentence what comes back: the entire type system, printable as SDL, and no data at all. Knowing that introspection travels over the same endpoint as ordinary queries is the point being checked.
Explain the boundary precisely — descriptions and printed defaults survive, # comments and directive applications do not, deprecated fields need an explicit ask. Interviewers listen for whether you can separate what is exposed from what is executable.
Show that you rate this as reconnaissance rather than access, and say what you would actually inspect first: whether any operation named in that SDL is reachable without authorization. That triage is the answer, not the toggle.
Own the question of whether your schema's shape is public by design. Descriptions become external documentation the moment introspection is served, so decide who writes them and for whom, rather than discovering internal notes on a partner's screen.
## The one-line definition A GraphQL server is required by the specification to describe its own type system on request. Two meta-fields on the query root type, `__schema` and `__type`, return that description as ordinary GraphQL data. That is the whole trick: the schema is queryable through the same endpoint, the same document syntax and the same response envelope as your business data, so any caller who can send a query can read it. The mechanics of those meta-types are a type-system subject in their own right; what matters here is the *exposure*, which is what an interviewer is actually asking about. ## What one result contains Enough to reconstruct the SDL. Concretely: * every named type and its kind — object, interface, union, enum, input object, scalar; * for each object and interface, its fields: name, description, deprecation flag and deprecation reason, and the full argument list; * for each argument and input field: name, type reference (carrying nullability and list wrapping) and the *printed* default value; * enum values, union member types, and the interfaces each object implements; * every directive **definition**, with its valid locations and arguments; * the names of the root operation types. Run that through a printer and you have the schema file, minus formatting. On a legal case-file graph with 218 types and 1,247 fields, that is a complete map of the API produced by one request, in well under a second. ## What it does not contain This is the half candidates skip, and it is what separates a real answer from a scare story. * **No data.** Introspection describes `Case.privilegedNoteCount`; it does not return anybody's case. * **No implementation.** No resolver source, no backing store, no service topology — though names leak intent, and a field called `legacyBillingLookup` tells a reader something. * **No entitlements.** A field being present in the type system says nothing about whether this caller may execute it. Introspection is not a permission listing, and treating it as one is a common misreading in both directions. * **Not the schema file.** `#` comments, file layout and definition ordering across files are gone. Descriptions — the docstring-style strings — do survive, verbatim, which is why an internal note written for teammates becomes public documentation. * **Not directive applications.** Standard introspection reports which directives *exist*, not which schema elements they were applied to. Deprecation is the deliberate exception, because it has its own `isDeprecated` and `deprecationReason` fields (later editions add a dedicated field for the URL a custom scalar points at). So a custom `@auditLogged` marker on a field will not show up, but everything the field looks like will. ## The deprecation wrinkle A field listing omits deprecated fields by default; a boolean argument on that listing includes them. People read "omitted by default" as "hidden" and it is not — asking once returns them, along with the reason string explaining why they were retired. That matters because a deprecated field is usually the least maintained, least tested and least tightly authorized thing in the schema, which makes it the most attractive to probe. ## Why an interviewer cares Because the honest risk statement is narrow and precise, and most candidates give a vague one. Introspection is a *reconnaissance* channel: it removes guesswork about names, arguments and shapes. If your schema exposes an administrative mutation that anyone can call, introspection is how it gets found in a minute rather than a month — but the vulnerability is that the mutation is callable, not that it is nameable. Conversely, if every field is authorized during execution, publishing the type system costs you exposure of your product's shape and your internal descriptions, which is a real cost worth deciding on deliberately, and not much more. So the two follow-on controls are different in kind: authorization enforced during execution decides what *runs*, while restricting introspection decides what is *listed*. Only the first is a security boundary. ## What to say "One introspection response reconstructs the SDL — every type, field, argument, default and description, plus deprecated fields if you ask for them. It gives no data, no code and no indication of what I'm authorized to call. It is a reconnaissance surface: it makes an unprotected operation trivial to find, but it does not make a protected one callable."
- Does an introspection result tell a caller which fields they are allowed to execute?No. Introspection describes the type system, not the caller's entitlements. A field listed there may still be refused during execution, and a field the caller is entitled to run is listed for everyone. Reading a permission model out of introspection is a misreading in both directions: absence is not denial, and presence is not permission.
- Are deprecated fields hidden from introspection?Only by default. A field listing omits them unless the caller passes the argument that includes them, at which point they come back with their deprecation reason attached. So deprecation is documentation, never concealment — and a retired field is often the least maintained and least carefully authorized part of the schema.
- What is lost between the schema source file and a schema rebuilt from introspection?Formatting, `#` comments and how definitions were split across files. Descriptions, deprecation reasons and printed argument defaults all survive. Applications of custom type-system directives are also lost — standard introspection reports directive definitions, not which elements carry them, with deprecation as the built-in exception.
Introspection is the building's floor plan, not its keys. Handing out the plan tells a stranger exactly which door says "Records Room"; whether that door is locked is a separate question, and the only one that decides who gets in.
saying these in an interview costs you the question
- Says introspection returns records, not just the schema
- Thinks introspection only answers authenticated callers
- Claims deprecated fields are permanently hidden
- Assumes descriptions stay internal to the team
- Believes rebuilding the SDL needs many crafted requests
- Treats a listed field as proof of permission