Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
Stentone
Contributor II
Contributor II

Permission Denied When Exporting and Downloading App

I am attempting to set up an OAuth client that can be used to programmatically export and download an app from a shared space via the Qlik Cloud REST API.

I am successfully able to run the export POST request, "https://<tenant>.<region>.qlikcloud.com/api/v1/apps/<appId>/export",  and receive the location header specifying a temp-contents ID. However, when I try to get the file from temp-contents endpoint via GET "https://<tenant>.<region>.qlikcloud.com/api/v1/temp-contents/<id>", I receive a response with a "404 Not Found" status with the following body:

{
    "traceId": "a5075a43661a3dde6633722c7ed6e8b5",
    "errors": [
        {
            "code": "TCS-012",
            "title": "Unable to retrieve metadata",
            "detail": "Metadata can't be retrieved",
            "meta": {
                "locale": "en-US",
                "errorType": "Error",
                "sourceErrors": "permission denied"
            }
        }
    ]
}

While it is returning a 404 error, the body's message suggests the client does not have sufficient permissions. I get the same error when trying the "/temp-contents/<id>/details" endpoint.

The client has the 'Analyzer' entitlement with the 'Tenant Admin' role. It is of type 'Web', has the M2M option checked, and has the trusted consent method. 

It has access to the 'admin.apps:export' and 'admin.apps:read' scopes as well as the "Can view" and "Can edit" space permissions in the shared space that the app I'm trying to export resides. I've also tried different combinations of space permissions and OAuth scopes to no avail.

My testing workflow has been to retrieve a token via "https://<tenant>.<region>.qlikcloud.com/oauth/token" with the previously mentioned scopes and use that to authenticate for the export and temp-contents requests.

Am I missing something here? Is there a way that I can debug and evaluate permissions for this, or view what's available in the temporary content service?

Any help would be appreciated!

Labels (2)
4 Replies
wow0609
Contributor II
Contributor II

We have the same issue.  We initially went about it a different way outlined in this post: https://community.qlik.com/t5/Security-Governance/Qlik-Embed-Chart-Table-ExportData-throws-quot-Acce...

But got no responses.  In the meantime, we rewrote the export/download logic to follow your example above.

What is interesting is that this works for us in the Microsoft EDGE browser, but fails with the TCS-012: Permission Denied, Metadata can't be retrieved message.

 

So, if any Qlik folks can chime in here, or if the OP has found a solution, we are all ears!

 

DaveChannon
Employee
Employee

@Stentone does it work if you use the same OAuth token for both requests? And does it work if the OAuth client has the admin_classic scope?

Stentone
Contributor II
Contributor II
Author

Hey @DaveChannon, I am using the same OAuth token for both requests when the error comes up. Since then, however, I've been able to get it to work by either providing the 'admin_classic' scope (as you mentioned) or the 'user_default' scope.

The combination of scopes that I am currently using and are working are the following:

  • user_default
  • spaces.shared:read
  • spaces.managed:read
  • spaces.data:read

I've kept everything else, space permissions and the like mentioned in the original post, the same.

I'd like to follow the suggestions in the documentation to avoid the use of 'user_default' and 'admin_classic' in favor of least privilege principles, but it seems at least one of the two, from my experience, is required. I am open to trying other configurations if you have suggestions though!

Stentone
Contributor II
Contributor II
Author

Hey @wow0609 , thanks for your response. I feel a bit better that someone else has ran into the same issue. I did eventually get it to work which I mention in my previous response to Dave, but I'll highlight again what worked for me if you'd like to replicate it.

Basically this combination of scopes, and keeping all the other configurations like space permissions the same as my original post, is what does it for me:

  • user_default
  • spaces.shared:read
  • spaces.managed:read
  • spaces.data:read

It's not my favorite solution since it uses 'user_default', but it gets the job done.