{"record":{"id":"663cf5a3d8a3d1e6","repo":"langflow-ai/langflow","slug":"only-the-resource-owner-or-a-superuser-may-adminis","errorCode":null,"errorMessage":"Only the resource owner or a superuser may administer shares for this resource.","messagePattern":"Only the resource owner or a superuser may administer shares for this resource\\.","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"error","filePath":"src/backend/base/langflow/api/v1/authz_shares.py","lineNumber":196,"sourceCode":"    owner_id: UUID | None,\n) -> None:\n    \"\"\"Require resource owner or superuser unless cross-user enforcement is active.\"\"\"\n    if getattr(user, \"is_superuser\", False):\n        return\n    if owner_id is not None and owner_id == user.id:\n        return\n    authz = get_authorization_service()\n    if await authz.supports_cross_user_fetch() and await authz.is_enabled():\n        # Why: in OSS, ``supports_cross_user_fetch()`` is False (see\n        # LangflowAuthorizationService), so this early-return is dead and the\n        # explicit 403 below is the floor. When an authorization plugin signals\n        # cross-user fetch support, the plugin is the authoritative gate via\n        # the ``ensure_share_permission()`` call that every share route makes\n        # immediately after this helper. Removing that downstream call — or\n        # weakening the plugin's cross-user fetch contract — REOPENS the\n        # ownership gap. Keep the two in lockstep.\n        return\n    raise HTTPException(\n        status_code=status.HTTP_403_FORBIDDEN,\n        detail=\"Only the resource owner or a superuser may administer shares for this resource.\",\n    )\n\n\n@router.post(\"\", response_model=ShareRead, status_code=status.HTTP_201_CREATED)\n@router.post(\"/\", response_model=ShareRead, status_code=status.HTTP_201_CREATED)\nasync def create_share(\n    payload: ShareCreate,\n    current_user: CurrentActiveUser,\n    session: DbSession,\n) -> ShareRead:\n    \"\"\"Create an authz_share row for a resource.\"\"\"\n    owner_id = await _resolve_resource_owner(\n        session,\n        resource_type=payload.resource_type,\n        resource_id=payload.resource_id,\n    )","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/authz_shares.py#L178-L214","documentation":"Raised by _ensure_can_administer_share in the /api/v1/authz/shares routes — the OSS ownership floor. If the caller is neither the resource owner nor a superuser and no cross-user-fetch-capable authorization plugin is active, share administration is refused with 403. When a plugin signals supports_cross_user_fetch() AND is_enabled(), this floor is bypassed and the plugin's ensure_share_permission() becomes the authoritative gate.","triggerScenarios":"POST/PATCH/DELETE /api/v1/authz/shares/{id} (or POST /authz/shares) as a non-owner, non-superuser while running the OSS pass-through authorization service (LANGFLOW_AUTHZ_ENABLED=false or no plugin registered).","commonSituations":"Team admin trying to manage another user's shares on OSS Langflow (no plugin installed); enabling LANGFLOW_AUTHZ_ENABLED=true but expecting it to widen share administration — without a registered plugin the floor stays; scripts using service accounts that are not superusers.","solutions":["Perform share administration as the resource owner or as a superuser","Install/register an authorization plugin via the lfx.services entry point (authorization_service) that sets SUPPORTS_CROSS_USER_FETCH=True and grants share permissions","Do not attempt to bypass the floor — it exists so the OSS pass-through cannot let a non-owner mint share rows"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function canAdministerShares(user, ownerId) {\n  return user.is_superuser || user.id === ownerId;\n}","typeGuard":"const canAdminShares = (u: {id: string; is_superuser: boolean}, ownerId: string): boolean =>\n  u.is_superuser || u.id === ownerId;","tryCatchPattern":null,"preventionTips":["On OSS (no authz plugin), only build share-management UI for the owner or superuser","Do not expect LANGFLOW_AUTHZ_ENABLED=true alone to widen share administration — a registered plugin is required"],"tags":["authz","api","shares","forbidden","oss-floor","ownership"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}