Single sign-on is a mechanism that allows you to authenticate users in your systems and subsequently tell Zendesk that the user has been authenticated. If you use single sign-on with JWT, a user is automatically verified with the identity provider when they sign in. The user is then allowed to access Zendesk without being prompted to enter separate sign-in credentials.
At the core of single sign-on is a security mechanism that allows Zendesk to trust the sign-in requests it gets from your systems. Zendesk only grants access to the users who have been authenticated by you. Zendesk SSO relies on a technology called JSON Web Token (JWT) for securing the exchange of user authentication data.
The IT team in a company is usually responsible for setting up and managing the company's JWT authentication system. Their role is to implement SSO for Zendesk on the system. Refer the team to the following topic in this article:
Related articles:
How JWT SSO for Zendesk works
Once you enable SSO, sign-in requests are routed to a sign-in page external to Zendesk Support.
Steps of the JWT SSO authentication process:
- An unauthenticated user navigates to your Zendesk Support URL. Example: https://yoursubdomain.zendesk.com/.
- The Zendesk SSO mechanism recognizes that SSO is enabled and that the user is not authenticated.
- Zendesk redirects the user to your organization's remote sign-in page. Example: https://mycompany.com/zendesk/sso.
- A script on the remote server authenticates the user using your organization's proprietary sign-in process.
- The authentication system builds a JWT request that contains the relevant user data.
- The authentication system redirects the user to the following Zendesk endpoint with the JWT payload:
https://yoursubdomain.zendesk.com/access/jwt
- Zendesk parses the user detail from the JWT payload and then grants the user a session.
As you can see, this process relies on browser redirects and passing signed messages using JWT. The redirects happen entirely in the browser and there is no direct connection between Zendesk and your systems, so you can keep your authentication scripts safely behind your corporate firewall.
Requirements for enabling JWT SSO
- The remote login URL where Zendesk users should be redirected when they attempt to access Zendesk
- (Optional) The remote logout URL where Zendesk can redirect users after they sign out of Zendesk
- (Optional) A list of IP ranges to redirect users to the appropriate sign-in option. Users making requests from the specified IP ranges are routed to the remote JWT authentication sign-in form. Users making requests from IP addresses outside the ranges are routed to the normal Zendesk sign-in form. If you don't specify a range, all users are redirected to the remote authentication sign-in form.
Confirm with the team that any Zendesk-bound traffic is over HTTPS, not HTTP.
Next, enter the information in Support to enable single sign-on. See Enabling JWT SSO.
The IT team may require additional information from Zendesk to configure the SAML implementation. Refer them to the Technical implementation worksheet in this article.
Enabling JWT SSO
You can enable JWT single sign-on only for end users, only for agents (staff members), or for both groups. If you're using both JWT and SAML, you need to select one as the primary authentication method. When signing into Zendesk, users will redirected to your primary sign-in page. Users can sign in with the secondary method by going to the secondary sign-in page. For details, see Using different SAML and JWT SSO (single sign-on) for agents and end users.
You must sign in to Zendesk Support as an administrator to enable JWT single sign-on.
To enable JWT single sign-on
- In any product, click the Zendesk Products icon (
) in the top bar, then select Admin Center.
- Click the Security icon (
) in the left sidebar, then click the Single sign-on tab.
- For JSON Web token, click Configure.
- For Remote Login URL, enter the URL where your users should be redirected when they attempt to access your Zendesk URL.
Zendesk automatically adds a brand_id parameter to the URL. This is the Zendesk Support brand the user was on when they attempted to sign in.
- For Remote Logout URL, enter the URL that Zendesk will return your users to after they sign out.
Zendesk automatically adds email, external_id, and brand_id parameters to the URL. If you prefer not having email and external id information in the URL, specify blank parameters in the logout URL. Example:
https://www.xyz.com/user/signout/?email=&external_id=
Note: If you're using an Ember.js application, you need to amend the logout URL to use blanked parameters before the hash. For example,https://somedomain.com/?brand_id=&return_to=&email=#/zendesk-login/
. - (Optional) For IP ranges, enter a list of IP ranges if you want to redirect users to the appropriate sign-in option.
Users making requests from the specified IP ranges are routed to the JWT authentication sign-in form. Users making requests from IP addresses outside the ranges are routed to the normal Zendesk sign-in form. Don't specify a range if you want all users to be redirected to the JWT authentication sign-in form.
- If you use external IDs for your users, you can update these in Zendesk Support by selecting On for Update of external ids?.
- Provide the Shared secret to your IT team. They'll need it in their JWT implementation.
Important: Keep the shared secret safe. If it's compromised, all the data in your Support account is at risk.
- Once your JWT SSO configuration is set, click Enabled so you can assign this option to users.
- Click Save.
Assigning JWT SSO to users
- In Admin Center, click the Staff members or End users tab and select the External authentication option.
- Select JSON Web Token as the Single sign-on (SSO) option in the External authentication section.
- If you want all users to only use a single sign-on method, deselect the Zendesk authentication option.
Any Zendesk passwords will be permanently deleted from the account within 24 hours.
- If you disabled Zendesk passwords, select the menu option that specifies whether only the account owner or admins (which includes the account owner) can be granted access to the account in case the sign-in provider does down.
To gain access, the account owner or an admin requests to receive an email containing an one-time access link. Clicking the link grants the person access to the account. No password is required. See Accessing the account if passwords are disabled.
- Click Save.
Managing users in Zendesk after enabling JWT SSO
After enabling JWT single sign-on in Zendesk, changes made to users outside Zendesk sync to your Zendesk account. For example, if a user is added to your internal system, the user is automatically added to your Zendesk account. If a user is deleted in your internal system, the user will no longer be able to sign in to Zendesk However, their account will still exist in Zendesk.
By default, the only user data stored in Zendesk when single-sign on is enabled is the user's name and email address. Zendesk does not store passwords. As a result, you should disable any automated email notifications from Zendesk about passwords. See Disabling password notification emails from Zendesk.
To provide a better customer experience, you might want to store more than just the user's name and email address in Zendesk. See Obtaining additional user data.
Generating a new shared secret
In some cases, you may need to issue a new JWT shared secret and provide it to your IT team. For example, if the secret is compromised. You can generate a new JWT shared secret from Zendesk Admin Center by disabling your JWT configuration and then reenabling it. This action will create a new secret and invalidate the old one.
To generate a new shared secret:
- In any product, click the Zendesk Products icon (
) in the top bar, then select Admin Center.
- Click the Security icon (
) in the left sidebar, then click the Single sign-on tab.
- For JSON Web token, click Edit.
Your current JSON Web token configuration appears.
- Deselect the Enabled checkbox.
- Save your changes.
- Click Configure next to JSON Web token to reopen the configuration.
You should see a new Shared secret in plain text at the bottom of the configuration page.
- Make a copy of the new shared secret to give it to your IT team.
- Click Enabled to reenable the configuration with the new shared secret.
- Save your changes.
Switching authentication methods
Additional information about JWT
JWT is a recent open standard that is being driven by the international standards body IETF and has top-level backers from the technology sector (for example, Microsoft, Facebook, and Google).
The fundamental building blocks of JWT are very well understood components and the result of this is a fairly simple spec, which is available here http://tools.ietf.org/html/draft-jones-json-web-token-10. There are a lot of open source implementations of the JWT spec that cover most modern technologies. This means that you can get JWT single sign-on set up without much difficulty.
One thing to be aware of is that the JWT payload is merely encoded and signed, not encrypted, so don't put any sensitive data in the hash table. JWT works by serializing the JSON that is being transmitted to a string. It then base 64 encodes that string and then makes an HMAC of the base 64 string which depends on the shared secret. This produces a signature that the recipient side can use to validate the user.
Technical implementation worksheet
This section is for the team in the company responsible for the company's JWT authentication system. It provides details about the Zendesk JWT SSO implementation.
Topics covered:
JWT algorithm
Specify HS256 as the JWT algorithm in the header of your JWT payload:
{
"typ":"JWT",
"alg":"HS256"
}
HS256 stands for HMAC SHA 256, a 256-bit encryption algorithm designed by the U.S. National Security Agency.
Zendesk JWT endpoint
After successfully authenticating the user, redirect the user along with the JWT payload to the following Zendesk endpoint:
https://yoursubdomain.zendesk.com/access/jwt
The payload should be base64-encoded and appended to the URL as a query string.
The JWT payload must be sent to your Zendesk Support subdomain using the https protocol. Example:
https://yoursubdmain.zendesk.com/access/jwt?jwt={payload}
Host-mapped subdomains are not supported.
JWT attributes
Send attributes to Zendesk as a base64-encoded hash (Ruby) or dictionary (Python). Example using Ruby:
payload = JWT.encode({
:email => "bob@example.com", :name => "Bob", :iat => Time.now.to_i, :jti => rand(2<<64).to_s
}, "Our shared secret")
Zendesk requires an email address to uniquely identify the user. Beyond the required attributes listed in the table below, you may optionally send additional user profile data. This data is synced between your user management system and Zendesk Support.
Attribute | Required | Description |
---|---|---|
iat | Yes | Issued At. The time the token was generated, this is used to help ensure that a given token gets used shortly after it's generated. The value must be the number of seconds since UNIX epoch. Zendesk allows up to three minutes clock skew, so make sure to configure NTP or similar on your servers. |
jti | Yes | JSON Web Token ID. A unique id for the token, used by Zendesk to prevent token replay attacks. |
Yes | Email of the user being signed in, used to uniquely identify the user record in Zendesk Support. | |
name | Yes | The name of this user. The user in Zendesk Support will be created or updated in accordance with this. |
external_id | No | If your users are uniquely identified by something other than an email address, and their email addresses are subject to change, send the unique id from your system. Specify the id as a string. |
locale (for end-users)
locale_id (for agents) |
No | The locale in Zendesk Support, specified as a number. |
organization | No | The name of an organization to add the user to. Note: If the option End-users can belong to multiple organizations is enabled, additional organizations append the original organization, and are considered secondary organizations. This does not delete the existing memberships.
If you'd like to pass multiple organizations at the same time, use the organizations attribute instead. The organizations need to be passed in a string, separated by commas. |
organization_id | No | The organization's external ID in the Zendesk API. If both organization and organization_id are supplied, organization is ignored. Note: If the option End-users can belong to multiple organizations is enabled, additional organizations append the original organization, and are considered secondary organizations. This does not delete the existing memberships.
|
phone | No | A phone number, specified as a string. |
tags | No | This is a JSON array of tags to set on the user. These tags will replace any other tags that may exist in the user's profile. |
remote_photo_url | No | URL for a photo to set on the user profile. |
role | No | The user's role. Can be set to "user", "agent", or "admin". Default is "user". If the user's role is different than it is in Zendesk Support, the role is changed in Zendesk Support. |
custom_role_id | No | Applicable only if the role of the user is agent. |
user_fields | No |
A JSON hash of custom user field key and values to set on the user. The custom user field must exist in order to set the field value. Each custom user field is identified by its field key found in the user fields admin settings. The format of date values is yyyy-mm-dd. If a custom user field key or value is invalid, updating the field will fail silently and the user will still log in successfully. For more information about custom user fields, see Adding custom fields to users.
Note: Sending null values in the the user_fields attribute will remove any existing values in the corresponding fields.
|
Remote login URL parameter (return_to)
When Zendesk redirects a user to your remote login page, it also passes a return_to URL parameter. The parameter contains the page that Zendesk will return the user after your system has authenticated the user. Append the parameter (name and value) to the Zendesk JWT endpoint.
For example, suppose an agent who is signed out clicks the following link to open a ticket in Support: https://mycompany.zendesk.com/tickets/1232. The flow is as follows:
- On click, Zendesk redirects the user to your remote login URL and appends the following
return_to
parameter to the URL:https://mycompany.com/zendesk/sso?return_to=https://mycompany.zendesk.com/tickets/123
- Your authentication system takes the
return_to
parameter (name and value) from the URL and, after successfully authenticating the user, appends it to the Zendesk JWT endpoint. Example:https://mycompany.zendesk.com/access/jwt?jwt=payload&return_to=https://mycompany.zendesk.com/tickets/123
- Zendesk uses the parameter to open the ticket page for the agent.
The return_to
parameter is an absolute URL for the agent interface, and a relative one for Help Center.
Whether you pass in the return_to
parameter or not is optional, but we recommend it for the best user experience.
return_to
address contains its own URL parameters, make sure that your script URI-encodes the entire return_to value when submitting the JWT token.Error handling
If Zendesk encounters an error while processing a JWT login request, it sends a message that explains the issue. If you specified a remote logout URL when you configured the JWT integration, it redirects to that URL and passes a message and a kind parameter. In case of error, the kind parameter always has the value "error". Zendesk recommends specifying a remote logout URL, as well as logging messages from Zendesk alongside the type. Most of the errors that can happen are ones that you'll want to fix. Examples: clock drifts, rate limits being hit, invalid tokens, and so on.
JWT implementation code examples
The actual JWT implementation is straightforward and most modern languages have libraries that support it. Zendesk provides a series of examples for various stacks in the following JWT SSO GitHub repository:
If you implement JWT in any other stack, we would love to feature an example of that there as well. Add a comment to this article to share what you've implemented.
In case you run IIS/AD and don't want to build your own .NET solution, we provide a full implementation in classic ASP, which requires you to adjust only a couple of variables. Download the ASP authentication script from this page on Github: https://github.com/zendesk/zendesk_jwt_sso_examples/tree/master/bundles.
96 Comments
Hello,
I want to be able to display an account number passed through our JWT to our Help Center on ZenDesk. Is it possible to extract that information some way in the JS file, so that I can bind it to the homepage?
Regards,
Daras
Hi Daras - Welcome to The Community!
You can definitely pass information about your users to Zendesk using JWT. I would recommend a custom user field to store it.
I'd like to get a bit more information about your use case though, so I'm going to follow up with you in a ticket. Stay tuned!
Feature request: use expiration value when present in token ('exp'), so that token expiration can be extended.
As far as I can tell, there is only a 3 minute window as it is currently implemented.
Hi Charles,
Thanks for sharing your feedback!
I also recommend cross-posting in our Developer Feature Request forum to help gauge interest from other users as well as provide visibility to the appropriate team :)
Your feedback is greatly appreciated :)
We want to enable JWT SSO for end-users. Does this mean that the user will be registered automatically registered Zendesk when he creates an account in our system, or just that the user will be recognized as already verified (by our system) when login to Zendesk?
Hi Pedro,
When the unauthenticated user attempts to access Zendesk resources requiring login (e.g. tickets, restricted HC content etc.) they’ll be redirected to your system. Your system will be responsible for evaluating the user’s legitimacy via a login/active session and sending the user back to Zendesk with JWT payload. If that payload is successful, it will then create a user in ZD for the user if one hasn’t already been created.
Let me know if you have additional questions for me.
Thanks!
Thanks Brett!
Happy to help Pedro :)
We want to do logout in my webpage while zendesk also logout ,But I couldn't find a demo ,Please tell me how to achieve it
Same thing here as Q LIU - can we remotely log out the active session in Zendesk when users log out from our web page? How?
https://support.zendesk.com/hc/en-us/community/posts/203432866-SSO-force-logout-previous-session
Same problem is described here too, without any answers.
Hi Jonas and Q,
With a custom script you could detect the user ID and delete the active session.
https://developer.zendesk.com/rest_api/docs/support/sessions#delete-session
Alternatively, visiting {subdomain}.zendesk.com/access/logout does the same thing. You could add this as part of your users logout flow to accomplish the same result.
Hello!
The authentication system on my end requires a bit of information about the user to present them the proper login page. Is there a way that I could tokenize the login url in Zendesk to send this information along with the login request?
Something like...
I send a link to a user like:
mycompany.zendesk.com/tickets/123?userinfo=something
They aren't already authenticated so they get redirected to
myloginpage.com?return_to=mycompany.zendesk.com/tickets/123&userinfo=something
Is anything like this possible, or would you have any examples of how other users have navigated around this issue?
When using JWT SSO where we are adding and managing users external from Zendesk, is it possible when a new user is added via our web application, that we can suppress the email that Zendesk sends out to the user asking them to click a link to set a password (and authenticates their email)? Our own web application does this already.
Hey Andrew,
If you disable both checkboxes and remove the text under User welcome email text and Email verification email text does that suppress the emails being sent out to your end-users? I've attached a screenshot below:
If the emails continue being delivered let me know and we can dig into this a bit further.
Cheers!
@Brett
Thanks for the response, but I forgot to give a couple pieces of key info that will likely change your recommended solution.
1. We are mulitbrand in Zendesk. We want to suppress these emails for only one brand.
2. We are using SSO, but only on one brand (at this time). The SSO script that Zendesk points to, will check the referrer and direct our first brand customers to the 'backdoor' login of /access/normal while the new second brand customers are logging in via our SSO. It is the second brand with the SSO that we want to suppress the emails for.
Hey Andrew,
I'm afraid these settings are account wide so you wouldn't be able to toggle off for one brand while leaving another brand activated. One of the limitations of multibranding is that only login configuration can be set up for each account. This will include the welcome emails that are sent out when an account is created.
More information on multibrand limitations can be found here: Multibrand known issues
I wish I was able to provide another alternative for you but I'm afraid one does not exist at this time :-/
After configuring the JWT of SSO, I can't go to the homepage of the management desk to process the work order. Why? How do I get to the admin desk homepage?
Hello Shaodong,
I would recommend navigating to subdomain.zendesk.com/agent, if you can get into through this link then you are running into an SSO issue. If this is the case then I would recommend reaching out your developers to resolve this. Also, be sure to replace subdomain w/ your subdomain.
Hello!
I'm curious what takes precedence with regards to Organizations: if we send an Organization ID as part of the SSO JWT when creating a user, but have also enabled the email domain automation (adding specific domains to organizations with the expectation that users having those domains will automatically be added to that organization), which determines the Organization of that user?
Hey there Annie,
This is a very good question. However, it's a question that has a few different answers depending on how you're setting this up. If your end-user's are verified upon creation, and you have multiple orgs off for end-users, email mapping should take precedence.
We'd recommend using one over the other if possible so you don't run into any issues. However, there are certain factors we cannot account for since JWT is a pretty customized aspect. If you're wanting further clarity I would recommend sending in a support ticket to support@zendesk.com with your JWT payload information.
I hope this helps!
I seem to be having a problem with the JWT Active Directory integration that Zendesk has provided, you can see the article here https://support.zendesk.com/hc/en-us/articles/203663856-Configure-Zendesk-for-your-Active-Directory-Microsoft-environment
I am currently getting the following error
The supplied iat value is more than 3 minutes off, check your server clock.
When I set the JWT plugin to debug mode I am presented with the IAT attribute that is being sent, placing that in an Epoch time converter shows that the time being sent to the Zendesk servers are identical to what the NTP time servers are presenting as the current time.
Anyone experience and solved this issue?
C# example-
//JWT uses Unix epoch in seconds
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
int timestamp = (int)t.TotalSeconds;
payload = new Dictionary<string, object>() {
{ "iat", timestamp },
{ "jti", System.Guid.NewGuid().ToString() },
{"tags", aryTags },
{ "name", username },
{ "email", useremail }
};
Hi, I have a question about the security issues in this SSO method. Our pen tests identified a security vulnerability that can lead to a session hijacking attack because the JWT is passed as a query string param in the URI. This means that the session token can be stolen from browser history, server logs, etc...
In RFC6750, we have the following quote:
"Don't pass bearer tokens in page URLs: Bearer tokens SHOULD NOT be passed in page URLs (for example, as query string parameters).
Instead, bearer tokens SHOULD be passed in HTTP message headers or message bodies for which confidentiality measures are taken.
Browsers, web servers, and other software may not adequately secure URLs in the browser history, web server logs, and other data structures. If bearer tokens are passed in page URLs, attackers might be able to steal them from the history data, logs, or other unsecured locations."
That's a big deal for our compliance standards. Do you have any considerations about this?
Thanks!
Emerson -- not speaking for Zendesk, of course, but while it would be preferable for the JWT to be in a header, the risk is substantially mitigated by the presence of the timestamp. Zendesk only allows the timestamp to be off by 3 minutes, so a hijacker would need to obtain and use the URL within that time.
Hello,
I am having a CORS Issue with JWT SSO. We are multibrand on Zendesk and have branded login pages for our site. Our process is as follows
1. when the user accesses a resource on Zendesk they are redirected to the default sso logon https://www.mysite.com/zendesk/login?brand_id=xxxxx...
2. We extract the brand ID and retrieve the brand data(cached) via the API and then redirect to the specific brand login page with additional fields appended to the URL
3. Our login form is generated and then on submission is POSTED to our session manager. If a session is successfully created we build the JWT package and redirect back to the zendesk URL., for example: using the sandbox we would redirect to:
https://mysite1576179182.zendesk.com/access/jwt?jwt=eyJ0eXAiOiJ.......SnyA&return_to=https://mysite1576179182.zendesk.com/agent/admin/tickets
we get the following errors:
(url) has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
How can we resolve this is Issue?
Thanks,
Hey Garfield,
It looks like you have a ticket open with our Customer Advocacy team regarding this issue.
We will continue working with you there to get this resolved.
Cheers!
Brett Bowser Thanks for the quick response. I will look forward to hearing from them. I didn't see a lot of posts in the forums on CORS errors with SSO so I assume its probably some mistake that I am making in the implementation
Thanks,
Hello,
We are getting an "Unknown error during sign-in" when signing in via SSO. One of our admins has a sandbox account that he was able to authenticate with using the normal login link and create a ticket with. Taking the link to the ticket https://<ourdomain>.zendesk.com/agent/tickets/383 and putting it into an icognito session redirected to our sso URL. He authenticated into our system using the same email address. Our system generated the JWT package and popped the /access/jwt url including the payload and return_to link. We receive the unknown error response on the UI and it redirects back to our login page.
When we attempt to login using another admin account, we get the same error, but with a third admin account it logs in correctly. I can give you more detail as well as the JWT package if needed. Admin level accounts should be able to view everything right?
Any thoughts on what could be happening?
Hey Garfield,
It looks like our team is still looking into this for you. You'll receive an update in the ticket to troubleshoot further.
Cheers!
Please add a link to the document which describes the numerical identifiers for the expected locales. I have searched for the identifiers but there is a confusion as that document describes them as strings which seems wrong.
Please sign in to leave a comment.