You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3e1a0fd
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,8 @@
2
2
3
3
## Changes
4
4
5
+
-`ToGraphQLSchemaStringAsync(ClaimsPrincipal? user)` (and `ToGraphQLSchemaString(QueryRequestContext? requestContext)`) output SDL containing only what that user may access, using the schema's `AuthorizationService` as query execution does. The result is self-consistent: a type the filtering leaves empty is hidden along with the fields returning it, a field is hidden when an argument's type is hidden, hidden interfaces and union members are dropped from `implements` and union lists, and a directive with an argument of a hidden type is hidden. Useful for handing a schema to a user or AI agent (e.g. an MCP server tool) where SDL is more compact than introspection. `ToGraphQLSchemaString()` without a user still outputs the full schema. Both are default interface methods on `ISchemaProvider`, so custom implementations do not break.
6
+
- Introspection for a user now hides the same things the SDL does. Previously a type with no type-level authorization but every field protected was still listed (with `fields: []`), a field taking an argument of a protected enum or input type was listed, protected interfaces still appeared in `interfaces`, and a directive with an argument of a protected type was listed. These are now hidden, so a client building a schema from introspection gets a valid one. Introspection without a user is unchanged.
5
7
-`[Required]` on an argument (a property/field of an arguments object or a method parameter) now behaves like `ArgumentHelper.Required<T>()` - the argument has no default value and must be provided by the query. Previously a value type kept its implicit `default(T)` as the schema default, so `[Required] int Take` printed `take: Int! = 0` (optional for clients) and a query leaving it out ran with `0`. It is now `take: Int!` and leaving it out is a `missing required argument` error. Remove `[Required]` if you relied on the old default.
6
8
- Introspection `__InputValue.defaultValue` no longer strips the quotes off string-like defaults. The spec defines it as the GraphQL literal, so a string default of `hello` is now returned as `"hello"` - the same text as in the SDL. Clients building a schema from introspection (`buildClientSchema`, GraphiQL, codegen against an endpoint) previously dropped such defaults or failed to parse them (`Guid`, strings with spaces). If you read `defaultValue` directly as text rather than parsing it as GraphQL, string defaults now include their quotes.
Copy file name to clipboardExpand all lines: docs/docs/authorization.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -63,7 +63,17 @@ A bare attribute with no roles or policies — `[GraphQLAuthorize]` or `[Authori
63
63
64
64
Introspection queries (`__schema` and `__type`) respect authorization — the result only includes the types and fields the requesting user is authorized to access, so protected type/field names are not discoverable by unauthorized users. Querying `__type(name: ...)` for a protected type returns `null`.
65
65
66
-
Note this applies only to introspection queries at runtime. `schema.ToGraphQLSchemaString()` always outputs the full schema — use it to generate SDL files for tooling and type generation.
66
+
`schema.ToGraphQLSchemaString()` always outputs the full schema — use it to generate SDL files for tooling and type generation.
67
+
68
+
To get SDL filtered for a user, use `ToGraphQLSchemaStringAsync(user)`. It uses the schema's `AuthorizationService` exactly as query execution does, and applies the same rules as introspection.
The result is self-consistent SDL: nothing in it refers to a type it does not define. Protected types are left out, as are fields that are protected, return a hidden type or take an argument of a hidden type. A type whose fields are all hidden is itself hidden, which can in turn hide the fields returning it. Protected interfaces are dropped from `implements` lists, and protected types from union member lists. A directive with an argument of a hidden type is hidden. The query root always stays: for a user who can see no query fields it is output as a bare `type Query`, which parses but fails schema validation, as there is no valid SDL for a schema with nothing in it. Introspection hides exactly the same types and fields, so `__schema`, `__type` and the SDL agree.
75
+
76
+
This is useful when handing a schema to a person or an AI agent (e.g. an MCP server tool), where fields they cannot query are noise or information they should not have. SDL is far more compact than an introspection result for the same information.
/// <summary>SDL with only what <paramref name="user"/> may see, filtered by this schema's AuthorizationService. See SchemaProvider for details.</summary>
0 commit comments