OAuth Grant_Type=Client_Credentials or Get Access Without a User

  • 18 February 2021
  • 9 replies

Hello All,

I've read through most all posts in this board relevant to OAuth ~/restapi/oauth/authorize and ~/restapi/oauth/token Authentication methods.

My use-case is germane to AppType Webserver and Other Non-UI. Generally speaking, our code (that engages the RingAPIs) may be triggered by various events. None of these have a Ring User context which is required to support grant_type=password.

The primary constraint we have, any OAuth grant_type method that requires Ring User/login ID/PWD/Ext/Phone# does not work when SSO is enabled for user logins. This means we can only use grant_type=authorization_code.

For us, auth_code means a SAML Assertion. It also means a Ring User/login is required, and we're back to - there is no Ring User context, only the registered Ring App context.

The example shown in Authentication Your Application - Is the in-body grant_type=password(+credentials) actually required?

If not, that example should work perfectly - but it doesn't. Are we missing something?

Microsoft provides a detailed how-to for this use-case, appropriately named "Get access without a user" :)

9 replies

First of all, please respect to the company brand name. If you don't want to write the full name RingCentral, use RC instead. Ring is a different company and it does not mean RingCentral.

The SSO constraint is a company's security policy. If the SSO is enabled and also allow login with RingCentral credentials, then you still can use password flow to login. But if the SSO setting disabled login with RingCentral credentials, then you can't use password flow. However, this will impact all users under the account, meaning that you cannot turn on/off for a particular extension.

We have a plan to release a new feature to allow disabling SSO on the user extension level. It will be supported soon (hopefully during Q2).

The sample you showed with the link is about getting an access token. You can get an access token by either authenticating using password flow or OAuth.

Hello @PhongVu, My apologies re: improper use of Ring vs. RingCentral/RC. No disrespect intended, won't happen again.

We were not considering turning off SSO for select RC User logins. Although the future feature you outlined may have utility for us given specific use-cases.

The use-case I'm attempting to outline (not so well I guess :-), is system-to-system with no RC User/Extension context. The Create App options Webserver and Other non-UI are germane to our need.

However, both of those Create App options setup API access such that an RC User login is required. E.g. An active Login with an extension and username (username=email in our Account). Either to obtain the Authorization token (~/restapi/oauth/authorize) or obtain an Access Token (~/restapi/oauth/token) it appears a username/password (RC Login) is required.

One of our developers implemented our app using Python/Selenium. Selenium handles the user login to AzureAD, collects a SAML Assertion (our user-SSO IdP), plays that Assertion to RC as code= for an Access Token.

We still see the common constraint with the Selenium approach. An RC User login (extension + username/email) is required (translation, an RC User License is required).

The question still standing:

How does an app running unattended, with no RC user-context, access RC APIs with only its application-context (Client-ID and Client-Secret from Create App in RC)?

Of Note:

The APIs accessed in this use-case are Call Logs (Read Only) and Call Queues (Read Only).
All Call Logs are fetched & pumped into a DataLake for detailed reporting/analytics.

We do realize some RC API features/functions do require an RC User login/context. Those are outside the scope of this use-case.

Thanks in advance!

Unfortunately, RingCentral platform always requires user's authentication. The access token is granted per user and will be used to identify and allow who accesses what features based on user permissions (role).

The app client id and app client secret are for defining the scope of an application. E.g. you can build an app for just sending and receiving SMS, so you need to set the SMS permission for that app.

Now, each user who logs in will get an access token to perform send/read SMS from it's own phone numbers. The access token of this user cannot be used to access other users' SMS service.

For your use case (The APIs accessed in this use-case are Call Logs (Read Only) and Call Queues (Read Only)), you or your customer (if this app is built for another RingCentral customer) need to create a helper extension, create a custom role (user permissions) for this helper extension accordingly (See example screenshot) and then use that user's login credentials to authenticate.


Thank you @Phong Vu

This is making a bit more sense now. FYI ... the apps we're building are strictly for internal use.

Is "Helper Extension" the same thing as "Limited User"? I don't find reference to Helper Extension anywhere. If they are different, a pointer for how to set them up would be great.

In our case, "login credentials" takes the form of a SAML Assertion, (SSO is enabled). In the Developers Guide > Using Auth Tokens > Authenticating Your Application to Obtain an Access Token, I see this:

POST /restapi/oauth/token HTTP/1.1
Authorization: Basic WW91ckFwcEtleTpZb3VyQXBwU2VjcmV0
Content-Type: application/x-www-form-urlencoded;charset=UTF-8


Would a SAML Assertion go into the grant_type something like


Now we can setup an app in our OAuth services to issue an Auth_Code (~/restapi/oauth/authorize) for RC's ~/restapi/oauth/token ingesting. It would use the ClientID/ClientSecret as registered in RC's OAuth and could include the username/password pair of the helper extension (or limited user).

If OAuth ~/authorize & ~/token must be done in RC's OAuth services, please let us know how to frame a SAML Assertion to either submit to ~/authorize or ~/token.

Since SAML is an assertion of authenticated user/application, I'm assuming the submit would be to ~/token.

Looking forward to you thoughts.


Sorry for the delayed response.

Saying "Helper Extension" I meant just an extra user extension w/o number and phone. It's just an extension that you can setup a username and password and set the role to read company call log etc. Of course you can choose any existing extension but that user you must use that user's login credentials to use your app.

Your app type should be a Web server app.


And you have to implement OAuth authorization to login. It would be much easier to show you how to implement it if you use one of the RingCentral's SDKs.

G'Day @Phong Vu

We are selecting AppType = Webserver.

I now understand that all/any use of RC APIs requires an RC login(username)/extension.

I tend to agree, use of vendor's SDKs to hide code complexities is a good thing :). The developer implementing (coding) our app (pulls call-logs into a DataLake) is using Python. He has the RC Python SDK.

Remembering our RingCentral Account/tenant has SAML/SSO enabled (AzureAD is our IdP).

>> How do we use a SAML Assertion (valid RC username/extension) in the Authorization Code Flow?

Reviewing Authenticating Your Application to Obtain an Access Token

>> This appears to be the applicable method to use. It implements a pipeline of AuthN/AuthZ & returns an Access Token in one call (with no user/person interaction).

>> Though grant_type=password would seem to conflict with our SAML/SSO enabled (Password Flow).

Greatly appreciate your help!

Remembering our RingCentral Account/tenant has SAML/SSO enabled (AzureAD is our IdP).

>> How do we use a SAML Assertion (valid RC username/extension) in the Authorization Code Flow?

No, you don't always need the extension number. Just login with email address and password. When implementing the OAuth, the user will login via this


And you will receive the code via your defined redirectUri. Use the code to exchange for the access tokens.

@Phong Vu

Understand using "username" (which = email in RC). That is how people login today.

Our app is unattended code. It does not have a human user behind it to fill in or click WebUI forms.

I started with the https://login~ as in your example, tracing the flows in our environment. The following URL bypasses the RC SignOn form. We need to bypass all WebUI interactions where a human is expected to do something.

I see the SAML request sequence go though AOK

I see this next step in the trace sequence, converting the SAML Assertion into an OAuth Auth_Code.

POST with the SAMLResponse included.

Response to above includes the OAuth Auth_Code token (label = opentoken) and an action statement to POST opentoken to the URL:


>> This next step seen in the sequence capture is where we have issues.

GET {long-string}
302 Response

That ~/mobile/~ part in the above URL is where things break. Not clear where/how that is determined. Could it be derived from an RC user's profile? It's not in our IdP redirect URL (that's for the SAML part anyway)

>> I believe we need to POST the Auth_Code to ~/restapi/oauth/token as described in Step 4. Exchange code for token.

POST /restapi/oauth/token HTTP/1.1
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Basic cmVsLWFsbC1wZXJtaXNzaWXFjMmpRZmlQcnlkSUkweE92QQ==code=U0pDMTFQMDFQQVMwM XxBQUJfTVpHWk5lM29zNVFmWnNHQ01MSmJuMHJmNGlRcnRaeEptTWlPS0MzUTdYRDdSTURiaHBuWHZINGM2WTdqaWlBOE VhRHNxRWdJVUNYQjd4dmJsWHJoVVlWQVN2SFo2YWJPanJsRkFWZk9SMm5lek0tWnF5d3h8C3AnYOPxO0flEwO6Ffoq9Tl qs1s&grant_type=authorization_code&redirect_uri=

I assume this redirect_uri is the one configured in the RC App setup?


Not sure how you manage in this scenario to get the code. But once you get the code, you can use it to exchange for the access tokens. And yes, the redirect_uri is set in your app settings.