BerriAI/litellm · error · HTTPException

You don't have access to this project

Error message

You don't have access to this project

What it means

Read access on project/info is broader than admin-only: the call passes if user_api_key_has_admin_view is true (proxy admin) OR the caller's user_id appears in the project team's members_with_roles (any membership role, not just admin). Otherwise the endpoint returns 403 'You don't have access to this project'.

Source

Thrown at enterprise/litellm_enterprise/proxy/management_endpoints/project_endpoints.py:886

                param="project_id",
            )

        # Check if user has access to this project (admin or team member)
        is_admin = user_api_key_has_admin_view(user_api_key_dict)
        is_team_member = False

        if project.team_id and user_api_key_dict.user_id:
            team = await _team_table(prisma_client).find_unique(where={"team_id": project.team_id})
            if team:
                caller_user_id = user_api_key_dict.user_id
                for m in team.members_with_roles or []:
                    m_user_id = m.get("user_id") if isinstance(m, dict) else getattr(m, "user_id", None)
                    if m_user_id == caller_user_id:
                        is_team_member = True
                        break

        if not (is_admin or is_team_member):
            raise HTTPException(
                status_code=403,
                detail={"error": "You don't have access to this project"},
            )

        return project
    except Exception as e:
        verbose_proxy_logger.exception(
            "litellm.proxy.management_endpoints.project_endpoints.project_info(): Exception occured - {}".format(str(e))
        )
        raise handle_exception_on_proxy(e)


@router.get(
    "/project/list",
    tags=["project management"],
    dependencies=[Depends(user_api_key_auth)],
    response_model=list[LiteLLM_ProjectTable],
)

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Use a proxy admin key for admin-view dashboards that must see every project
  2. Ensure the caller's user is a member of the project's team (add via /team/update) when they legitimately need visibility
  3. Treat 403 here as expected application logic — show a 'no access' state instead of retrying
  4. Verify the key carries a user_id (keys of pure service accounts without users can never pass the member check)

Example fix

# before (403: user not on the project's team)
httpx.get(base + '/project/info', headers=other_team_hdr, params={'project_id': 'p1'})

# after: either add the user to the team, or use an admin key
httpx.post(base + '/team/update', headers=admin_hdr, json={'team_id': 'team-a', 'members_with_roles': [{'role': 'member', 'user_id': 'user-9'}]})
httpx.get(base + '/project/info', headers=user_9_hdr, params={'project_id': 'p1'})
Defensive patterns

Strategy: try-catch

Try / catch

try:
    r = httpx.get(base + '/project/info', headers=hdr, params={'project_id': project_id})
    r.raise_for_status()
except httpx.HTTPStatusError as e:
    if e.response.status_code == 403 and "don't have access" in e.response.text:
        return render_no_access(project_id)  # expected tenancy boundary: never retry, never leak existence
    raise

Prevention

When it happens

Trigger: GET /project/info with a key whose user is not a proxy admin and not a member of the team stored on the project row — e.g. a user from another team or a key with no user context.

Common situations: Multi-tenant dashboards showing all projects to every logged-in user; service keys not tied to a user; users who left or were removed from a team still holding cached links to its projects.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/441e39dd5eb58c05. Report an issue: GitHub.