Some PDIs are currently unavailable, and PDI actions are paused. View the latest updates here. Read More

Astrid Sapphire
ServiceNow Employee

This is a cross-post of my article from https://sapphirenow.dev (https://sapphirenow.dev/post/wdc-oauth-part-1/). You can find the original and other articles I've written on this website, as well as a link to my YouTube channel where I occasionally post video content.

 

Up your OAuth2.0 Game in Washington DC with Inbound Client Credentials

This article and the following articles in the Up your OAuth2.0 series, will guide you through setting up different types of OAuth Clients and Providers, including extended concepts around OIDC and more! After the guide, I’ll also talk through brief cases of where you might use each variant.

Alongside implementing several inbound authentication flow features and improvements, ServiceNow has also implemented API Authentication Scopes in order to provide granular access to APIs through scope definitions. I’ll walk through an initial example in the guide, but this will likely warrant its own post at some point.

This first article focusses on Inbound API Authentication to your ServiceNow instance, using the Client Credentials grant which was implemented in the Washington DC release.

 

Guide:

This guide requires the user to have the admin role.

 

Preparing your instance:

There are two pre-requisites required to permit the client credentials flow in a Washington DC instance as of Early Access:

  1. Validate that the following four plugins are installed. This can be done by navigating to Admin -> Application Manager, or by navigating to sys_plugins.list using the Filter Navigator (UI15/16) or the Next Experience header menus, for example. Please install any that are not installed.
    • OAuth 2.0 (com.snc.platform.security.oauth)
    • REST API Provider (com.glide.rest)
    • Authentication scope (com.glide.auth.scope)
    • REST API Auth Scope Plugin (com.glide.rest.auth.scope)
    • Note: In my Washington DC environment all four were already installed
  2. Navigate to the System Properties table and create or update the below property with the values listed. You can navigate to this table by navigating to sys_properties.list using the same method as above.
    • Name: glide.oauth.inbound.client.credential.grant_type.enabled
    • Value: true
    • Type: true | false
    • Note: This flag is the primary mechanism for enabling and disabling this functionality

 

Creating an OAuth Client

You’ll now create a client and make an update to the OAuth Entity default view.

  1. Navigate to System OAuth -> Application Registry. Create a new record, selecting Create an OAuth API endpoint for external clients from the interceptor list. Populate mandatory fields as you need. Save this record (or submit and return to the form).
    • Note: Redirect URL and Login URL are not required as they are not used by this grant type
    • Note: Do not set Public Client to true, as RFC 6749, Section 4.4 indicates only confidential clients should use this flow. Section 2.1 of the same document defines client types.
  2. Using the context menu button indicated by the icon (or secondary/right click on the header bar), open the context menu and open Configure -> Form Builder (Form Design and Layout will also work). Add the existing OAuth Application User reference field to the ‘Default’ view, and save this change.
  3. Populate the newly-available OAuth Application User with an appropriately permissioned user, and save the record.
 
AstridSapphire_2-1707220700541.png
An example of an OAuth Client after Step 3

At this point, you are now able to request an Access Token from the /oauth_token.do endpoint of the instance you created this in. You’ll note that this is a Bearer token, and will have no scopes.

 

Granting and creating scopes

The final piece of the puzzle is granting authorisation scopes to your OAuth Entity. As in the past, the default useraccount scope remains available, and this scope continues to permit the full scope of permissions afforded to a user profile.

As an alternative, ServiceNow has now implemented API Authentication Scopes. These are similar to the existing API Access Policies in format, but their intent is to form a relationship between an API, such as platform or bespoke scripted REST APIs, and a scope. This allows you to limit which APIs your OAuth Client has access to, and can be used elsewhere as well. This is a big step forward in API governance and control, and I’m eager to see how this feature gets adopted.

To set up a new authentication scope, you can take the following steps:

  1. Navigate to sys_auth_scope.list using the methods described above. Create a new record, specifying a name and description in line with the purpose of your scope. For example, this could be ‘interaction_closer`. Save this record.
  2. Navigate to System Web Services -> API Auth Scopes -> REST API Auth Scope and create a new record, specifying a name, the Auth Scope you created in step 1, and a REST API. In my example, I’m implementing a scope to control access to only the Interaction Management API close resource, so I would set ‘Apply auth scope to all resources in this API’ to false, and select the ‘/now/interaction/{interaction_id}/close’ resource.
 
AstridSapphire_3-1707220747370.png
An example of an API Auth Scope after Step 2

This scope can now be applied to OAuth Clients, and its absence will block clients that do not have it from leveraging the resource in question. Ensure when implementing that you are aware of the breadth of use of your APIs, as this will be applied indescriminately as per your configuration. Disabling or deleting the REST API Auth Scope will allow you to restore the previous experience.

 

When to use Client Credentials?

The client credentials grant is designed for cases where the ‘client’ making the connection to ServiceNow is also the ‘resource owner’. This is most commonly the case for ServiceNow system-to-system integrations, where the authentication is not happening on behalf of an alternative ‘resource owner’, often a user. JWT bearer grants were supported and able to do this in the past, but client credentials now presents an alternative for situations wherein the JWT bearer grant may not be available, or is otherwise deemed unsuitable for your use case.

 

Closing notes

I hope this article gives you a bit of insight into the steps required to get a client credentials grant up and running in your ServiceNow instance. I think the real jewel in the crown here is the API Auth Scopes, which is an awesome maturity step.

 

Thank you for reading, and I hope you enjoyed/found value in this article. As always, I am open to feedback and can be reached here, as well as via Slack, LinkedIn, or email.

16 Comments
pavan9885
Kilo Sage

what make difference apart from giving the right permissions for the webservice user with all the required authentication access for the tables does this scope authentication changes any thing apart from scope 

chike_a
Tera Contributor

@pavan9885 @It’s a bit nuanced, but some big differences are that the user accounts you want to use for system-to-system integration no longer have to be local ServiceNow accounts with local passwords (e.g. you can now tie the App Reg to a user account imported from LDAP). And you no longer have to use the Resource Password grant flow, which is now considered outdated and was the only option for inbound system-to-system authentication (besides JWT or OIDC). 

Masa29
Tera Contributor

Does anybody find this working? I followed this article to set up the OAuth Client (Create an OAuth API endpoint for external clients), and the OAuth Application User is my user name. I can get the access token from Postman, but when I call a rest api using the access token, I get 401 "User Not Authenticated" error.  If I check the token in oauth_credential, it is created by "guest". I think that's why the 401 error.

Niclas
Tera Guru

Finally this is there, as legacy Ressource Owner Password grant type shall not be used anymore according to OAuth 2.0 Security Best Practices

 

But when I trying to connect via Postman to get the Access Token as described in KB1645212 it always returns access_denied. What am I missing?

 

API Response for Token: 

 

 

{
    "error_description": "access_denied",
    "error": "server_error"
}

 

 
Setup of my App Registry:
Niclas_0-1719562217924.png

 

 
Setup of the System Property:
Niclas_1-1719562269006.png

 

hustler
Giga Explorer

Not working for us as well. Getting same server_error and access_denied.

Malaravan S
Tera Explorer

I had the same issue, fixed by adding Bearer<token>. 'B' is caps.  Try it & let me know

Martin Ivanov
Giga Sage

@Malaravan S Where do you add this. Please give a little bit more info.

Astrid Sapphire
ServiceNow Employee

Hi folks,

I've written a follow up article detailing how to use this, which you can find at on my blog, SapphireNow: https://sapphirenow.dev/post/oauth-part-2/.

 

I'm keen to incorporate any issues or troubleshooting people are coming across, so please keep the feedback coming here or over at the SNDevs slack!

PawelW
Tera Contributor

It is not working.

Moritz4
Tera Contributor

Hi @Astrid Sapphire,

 

thank you very much for that article. It helps a lot to get started with the OAuth 2.0 client credentials grant.

I'm thrilled to see that this has been recently added to the ServiceNow platform.

 

I'm wondering if you have more insights whether this also works with an external IDP like Okta, EntraID or similar? After my research and try-outs, I have the feeling that this is only possible if we use ServiceNow as the IDP.

 

I'm looking forward to hear your thoughts on that.

 

Best regards

Moritz