Bird
Raised Fist0
FastAPIframework~20 mins

Role-based access control in FastAPI - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Role-based Access Control Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What is the output when accessing a protected route with insufficient role?

Consider a FastAPI route protected by a dependency that checks if the user has the 'admin' role. If a user with only the 'user' role tries to access it, what will be the HTTP response status code?

FastAPI
from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

fake_users_db = {
    "alice": {"username": "alice", "roles": ["user"]},
    "bob": {"username": "bob", "roles": ["admin"]}
}

def get_current_user(token: str = Depends(oauth2_scheme)):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication")
    return user

def require_admin(user: dict = Depends(get_current_user)):
    if "admin" not in user["roles"]:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions")
    return user

@app.get("/admin")
async def read_admin_data(user: dict = Depends(require_admin)):
    return {"msg": "Welcome admin!"}
AHTTP 403 Forbidden error
BHTTP 200 with message 'Welcome admin!'
CHTTP 401 Unauthorized error
DHTTP 404 Not Found error
Attempts:
2 left
💡 Hint

Think about what happens when the user is authenticated but lacks the required role.

📝 Syntax
intermediate
2:00remaining
Which code snippet correctly implements role checking in FastAPI dependency?

Choose the code snippet that correctly checks if the current user has the 'editor' role and raises a 403 error if not.

A
def require_editor(user: dict = Depends(get_current_user)):
    if user.roles != ['editor']:
        raise HTTPException(status_code=403, detail='Forbidden')
    return user
B
def require_editor(user: dict = Depends(get_current_user)):
    if 'editor' not in user['roles']:
        raise HTTPException(status_code=403, detail='Forbidden')
    return user
C
def require_editor(user: dict = Depends(get_current_user)):
    if 'editor' not in user.roles:
        raise HTTPException(status_code=403, detail='Forbidden')
    return user
D
def require_editor(user: dict = Depends(get_current_user)):
    if user['roles'] != 'editor':
        raise HTTPException(status_code=403, detail='Forbidden')
    return user
Attempts:
2 left
💡 Hint

Remember that roles are stored as a list inside a dictionary.

state_output
advanced
2:00remaining
What is the response when a user with multiple roles accesses a route requiring one role?

Given a user with roles ['user', 'editor'] accessing a route protected by a dependency that requires the 'editor' role, what will be the response?

FastAPI
from fastapi import FastAPI, Depends, HTTPException, status

app = FastAPI()

fake_users_db = {
    "carol": {"username": "carol", "roles": ["user", "editor"]}
}

def get_current_user(token: str):
    user = fake_users_db.get(token)
    if not user:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
    return user

def require_editor(user: dict = Depends(get_current_user)):
    if "editor" not in user["roles"]:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
    return user

@app.get("/edit")
async def edit_content(user: dict = Depends(require_editor)):
    return {"msg": f"Hello {user['username']}, you can edit content."}
AHTTP 403 Forbidden error
BHTTP 401 Unauthorized error
CHTTP 404 Not Found error
D{"msg": "Hello carol, you can edit content."}
Attempts:
2 left
💡 Hint

Check if the required role is present in the user's roles list.

🔧 Debug
advanced
2:00remaining
Identify the error in this role check dependency

What error will this FastAPI dependency raise when called?

FastAPI
def require_admin(user: dict = Depends(get_current_user)):
    if user['roles'] != 'admin':
        raise HTTPException(status_code=403, detail='Forbidden')
    return user
AAlways raises HTTP 403 even if user has 'admin' role
BRaises KeyError because 'roles' key is missing
CRaises TypeError due to wrong comparison
DReturns user correctly if 'admin' role is present
Attempts:
2 left
💡 Hint

Consider the data type of user['roles'] and what the comparison checks.

🧠 Conceptual
expert
2:00remaining
Why use dependencies for role-based access control in FastAPI?

Which is the best explanation for why FastAPI uses dependencies to implement role-based access control?

ADependencies force all routes to require admin role by default, simplifying security.
BDependencies automatically encrypt user roles to secure them from tampering.
CDependencies allow reusable, modular checks that run before route logic, enabling clean separation of authorization concerns.
DDependencies replace the need for authentication by verifying user identity through roles alone.
Attempts:
2 left
💡 Hint

Think about how dependencies help organize code and enforce checks.

Practice

(1/5)
1. What is the main purpose of role-based access control (RBAC) in FastAPI?
easy
A. To speed up API response times
B. To limit user actions based on their assigned roles
C. To automatically generate API documentation
D. To handle database migrations

Solution

  1. Step 1: Understand RBAC concept

    RBAC restricts what users can do depending on their roles, like admin or user.
  2. Step 2: Identify RBAC purpose in FastAPI

    FastAPI uses RBAC to check user roles before allowing access to certain endpoints.
  3. Final Answer:

    To limit user actions based on their assigned roles -> Option B
  4. Quick Check:

    RBAC = limit actions by roles [OK]
Hint: RBAC controls user permissions by roles, not speed or docs [OK]
Common Mistakes:
  • Confusing RBAC with performance optimization
  • Thinking RBAC auto-generates docs
  • Assuming RBAC manages database tasks
2. Which of the following is the correct way to declare a dependency that checks for an admin role in FastAPI?
easy
A. def admin_required(user: User = Depends(get_current_user)): if user.role == 'guest': raise HTTPException(status_code=401)
B. def admin_required(user: User): if user.role == 'admin': return True
C. def admin_required(): return 'admin' in user.roles
D. def admin_required(user: User = Depends(get_current_user)): if user.role != 'admin': raise HTTPException(status_code=403)

Solution

  1. Step 1: Check dependency signature

    def admin_required(user: User = Depends(get_current_user)): if user.role != 'admin': raise HTTPException(status_code=403) uses Depends to get current user, which is required for role checking.
  2. Step 2: Verify role check logic

    def admin_required(user: User = Depends(get_current_user)): if user.role != 'admin': raise HTTPException(status_code=403) raises HTTP 403 if user is not admin, correctly enforcing access control.
  3. Final Answer:

    def admin_required(user: User = Depends(get_current_user)): if user.role != 'admin': raise HTTPException(status_code=403) -> Option D
  4. Quick Check:

    Depends + role check + HTTPException = def admin_required(user: User = Depends(get_current_user)): if user.role != 'admin': raise HTTPException(status_code=403) [OK]
Hint: Use Depends to get user, then check role and raise HTTPException [OK]
Common Mistakes:
  • Not using Depends to get current user
  • Checking wrong role or missing exception
  • Returning True instead of raising exception
3. Given this FastAPI endpoint with role check dependency:
async def get_admin_data(admin: None = Depends(admin_required)):
    return {"data": "secret"}
What happens if a user with role 'user' calls this endpoint?
medium
A. The endpoint raises HTTP 403 Forbidden error
B. The endpoint returns {"data": "secret"}
C. The endpoint raises HTTP 401 Unauthorized error
D. The endpoint returns an empty response

Solution

  1. Step 1: Understand admin_required behavior

    admin_required raises HTTP 403 if user role is not 'admin'.
  2. Step 2: Apply to user role 'user'

    User role 'user' is not 'admin', so HTTP 403 is raised before endpoint runs.
  3. Final Answer:

    The endpoint raises HTTP 403 Forbidden error -> Option A
  4. Quick Check:

    Non-admin user triggers 403 error [OK]
Hint: Non-admin roles cause 403 error before endpoint runs [OK]
Common Mistakes:
  • Confusing 401 Unauthorized with 403 Forbidden
  • Expecting endpoint to return data for non-admin
  • Thinking empty response is returned
4. Identify the error in this FastAPI role check dependency:
def check_admin(user: User = Depends(get_current_user)):
    if user.role == 'admin':
        return True
    else:
        return False

@app.get('/admin')
async def admin_panel(is_admin: bool = Depends(check_admin)):
    if not is_admin:
        raise HTTPException(status_code=403)
    return {"msg": "Welcome admin"}
medium
A. Dependency should raise HTTPException directly, not return bool
B. Depends should not be used inside dependency functions
C. The endpoint should not check is_admin, dependency handles it
D. The function should return user object, not bool

Solution

  1. Step 1: Analyze dependency behavior

    check_admin returns True/False instead of raising HTTPException on failure.
  2. Step 2: Understand best practice for RBAC in FastAPI

    Dependencies should raise HTTPException to stop execution early, not return bool flags.
  3. Final Answer:

    Dependency should raise HTTPException directly, not return bool -> Option A
  4. Quick Check:

    Raise exception in dependency, don't return bool [OK]
Hint: Raise HTTPException in dependency to block access immediately [OK]
Common Mistakes:
  • Returning bool instead of raising exception
  • Not stopping request early in dependency
  • Misusing Depends inside dependencies
5. You want to create a reusable role checker in FastAPI that allows multiple roles (e.g., 'admin' or 'moderator') to access an endpoint. Which approach correctly implements this?
hard
A. def role_checker(user: User = Depends(get_current_user)): if user.role == 'admin' and user.role == 'moderator': return True raise HTTPException(status_code=403)
B. def role_checker(user: User = Depends(get_current_user)): if user.role != 'admin' or user.role != 'moderator': raise HTTPException(status_code=403)
C. def role_checker(allowed_roles: list[str]): def checker(user: User = Depends(get_current_user)): if user.role not in allowed_roles: raise HTTPException(status_code=403) return checker
D. def role_checker(allowed_roles: list[str]): for role in allowed_roles: if role == user.role: return True return False

Solution

  1. Step 1: Understand reusable dependency pattern

    def role_checker(allowed_roles: list[str]): def checker(user: User = Depends(get_current_user)): if user.role not in allowed_roles: raise HTTPException(status_code=403) return checker returns a function that checks if user role is in allowed_roles, raising HTTPException if not.
  2. Step 2: Verify logic for multiple roles

    def role_checker(allowed_roles: list[str]): def checker(user: User = Depends(get_current_user)): if user.role not in allowed_roles: raise HTTPException(status_code=403) return checker correctly uses 'not in' to allow any role in the list, making it reusable.
  3. Final Answer:

    def role_checker(allowed_roles: list[str]): def checker(user: User = Depends(get_current_user)): if user.role not in allowed_roles: raise HTTPException(status_code=403) return checker -> Option C
  4. Quick Check:

    Reusable role check with allowed_roles list = def role_checker(allowed_roles: list[str]): def checker(user: User = Depends(get_current_user)): if user.role not in allowed_roles: raise HTTPException(status_code=403) return checker [OK]
Hint: Return inner function checking role in allowed_roles, raise HTTPException [OK]
Common Mistakes:
  • Using incorrect logic with 'or' instead of 'in'
  • Returning bool instead of raising exception
  • Checking impossible conditions like role == 'admin' and 'moderator'