HumanSignal/label-studio · error · PermissionDenied
You do not have permission to create storages for this proje
Error message
You do not have permission to create storages for this project.
What it means
DRF PermissionDenied raised in ImportStorageListAPI.perform_create when the authenticated user lacks access to the project referenced in the request payload. Label Studio checks project.has_permission(user) before allowing a storage to be attached, so storages cannot be created for projects the user is not a member of (or lacks storages_create permission on).
Source
Thrown at label_studio/io_storages/api.py:51
project_pk = self.request.query_params.get('project')
if not project_pk:
raise ValidationError('query parameter "project" is required')
project = generics.get_object_or_404(Project, pk=project_pk)
self.check_object_permissions(self.request, project)
StorageClass = self.serializer_class.Meta.model
storages = StorageClass.objects.filter(project_id=project.id)
# check failed jobs and sync their statuses
StorageClass.ensure_storage_statuses(storages)
return storages
def perform_create(self, serializer):
from rest_framework.exceptions import PermissionDenied
project = serializer.validated_data.get('project')
if project is not None and not project.has_permission(self.request.user):
raise PermissionDenied('You do not have permission to create storages for this project.')
super().perform_create(serializer)
class ImportStorageDetailAPI(generics.RetrieveUpdateDestroyAPIView):
"""RUD storage by pk specified in URL"""
permission_required = ViewClassPermission(
GET=all_permissions.storages_view,
PATCH=all_permissions.storages_change,
PUT=all_permissions.storages_change,
DELETE=all_permissions.storages_change,
)
parser_classes = (JSONParser, FormParser, MultiPartParser)
serializer_class = ImportStorageSerializer
@extend_schema(exclude=True)
def put(self, request, *args, **kwargs):
return super(ImportStorageDetailAPI, self).put(request, *args, **kwargs)View on GitHub (pinned to 0b49e9b539)
Solutions
- Log in as (or use a token for) a user who is a member of the target project with storage create permission
- Verify the 'project' id in the request body matches a project in the same organization as the token
- Grant the user a role with storages_create permission (admin/owner) on the project
- Check organization membership of the API token via /api/current-user/whoami
Example fix
// before
curl -X POST /api/storages/s3/ -H "Authorization: Token <user-without-access>" -d '{"project": 5, ...}'
// after
curl -X POST /api/storages/s3/ -H "Authorization: Token <project-admin-token>" -d '{"project": 5, ...}' Defensive patterns
Strategy: validation
Validate before calling
import requests
# Check membership/permissions before POSTing a storage
r = requests.get(f"{LS_URL}/api/projects/{project_id}/", headers={"Authorization": f"Token {token}"})
if r.status_code == 404 or not r.ok:
raise PermissionError(f"No access to project {project_id}") Type guard
def can_access_project(resp):
return resp.status_code == 200 Try / catch
try:
resp = requests.post(f"{LS_URL}/api/storages/s3/", json=payload, headers=headers)
resp.raise_for_status()
except requests.HTTPError as e:
if resp.status_code == 403:
# switch to a token with storages_create permission
... Prevention
- Use an admin/owner token for storage management automation
- Confirm token's organization matches the project's organization
- Check the user's role before attempting storage CRUD
- Document which service accounts have storage permissions
When it happens
Trigger: POST to an import storage list endpoint (e.g. /api/storages/<type>/) with body containing a 'project' id for a project the requesting user cannot access; project passes a valid pk but has_permission returns False (not a project member, restricted role, or anonymous token).
Common situations: Using a service/account token that belongs to a different organization than the project; sharing a project id between workspaces; a user downgraded from admin/owner to reviewer/annotator attempting to attach S3/GCS/Azure storage.
Related errors
- Action is not allowed for the current user: {action_id}
- PermissionDenied
- You can delete members only for your current active organiza
- Add or Update Columns is not enabled for this organization.
- LOCK_PERMISSION_MESSAGE
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/d800176f4728f93b.
Report an issue: GitHub.