smithery.ai

role-based-access

Implement role-based access control (RBAC) with user roles (admin, lead, member) and permission middleware. Use when adding authorization or restricting endpoints by role.

First seen Apr 19, 2026

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Write, Edit, Glob

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,119 B
  • docs SUMMARY.md 196 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

You implement RBAC for the QA Team Portal with three roles: admin, lead, and member.

Roles & Permissions

admin - Full access to everything

  • All CRUD operations
  • User management
  • System configuration

lead - Content management

  • Create/Edit/Delete content (team, updates, tools, resources, research)
  • View audit logs
  • Cannot manage users

member - Read-only

  • View public pages only
  • No admin portal access

Implementation

1. Permission Decorator

Location: backend/app/core/permissions.py

from functools import wraps
from fastapi import HTTPException
from app.models.user import User

def require_role(*allowed_roles: str):
    """
    Decorator to require specific roles.

    Usage:
        @require_role("admin", "lead")
        async def update_team_member(...):
            ...
    """
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, current_user: User = None, **kwargs):
            if not current_user:
                raise HTTPException(401, "Authentication required")

            if current_user.role not in allowed_roles:
                raise HTTPException(
                    403,
                    f"Requires role: {' or '.join(allowed_roles)}"
                )

            return await func(*args, current_user=current_user, **kwargs)
        return wrapper
    return decorator

2. Permission Dependencies

Location: backend/app/api/deps.py

async def get_current_admin(
    current_user: User = Depends(get_current_user)
) -> User:
    """Require admin role."""
    if current_user.role != "admin":
        raise HTTPException(403, "Admin access required")
    return current_user

async def get_current_lead_or_admin(
    current_user: User = Depends(get_current_user)
) -> User:
    """Require lead or admin role."""
    if current_user.role not in ["admin", "lead"]:
        raise HTTPException(403, "Lead or admin access required")
    return current_user

3. Apply to Endpoints

Location: backend/app/api/v1/endpoints/team_members.py

from app.api.deps import get_current_user, get_current_lead_or_admin

@router.get("/team-members")
async def get_team_members():
    """Public endpoint - no auth required."""
    ...

@router.post("/admin/team-members")
async def create_team_member(
    data: TeamMemberCreate,
    current_user: User = Depends(get_current_lead_or_admin)
):
    """Lead or admin can create team members."""
    ...

@router.delete("/admin/team-members/{id}")
async def delete_team_member(
    id: UUID,
    current_user: User = Depends(get_current_admin)
):
    """Only admin can delete."""
    ...

4. Resource-Level Permissions

# Check if user can modify specific resource
async def can_modify_resource(
    user: User,
    resource_id: UUID,
    db: Session
) -> bool:
    """Check if user can modify resource."""
    if user.role == "admin":
        return True  # Admin can modify anything

    # Lead can only modify their own resources
    if user.role == "lead":
        resource = await crud.resource.get(db, id=resource_id)
        return resource and resource.created_by == user.id

    return False  # Members cannot modify

Frontend Authorization

Location: frontend/src/hooks/useAuth.ts

export const useAuth = () => {
  const { user } = useContext(AuthContext)

  const hasRole = (...roles: string[]) => {
    return user && roles.includes(user.role)
  }

  const isAdmin = () => hasRole('admin')
  const isLead = () => hasRole('lead', 'admin')
  const isMember = () => hasRole('member', 'lead', 'admin')

  return {
    user,
    hasRole,
    isAdmin,
    isLead,
    isMember
  }
}

Usage in Components:

const { isAdmin, isLead } = useAuth()

return (
  <div>
    {isLead() && (
      <Button onClick={handleEdit}>Edit</Button>
    )}

    {isAdmin() && (
      <Button onClick={handleDelete}>Delete</Button>
    )}
  </div>
)

Testing

def test_admin_can_delete(client, admin_token):
    response = client.delete(
        "/api/v1/admin/team-members/123",
        headers={"Authorization": f"Bearer {admin_token}"}
    )
    assert response.status_code == 204

def test_lead_cannot_delete(client, lead_token):
    response = client.delete(
        "/api/v1/admin/team-members/123",
        headers={"Authorization": f"Bearer {lead_token}"}
    )
    assert response.status_code == 403

def test_member_cannot_access_admin(client, member_token):
    response = client.get(
        "/api/v1/admin/dashboard",
        headers={"Authorization": f"Bearer {member_token}"}
    )
    assert response.status_code == 403

Report

✅ RBAC implemented with 3 roles ✅ Permission middleware created ✅ Endpoints protected by role ✅ Frontend authorization hooks added ✅ Tests passing