langflow-ai/langflow · error · HTTPException

Superuser required to administer roles.

Error message

Superuser required to administer roles.

What it means

Superuser gate on the role-administration routes under /api/v1/authz/roles (create/update/delete; list and read are open to any authenticated user). A non-superuser calling a mutating role route gets HTTP 403 'Superuser required to administer roles.'

Source

Thrown at src/backend/base/langflow/api/v1/authz_roles.py:37

    safe_invalidate_role,
)
from langflow.services.authorization.utils import audit_decision
from langflow.services.database.models.auth import AuthzRole, AuthzRoleAssignment
from langflow.services.deps import get_authorization_service

router = APIRouter(prefix="/authz/roles", tags=["Authorization"])

# Match ``authz_shares``: cap any single list call so an authenticated client
# (or a buggy frontend) can't enumerate the entire role/team catalog in one
# request. 100 default / 200 max is enough for typical UI dropdowns.
_LIST_MAX_LIMIT = 200
_LIST_DEFAULT_LIMIT = 100


def _require_superuser(user) -> None:
    """Superuser-only gate. Role admin is an operations action."""
    if not getattr(user, "is_superuser", False):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Superuser required to administer roles.",
        )


async def _detect_parent_cycle(
    session: DbSession,
    *,
    role_id: UUID,
    proposed_parent_id: UUID,
) -> bool:
    """Walk the parent chain from ``proposed_parent_id``; True if ``role_id`` appears.

    Used to reject ``PATCH`` requests that would set a role as its own ancestor.
    Walks at most ``len(all_roles)`` steps so a pre-existing cycle terminates.
    """
    visited: set[UUID] = set()
    cursor: UUID | None = proposed_parent_id

View on GitHub (pinned to 976ec789d2)

Solutions

  1. Use the seed superuser credentials (LANGFLOW_SUPERUSER env vars) to obtain the token for role admin
  2. Restrict the role-management UI to superusers so the 403 never fires in production
  3. Verify is_superuser on the /api/v1/users/whoami response before showing admin controls
Defensive patterns

Strategy: validation

Validate before calling

const me = await api.get('/users/whoami');
if (!me.is_superuser) disableRoleAdminUI();

Type guard

const canAdminRoles = (u: { is_superuser?: boolean } | null): boolean =>
  Boolean(u?.is_superuser);

Try / catch

catch (e) { if (e.status === 403) notify('Superuser required'); return; }

Prevention

When it happens

Trigger: POST/PATCH/DELETE /api/v1/authz/roles* with a token whose user has is_superuser=False. Listing (GET '') and reading a single role (GET /{role_id}) do not hit this, only the mutations do.

Common situations: Frontends that show the role-admin UI to all logged-in users, scripts authenticated as a normal workspace user, or forgetting to switch tokens when moving from read-only inspection to role editing.

Related errors


AI-assisted analysis of langflow-ai/langflow@976ec789d2 (2026-08-14). Data as JSON: /api/errors/245342e9b57915d4. Report an issue: GitHub.