Zendesk API seems not to be working with OpenID Connect | Community
Skip to main content

Zendesk API seems not to be working with OpenID Connect

  • April 9, 2024
  • 5 replies
  • 0 views

Our application is using Auth0 to authenticate users. We configured Zendesk Application in our Auth0 account and it is working when end users log in with the sign-in link inside Zendesk.

 

Now, however, we are trying to contact Zendesk API from third party application with the same exact OIDC client information used by Zendesk. Users of our application should have access to their Zendesk tickets via Zendesk Request API (https://developer.zendesk.com/api-reference/ticketing/tickets/ticket-requests/). However, when user signs in our application, which in return sends request to Zendesk Request API along with the bearer, the Request API gives 401 Unauthorized response with the following error:

"error": "invalid_token",
“error_description": "The access token provided is expired, revoked, malformed or invalid for other reasons."

We have also tried to test this direct call to the Request API with Postman by using following configurations:
       - Authorization type: OAuth 2.0

  - Grant type: Authorization Code (with PKCE)

  - Callback URL: URL from the Auth0 Zendesk application

  - Auth URL: OAuth Authorization URL from the Auth0 Zendesk application

  - Access token URL: OAuth Token URL from the Auth0 Zendesk application

  - Client ID: ClientID from Auth0 Zendesk application

  - Client secret: Empty

  - Scope: “openid email”

  - Client authentication: “Send client credentials in body”

  - Auth request query parameters: “audience”

  

We also tried the same without PKCE and client id and secret. It gives the same problem.

 

With this Postman configuration we manage to get new access token, but using it in request to Zendesk Request API we get the same error as before in our application:

"error": "invalid_token",
“error_description": "The access token provided is expired, revoked, malformed or invalid for other reasons."

Note that the same configuration works when we login to Zendesk portal itself. 

 

Our access token payload looks like this:

{
 "iss": "https://[OUR_AUTH0_SUBDOMAIN].eu.auth0.com/",
 "sub": "auth0|[AUTH0_USER_ID]",
 "aud": [
   "[OUR_INTERNAL_AUDIENCE]",
   "https://[OUR_AUTH0_SUBDOMAIN].eu.auth0.com/userinfo"
 ],
 "iat": 1712656741,
 "exp": 1712657641,
 "scope": "openid email",
 "azp": "3FySxa06Fsf8ODU8WqyidSp3d2PTEwi9"
}

 

Our id token payload looks like this:

{
 "email": "[USER_EMAIL]",
 "email_verified": true,
 "iss": "https://[OUR_AUTH0_SUBDOMAIN].eu.auth0.com/",
 "aud": "3FySxa06Fsf8ODU8WqyidSp3d2PTEwi9",
 "iat": 1712656598,
 "exp": 1712692598,
 "sub": "auth0|[AUTH0_USER_ID]",
 "sid": "BJfNIHC8ivg8CR7Yi8Dpoq1hfWR-nYbE"
}

According to jwt.io both tokens are valid and signature is verified.

 

Is the Zendesk API out of the scope of OpenID Connect EAP or is there something more we need to do? 

5 replies

Caroline13

Hey Jukka, it sounds like you're trying to use OIDC to as a way to authenticate your API calls? That's not something we support, nor something that I even considered to be honest so thanks for bringing it up. What's the benefit to using OIDC here?


  • Author
  • April 17, 2024

Hi Caroline! Our use case is that we want the end users to be able to see and create tickets in our application developed by third party (outside of the normal Zendesk UI) that uses Auth0 for end user management. For creating and listing the tickets we are planning to use the Request API. The documentation in https://developer.zendesk.com/api-reference/ticketing/tickets/ticket-requests/ says following:

A request is an end user's perspective on a ticket. End users can only see public comments and certain fields of a ticket. Use this API to let end users view, update, and create tickets they have access to.

So correct me if I am wrong, but this is probably the endpoint we need to use for our end users to create and see their tickets from third party solutions. Moreover, the code examples give following example of the authentication:

curl https://{subdomain}.zendesk.com/api/v2/requests.json -d '{"request": {"subject": "Help!", "comment": {"body": "My printer is on fire!", "uploads": [...] }}}' -v -u {email_address}:{password} -X POST -H "Content-Type: application/json"

And here we hit a problem. Let me emphasis the problem:

-u {email_address}:{password}

We do not have the users password as only Auth0 knows that. And even if we would ask the users password separately from the user (which would break all the reasons we have protocols like OpenID Connect in the first place both from security and UX perspective), Zendesk would not know whether or not it is correct because, again, only Auth0 knows if the password is correct or not. And as you said, there is no way of the API to connect to Auth0, at least via OpenID Connect.

So to me it seems like the Zendesk API is designed from the point of view that either you use Zendesk internal login system (where Zendesk keeps all users and their passwords) or you do not use the API at all. Basically we would need to have separate login for our own applications via Auth0 and then have user register and login into Zendesk via separate login window inside a system, where the user is already logged in. This is not how SSO should work. In nowadays world this is supreme let-down from UX perspective.

What the Zendesk API should, in my opinion, be doing is acting as resource server (https://www.oauth.com/oauth2-servers/the-resource-server/) that just accepts a valid token, authorizes the user for certain Zendesk entities and then serves the request or declines the request if authorization fails. This would mean that if the user already has a valid authentication token in one application with correct scopes, the Zendesk API should accept it and serve the requests.

The current EAP OpenID Connect implementation is okayish as it lets our users to sign in using with the same protocol as rest of our application is using (previously with SAML the user needed to input their credentials when they went to the Zendesk portal from our platform). But at the same time it is subpar as it does not utilize the whole potential of the standard. The real power of OpenID Connect (compared to for example SAML) comes from the fact that it enables third parties to develop a single application towards as many API's as they want without having the user login million times. And right now our application is unable to reach this potential benefit as the Zendesk API does not support this use case.

As good and customizable as the Zendesk UI is, it is not enough for the companies that want to build a platform where the whole experience is streamlined from beginning to end. For this we need fully functioning API's, starting from the authentication.


Caroline13

While the documentation does indeed show an example where the authentication happens using email/password - it's still possible for you to use an API token for this authentication. Your backend system can make an API request with the end user's Auth0 information and create the ticket on their behalf. But your point is still valid that it'd be simpler and seamless if we accepted the token for the full workflow. Appreciate you bringing up this use case. 


  • Author
  • May 2, 2024

Hi Caroline and thanks for your response! If this is possible, could you send us an example on how this is achieved?

We have tried everything to no avail and I double checked just now that it does not work at least in the way it is usually done. I even added email to the access token separately just to check if the API works differently from the UI. I have tried with both ID token and Access token in authorization header.

Our access token looks like:

{
 "email": "[MY_EMAIL]",
 "iss": "[OUR_ISSUER]",
 "sub": "auth0|[IAM_ID]",
 "aud": [
   "[OUR_INTERNAL_AUDIENCE]",
   "https://[OUR_DOMAIN]/userinfo"
 ],
 "iat": 1714656020,
 "exp": 1714656920,
 "scope": "openid email",
 "azp": "3FySxa06Fsf8ODU8WqyidSp3d2PTEwi9"
}

I have also tried Access token without the email. Nothing changes.

Our id token looks like this:

{
 "email": "[MY_EMAIL]",
 "email_verified": true,
 "iss": "[MY_EMAIL]",
 "aud": "[AUDIENCE]",
 "iat": 1714656020,
 "exp": 1714692020,
 "sub": "auth0|[IAM ID]",
 "sid": "FD3a9DdFQk9vT8qNb5EXIVTroQMtYS4d"
}

Both tokens have correct signature. The same client information that we use to fetch these tokens work on the UI side.

I have tried this out with both Postman and Curl. This is my Curl command:

curl https://[OUR_SUBDOMAIN].zendesk.com/api/v2/requests.json 
-d '{"request": {"subject": "Help!", "comment": {"body": "My printer is on fire!"}}}' 
-v -X POST -H "Content-Type: application/json" 
-H "Authorization: Bearer [MY_ACCESS_TOKEN]"

The result is always the same:

{
"error":"invalid_token",
"error_description":"The access token provided is expired, revoked, 
malformed or invalid for other reasons."
}

What are we doing wrong?


Caroline13

I don't have specific documentation with examples on how to achieve this, but I hope the below will help.  Let me know if I've understood you correctly. 

 

To show a user's Zendesk tickets inside a third-party app (using Auth0 as the IdP) there's two options as I understand it;

  1. Have your backend server make an authenticated API request to https://subdomain.zendesk.com/api/v2/requests using the email address of the authenticated user (which you know because the user authenticated via Auth0). Use the following request with an API or OAuth token and the user's email address to only retrieve their specific tickets, such as: curl https://{subdomain}.zendesk.com/api/v2/requests.json -v -u {enduser_email_address}/token:{api_key}
  2. Do the same thing in step 1, but use any of our other APIs to retrieve the tickets, such as curl https://{subdomain}.zendesk.com/api/v2/users/{user_id}/tickets/requested -v -u {admin_email_address}/token:{api_key} and in this case since you're are specifying the user_id you can make the request with any admin user's email address.