Bird
Raised Fist0
GraphQLquery~10 mins

Role-based access control in GraphQL - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Role-based access control
User sends GraphQL request
↓
Check user role in context
↓
Check permissions
↓
Allow or deny access
↓
Return data or error
The system checks the user's role before running the query and allows or denies access based on permissions.
Execution Sample
GraphQL
query GetUserData {
  user(id: "123") {
    name
    email
  }
}
A user requests data; the system checks their role to decide if they can see the email.
Execution Table
StepActionUser RolePermission CheckAccess ResultReturned Data
1Receive requesteditorCheck role 'editor'Role foundN/A
2Check permission for 'email' fieldeditorEditors allowed email access?YesProceed
3Fetch user dataeditorAccess grantedAllowed{name: 'Alice', email: 'alice@example.com'}
4Return responseeditorN/ASuccess{name: 'Alice', email: 'alice@example.com'}
5EndeditorN/ARequest completeN/A
💡 Request ends after data is returned or access is denied.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
userRoleundefinededitoreditoreditoreditor
permissionundefinedundefinedallowedallowedallowed
accessGrantedfalsefalsetruetruetrue
responseDatanullnullnull{name, email}{name, email}
Key Moments - 3 Insights
Why does the system check the user role before fetching data?
The system checks the role first (see Step 1 in execution_table) to decide if the user has permission to access requested fields, preventing unauthorized data access.
What happens if the user role is not found?
If no role is found, the system rejects the request immediately (see concept_flow branch 'No role' leading to 'Reject request'), so no data is fetched or returned.
Why is permission checked for each field?
Permissions can differ per field; checking each field (Step 2) ensures users only see data they are allowed to, protecting sensitive information.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the userRole after Step 2?
Aundefined
Badmin
Ceditor
Dguest
💡 Hint
Check the 'userRole' row in variable_tracker after Step 2.
At which step does the system decide if access is allowed?
AStep 2
BStep 3
CStep 1
DStep 4
💡 Hint
Look at the 'Permission Check' and 'Access Result' columns in execution_table.
If the userRole was 'guest' without email permission, what would change in the execution_table?
AUserRole would change to 'editor'
BAccess Result at Step 2 would be 'No', and no data returned
CPermission Check would be skipped
DResponseData would include email anyway
💡 Hint
Refer to how 'permission' and 'accessGranted' variables affect returned data in variable_tracker.
Concept Snapshot
Role-based access control in GraphQL:
- User role checked before query execution
- Permissions verified per requested field
- Access denied if role missing or insufficient
- Protects sensitive data by limiting field visibility
- Returns data only if access granted
Full Transcript
Role-based access control means the system checks the user's role before running a GraphQL query. It looks at the user's role in the request context and then checks if that role has permission to access each requested field. If the role is missing or does not have permission, the system denies access and does not return the data. This protects sensitive information by only showing data to users allowed to see it. The execution steps show receiving the request, checking role, verifying permissions, fetching data if allowed, and returning the response.

Practice

(1/5)
1. What is the main purpose of role-based access control (RBAC) in GraphQL APIs?
easy
A. To format the response data
B. To speed up query execution
C. To restrict data access based on user roles
D. To cache query results

Solution

  1. Step 1: Understand RBAC concept

    RBAC limits what data users can access depending on their assigned roles.
  2. Step 2: Identify RBAC purpose in GraphQL

    In GraphQL, RBAC ensures users only see or modify data allowed by their role.
  3. Final Answer:

    To restrict data access based on user roles -> Option C
  4. Quick Check:

    RBAC = restrict access by role [OK]
Hint: RBAC controls who can see or change data [OK]
Common Mistakes:
  • Confusing RBAC with performance optimization
  • Thinking RBAC formats data output
  • Assuming RBAC caches data
2. Which of the following is the correct way to apply a role-based directive in a GraphQL schema to restrict a query to admins only?
easy
A. type Query { users: [User] @hasRole(role: "admin") }
B. type Query { users: [User] @roleCheck("admin") }
C. type Query { users: [User] @auth(role: "admin") }
D. type Query { users: [User] @access(role = admin) }

Solution

  1. Step 1: Identify correct directive syntax

    The standard directive for role checks is @hasRole with a role argument as a string.
  2. Step 2: Match syntax to options

    type Query { users: [User] @hasRole(role: "admin") } uses @hasRole(role: "admin"), which is the correct syntax.
  3. Final Answer:

    type Query { users: [User] @hasRole(role: "admin") } -> Option A
  4. Quick Check:

    @hasRole(role: "admin") syntax correct [OK]
Hint: Look for @hasRole with role as string argument [OK]
Common Mistakes:
  • Using incorrect directive names like @auth or @roleCheck
  • Missing quotes around role name
  • Using = instead of : in directive arguments
3. Given this GraphQL query protected by @hasRole(role: "editor"), what will happen if a user with role "viewer" tries to run it?
query { editArticle(id: "123") { title content } }
medium
A. The query returns an authorization error
B. The query returns empty data with no error
C. The query returns the article data as usual
D. The query causes a server crash

Solution

  1. Step 1: Understand role restriction effect

    @hasRole(role: "editor") restricts access to users with the editor role only.
  2. Step 2: Check user role against required role

    User has role "viewer", which does not match "editor", so access is denied.
  3. Final Answer:

    The query returns an authorization error -> Option A
  4. Quick Check:

    Role mismatch = authorization error [OK]
Hint: Role mismatch causes authorization error [OK]
Common Mistakes:
  • Assuming query returns data anyway
  • Thinking query returns empty data silently
  • Believing server crashes on role denial
4. You wrote this schema directive to restrict a mutation to admins:
type Mutation { deleteUser(id: ID!): Boolean @hasRole(role: admin) }

Why does this cause a syntax error?
medium
A. The directive name @hasRole is invalid
B. ID! is not a valid type
C. Mutation type cannot have directives
D. The role value admin is missing quotes

Solution

  1. Step 1: Check directive argument syntax

    Directive arguments require string values in quotes, e.g., role: "admin".
  2. Step 2: Identify missing quotes error

    Here, role: admin lacks quotes, causing a syntax error.
  3. Final Answer:

    The role value admin is missing quotes -> Option D
  4. Quick Check:

    Directive string args need quotes [OK]
Hint: Always put role names in quotes in directives [OK]
Common Mistakes:
  • Thinking directive names are wrong
  • Believing directives can't be on mutations
  • Misunderstanding ID! type syntax
5. You want to allow only users with roles "admin" or "manager" to update product prices. Which schema directive setup correctly enforces this in GraphQL?
hard
A. type Mutation { updatePrice(id: ID!, price: Float): Product @hasAnyRole(roles: ["admin", "manager"]) }
B. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) }
C. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: "admin") @hasRole(role: "manager") }
D. type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(roles: "admin,manager") }

Solution

  1. Step 1: Understand multi-role directive syntax

    @hasRole accepts an array of roles to allow multiple roles access.
  2. Step 2: Evaluate options for correct syntax

    type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) } uses @hasRole(role: ["admin", "manager"]), which correctly passes an array of roles.
  3. Step 3: Identify incorrect options

    type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(roles: "admin,manager") } passes a string, not an array; C uses multiple directives which may not combine logically; A uses a non-standard directive @hasAnyRole.
  4. Final Answer:

    type Mutation { updatePrice(id: ID!, price: Float): Product @hasRole(role: ["admin", "manager"]) } -> Option B
  5. Quick Check:

    Array of roles in @hasRole = correct [OK]
Hint: Use array syntax for multiple roles in @hasRole [OK]
Common Mistakes:
  • Passing roles as comma string instead of array
  • Using multiple @hasRole directives expecting OR logic
  • Using non-standard directive names
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard