{"record":{"id":"caa4fead8c5fb33d","repo":"langflow-ai/langflow","slug":"superuser-required-to-administer-teams","errorCode":null,"errorMessage":"Superuser required to administer teams.","messagePattern":"Superuser required to administer teams\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"src/backend/base/langflow/api/v1/authz_teams.py","lineNumber":46,"sourceCode":"from langflow.services.authorization.invalidation import (\n    safe_invalidate_all,\n    safe_invalidate_user,\n)\nfrom langflow.services.authorization.utils import audit_decision\nfrom langflow.services.database.models.auth import AuthzTeam, AuthzTeamMember\nfrom langflow.services.database.models.user.model import User\nfrom langflow.services.deps import get_authorization_service\n\nrouter = APIRouter(prefix=\"/authz/teams\", tags=[\"Authorization\"])\n\n# See ``authz_roles._LIST_MAX_LIMIT`` — same bound, applied to teams + members.\n_LIST_MAX_LIMIT = 200\n_LIST_DEFAULT_LIMIT = 100\n\n\ndef _require_superuser(user) -> None:\n    if not getattr(user, \"is_superuser\", False):\n        raise HTTPException(\n            status_code=status.HTTP_403_FORBIDDEN,\n            detail=\"Superuser required to administer teams.\",\n        )\n\n\n# --- teams ---------------------------------------------------------------- #\n\n\n@router.get(\"\", response_model=list[TeamRead])\n@router.get(\"/\", response_model=list[TeamRead])\nasync def list_teams(\n    session: DbSession,\n    current_user: CurrentActiveUser,  # noqa: ARG001 — any authenticated user can list\n    search: Annotated[str | None, Query(description=\"Substring match on team_name or adom_name\")] = None,\n    is_active: Annotated[bool | None, Query()] = None,\n    limit: Annotated[int, Query(ge=1, le=_LIST_MAX_LIMIT)] = _LIST_DEFAULT_LIMIT,\n    offset: Annotated[int, Query(ge=0)] = 0,\n) -> list[TeamRead]:","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_teams.py#L28-L64","documentation":"Raised by every route on /api/v1/authz/teams via _require_superuser when the authenticated user has is_superuser=False. The entire team administration API (list/create/update/delete teams and members) is superuser-only in OSS Langflow; there is no per-team admin grant.","triggerScenarios":"Any call to /api/v1/authz/teams* (GET, POST, PATCH, DELETE, member operations) as a regular non-superuser account.","commonSituations":"Logging in as a normal user and pointing admin UI at the teams endpoints; service accounts not flagged superuser; assuming workspace/project admin rights grant team administration (they do not).","solutions":["Authenticate as a user with is_superuser=true (the Langflow superuser/admin account)","If using a service account for team provisioning, ensure it is flagged superuser in the DB","Hide team-management UI for non-superusers to avoid the 403 entirely"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function requireSuperuser() {\n  const me = await getCurrentUser();\n  if (!me.is_superuser) throw new Error('teams API requires a superuser account');\n  return me;\n}","typeGuard":"const isSuperuser = (u: {is_superuser?: boolean} | null): boolean =>\n  !!u?.is_superuser;","tryCatchPattern":null,"preventionTips":["Gate all /authz/teams UI behind a superuser check on the current user","Provision service accounts used for team management with is_superuser=true"],"tags":["authz","api","teams","forbidden","superuser","rbac"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}