Skip to content

Forbidden error when client only has Site.Selected permission #9

@Hemario

Description

@Hemario

For security reasons, it was decided that the app registration only receives Site.Selected as permission.
As a result, the _get_site_id() (and the functions below) return a Forbidden error.

Calling code:

storage_options = {
        "client_id": client_id,
        "tenant_id": tenant_id,
        "client_secret": client_secret,
    }
fs = fsspec.filesystem("msgd", **storage_options)
print(fs.ls(f"{site_name}/Documents/POC"))

httpx.HTTPStatusError: Client error '403 Forbidden' for url 'https://graph.microsoft.com/v1.0/sites?search=$site_name'

Full stack trace:

HTTP error 403: b'{"error":{"code":"accessDenied","message":"Access denied","innerError":{"date":"2026-01-27T14:54:28","request-id":"$request_id","client-request-id":"$client_request_id"}}}'
Traceback (most recent call last):
  File "/home/AD/$USER/projects/$project/src/collab/fs.py", line 47, in <module>
    main()
    ~~~~^^
  File "/home/AD/$USER/projects/$project/src/collab/fs.py", line 37, in main
    print(fs.ls(f"<site-name>/Documents/POC"))
          ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/fsspec/asyn.py", line 118, in wrapper
    return sync(self.loop, func, *args, **kwargs)
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/fsspec/asyn.py", line 103, in sync
    raise return_result
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/fsspec/asyn.py", line 56, in _runner
    result[0] = await coro
                ^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 1796, in _ls
    return await drive_fs._ls(file_path, detail=detail, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 1793, in _ls
    return await super()._ls(file_path, detail=detail, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 761, in _ls
    url = await self._path_to_url_async(path, item_id=item_id, action="children")
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 1728, in _path_to_url_async
    await self._ensure_drive_id()
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 1686, in _ensure_drive_id
    site_id = await self._get_site_id()
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 1735, in _get_site_id
    response = await self._msgraph_get(url)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 573, in _msgraph_get
    return await self._call_msgraph("GET", url, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 562, in _call_msgraph
    return await _http_call_with_retry(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<4 lines>...
    )
    ^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 152, in wrapper
    raise e
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 144, in wrapper
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 183, in _http_call_with_retry
    raise e
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/msgraphfs/core.py", line 164, in _http_call_with_retry
    response.raise_for_status()
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/AD/$USER/.conda/envs/$project/lib/python3.13/site-packages/httpx/_models.py", line 829, in raise_for_status
    raise HTTPStatusError(message, request=request, response=self)
httpx.HTTPStatusError: Client error '403 Forbidden' for url 'https://graph.microsoft.com/v1.0/sites?search=$site_name'

Possible solutions:

  • Allow us to pass site_id in storage_options
  • Use a host_name + site_name combination, call GET https://graph.microsoft.com/v1.0/sites/<host_name>:/sites/<site_name> and parse the result

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions