Forum Discussion

g3kuser's avatar
g3kuser
Helper II
1 year ago
Solved

Fabric APIs from notebook using SPN auth

Hi,   I need to call Fabric APIs from notebook to get workspace, items and create shortcuts but getting following error just for shortcut creation.  'errorCode': 'InsufficientScopes', 'message': '...
  • Anonymous's avatar
    Anonymous
    1 year ago

    Hi g3kuser ,

     

    As you're building a generic framework that should work for both named users and SPNs, but you're hitting limitations where:
     
    >>Direct use of ClientSecretCredential works for SPNs.
    >>mssparkutils.credentials.getToken(...) does not work for some endpoints (e.g., shortcut creation, connections) under SPN context.
     
    Cause for the issue might be,
                       The token retrieved using mssparkutils.credentials.getToken(...) does not always include all required scopes — particularly for application-level permissions used by SPNs. It's likely retrieving a user-delegated token, or a token with limited/default scopes.
     
    This mismatch causes InsufficientScopes errors on more privileged Fabric APIs like:
    *POST /v1/workspaces/{workspaceId}/shortcuts
    *GET /v1/connections
     
    These often require app-level roles and proper access tokens issued via the client credentials flow.
    We can suggest that,
    Since you want a framework-agnostic approach, here’s how you can proceed:
     
    **Differentiate Named User vs SPN Execution
    Use this logic to detect if the notebook is running under a user or an SPN:
    try:
        user = mssparkutils.env.getUserName()
        is_spn = False
    except:
        is_spn = True
     
    else, you can check the structure of the returned token or decode the JWT to see if it’s an app (SPN) or user principal.
    Split Authentication Flow Dynamically
    if is_spn:
        # Use explicit credential (ClientSecretCredential) for SPN
        credential = ClientSecretCredential(tenant_id=tenant_id, client_id=client_id, client_secret=client_secret)
        access_token = credential.get_token(scope)
        token_string = access_token.token
    else:
        # Use mssparkutils for user context
        token_string = mssparkutils.credentials.getToken("https://api.fabric.microsoft.com/.default")
    This ensures the right token with correct scopes is used based on the execution context.
     
    If these workarounds don't help you,
    I suggest reaching out to Microsoft Support by raising a ticket. Microsoft will analyze backend logs and provide a resolution
     
    Below is the link to create Microsoft support ticket:
     
    If this post helps, then please consider Accepting as solution to help the other members find it more quickly, don't forget to give a "Kudos" – I’d truly appreciate it!

    Regards,
    B Manikanteswara Reddy