Bird
Raised Fist0
GraphQLquery~5 mins

Role-based access control in GraphQL

Choose your learning style10 modes available
Introduction

Role-based access control helps keep data safe by letting only certain people do certain things. It makes sure users see or change only what they are allowed to.

When you want to let managers see all employee records but regular employees see only their own.
When you want to allow admins to add or delete data but users can only read it.
When you want to hide sensitive information from some users based on their job role.
When you want to control who can update or delete posts in a blog app.
When you want to give different access levels in a school system for students, teachers, and staff.
Syntax
GraphQL
directive @hasRole(roles: [String!]) on FIELD_DEFINITION

type Query {
  getData: [Data] @hasRole(roles: ["admin", "manager"])
}
The @hasRole directive checks if the user has one of the allowed roles before running the query.
Roles are listed as strings inside the roles array.
Examples
This query lets only admins fetch all users.
GraphQL
type Query {
  allUsers: [User] @hasRole(roles: ["admin"])
}
This mutation allows admins and editors to delete posts.
GraphQL
type Mutation {
  deletePost(id: ID!): Post @hasRole(roles: ["admin", "editor"])
}
This query lets regular users and admins see their profile.
GraphQL
type Query {
  myProfile: User @hasRole(roles: ["user", "admin"])
}
Sample Program

This example shows a query that only admins can run to get secret data.

GraphQL
directive @hasRole(roles: [String!]) on FIELD_DEFINITION

type Query {
  secretData: String @hasRole(roles: ["admin"])
}

# Example resolver logic (not GraphQL schema):
# If user role is 'admin', return 'Top secret info'. Otherwise, deny access.
OutputSuccess
Important Notes

Role-based access control is often done using directives or middleware in GraphQL.

Always check user roles on the server side to keep data safe.

Summary

Role-based access control limits data access based on user roles.

Use directives like @hasRole to protect queries and mutations.

This helps keep your app secure and organized.

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