{"record":{"id":"fbb6371f7550dbb8","repo":"getredash/redash","slug":"you-don-t-have-permission-to-edit-this-resource","errorCode":null,"errorMessage":"You don't have permission to edit this resource.","messagePattern":"You don't have permission to edit this resource\\.","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"redash/permissions.py","lineNumber":109,"sourceCode":"    return require_permission(\"super_admin\")(fn)\n\n\ndef has_permission_or_owner(permission, object_owner_id):\n    return int(object_owner_id) == current_user.id or current_user.has_permission(permission)\n\n\ndef is_admin_or_owner(object_owner_id):\n    return has_permission_or_owner(\"admin\", object_owner_id)\n\n\ndef require_permission_or_owner(permission, object_owner_id):\n    if not has_permission_or_owner(permission, object_owner_id):\n        abort(403)\n\n\ndef require_admin_or_owner(object_owner_id):\n    if not is_admin_or_owner(object_owner_id):\n        abort(403, message=\"You don't have permission to edit this resource.\")\n\n\ndef can_modify(obj, user):\n    return is_admin_or_owner(obj.user_id) or user.has_access(obj, ACCESS_TYPE_MODIFY)\n\n\ndef require_object_modify_permission(obj, user):\n    if not can_modify(obj, user):\n        abort(403)\n","sourceCodeStart":91,"sourceCodeEnd":119,"githubUrl":"https://github.com/getredash/redash/blob/ca79fe988d81cdac9675b412f3dfcab107bc1fbc/redash/permissions.py#L91-L119","documentation":"Thrown by redash.permissions.require_admin_or_owner when the caller is neither an admin of the organization nor the owner of the target resource. Many user-resource endpoints (e.g. deleting or editing another user's objects) call this guard, and it aborts with HTTP 403 before the handler body runs.","triggerScenarios":"Calling an admin-or-owner-protected endpoint such as POST/DELETE on a user resource while authenticated as a non-admin user whose id differs from object_owner_id; e.g. user A deleting user B, or a viewer-tier API key hitting an edit endpoint.","commonSituations":"Sharing a service account API key with limited permissions across scripts; frontends leaking edit/delete buttons to non-admins; org members attempting to manage teammates' resources after permission changes removed their admin status.","solutions":["Perform the operation as the resource owner or with an admin account/API key","Have an admin grant the caller the needed permission on the object (e.g. modify access) if the code path supports can_modify","Hide/disable edit/delete actions in the client for users who are neither owner nor admin"],"exampleFix":"# before\nrequests.delete(f\"{url}/api/users/{other_uid}/resources/{rid}\", headers=limited_hdrs)  # 403\n# after\nrequests.delete(f\"{url}/api/users/{other_uid}/resources/{rid}\", headers=admin_hdrs)","handlingStrategy":"validation","validationCode":"session = requests.get(f\"{url}/api/session\", headers=hdrs).json()\nuser = session.get(\"user\", {})\nis_admin_or_owner = any(g.get(\"type\") == \"admin\" for g in session.get(\"user\", {}).get(\"groups\", [])) or user.get(\"id\") == target_owner_id\nif not is_admin_or_owner:\n    raise PermissionError(\"caller is neither admin nor owner\")","typeGuard":"def can_manage(session_user, owner_id):\n    return session_user[\"id\"] == owner_id or \"admin\" in session_user.get(\"group_ids\", ())","tryCatchPattern":null,"preventionTips":["Gate edit/delete UI actions on ownership or admin status before sending requests","Use the principle of least privilege: give scripts keys scoped to what they actually need","Centralize permission checks client-side to avoid scattered 403 handling"],"tags":["redash","authorization","http-403","permissions","access-control"],"backgroundTag":"permission-denied-403","analyzedSha":"ca79fe988d81cdac9675b412f3dfcab107bc1fbc","analyzedAt":"2026-08-28T18:32:34.637Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}