Authentication

Introduction

This document introduces the concepts of applying authentication protocols to Semantic Composition Language (SCL) based botlets built using the Microsoft Knowledge Graph Exchange. The examples described in some of the sections use OAuth protocol parameters that are specific to Microsoft.

If you intend on using authentication services from third-party companies, you must visit the third-party company’s website to obtain their authentication specific parameters. Once you’ve obtained these parameters, you can populate them in the fields in the Authentication menu tab of the Workspace.

If you want to authenticate a Microsoft BotFramework bot that is registered in the Workspace, refer to the section BotFramework Bot OAuth2 Configuration Settings for more details.

Framing and Background

Users expectations are shifting. We no longer live in a world where users expect or want their data to be encapsulated in an app or website. To help users get things done, efficiently and with less friction, services need to be able to seamlessly operate on both the public and private (user-specific) knowledge graphs.

Imagine your perfect personal assistant. It would know your family; have access to your email; makes sure you can get from point A to point B on time, but it would also help you manage all of your personal life: your shopping lists, sending meetings, planning events, buying gifts, and even sometimes, giving information and “act on behalf of” access to others that it knows you trust.

Traditionally, authentication happens between a user and a service, or in the case of OAuth, a user, a resource provider, and a 3rd party resource consumer. The user explicitly consents to trust both services. In the world of botlets, authentication may have to flow down a chain of botlets which may come from different sources. This flow should be transparent to the user while maintaining trust and control.

System Overview

alternate text

To securely invoke a 3rd party API that requires authentication, the botlet stores its 3rd party service credentials in an auth config inside of the botlet vault. This can be done through the Workspace or by using the SCL SAVE command. The runtime has built in support for OAuth2, OAuth1, and Username/Password through the CREATE_AUTH command.

CREATE_AUTH produces a $mst.auth.chain entity that is passed to botlets or services that need credentials. It first checks the User Vault, and if valid credentials are found, there will be a return immediately. Otherwise it will check the Botlet Vault for a valid auth configuration of type $mst.auth.oauth2.config, $mst.auth.oauth1.config or $mst.auth.user_password.config.

In case of OAuth, the authorization flow that directs the user to the 3rd party website will kick off. In case of username/password, the user will be asked for those. Once the user’s credentials are collected, they are stored in the User Vault and the $mst.auth.chain is returned.

The redirect URL for OAuth2 is: https://api.botletstore.com/callback/oauth2. This needs to be configured on the 3rd party OAuth2 provider’s developer website that also provides the Oauth2 client_id and client_secret.

Example:

SAY "GCa1 OAUTH2 Demo"
CREATE_AUTH "microsoft"
SAY "Got AUTH: ${AUTH.id, AUTH.owner_id, AUTH.credential_id, AUTH.domain}"
CALL "example.service", "gcal", auth=AUTH
SAY "Got next meeting: ${CALL_RESULT.to_json()}"
END

Creating Authentication Configurations on Botlets

The information that follows will guide you through the steps of using the Configs in Vault interface for creating the following configurations on botlets:

  • OAuth1
  • OAuth2
  • User Password
  • Botlet Secret
  • External OAuth2

To create authentication configurations on a botlet, refer to the steps below:

  1. In the Items Tree, click an Organization, and then select a botlet under it.
  2. In the Control Panel, click the Authentication menu tab.
  3. In the Configs in Vault, click Create a config.
alternate text
  1. Select a configuration in the list (e.g., OAuth1), and then click Add.
alternate text
  1. Complete all the required configuration fields, and then click Create (e.g., Create OAuth1 Config).
  2. Repeat steps 1 through 5 to create the other configuration (i.e., OAuth2).

The fields for each authentication configuration option are described in the following sections.

Editing Authentication Configurations on a Botlet

To edit authentication configurations on a botlet, refer to the high-level steps below. For this example, we are editing the OAuth2 configuration properties.

  1. In the Items Tree, click an Organization, and then select a botlet under it.
  2. In the Control Panel, click the Authentication menu tab.
  3. Click Edit in the list of Configs in Vault (e.g., OAuth2).
alternate text
  1. Update the configuration properties, and then click Update OAuth2 Config.
alternate text

Deleting Authentication Configurations on Botlets

To delete authentication configurations on a botlet, refer to the high-level steps below:

  1. In the Items Tree, click an Organization, and then select a botlet under it.
  2. In the Control Panel, click the Authentication menu tab.
  3. Click Delete in the list of Configs in Vault (e.g., OAuth2).
alternate text

OAuth1

The runtime has built in support for standard OAuth1. As a botlet developer, you can configure an OAuth1 provider, trigger an OAuth1 flow, generate an OAuth1 token, and a secret for a user of your botlet.

This information below provides details on how to configure an OAuth1 provider, how to use CREATE_AUTH to trigger OAuth1 flows, and how to pass and retrieve the generated credentials in your external service.

Triggering an OAuth1 Flow

Once an OAuth1 configuration is added, an OAuth1 flow can be triggered in SCL using CREATE_AUTH command. The following is an example of this usage:

CREATE_AUTH “microsoft” STORE creds

The above command will check the user vault to see if credentials from a previous OAuth1 flow already exists and if so, the “creds” will be populated with a reference to the credentials. If they do not exist, a new OAuth1 flow will be triggered and the user will be prompted with a URL that will allow approval and generation of the credentials.

Passing Credentials to External Services

The generated credentials from the above step can be passed to other botlets and external services. When the credentials are passed to external services, the runtime populates the reference with the generated OAuth1 user token and user secret.

Example

CALL “example.service”, “gcal”, auth=creds

In the above example, example.service is an external web service and “creds” are the generated reference in step 1 “Triggering an OAuth1 Flow.” When the call is made to the external service, the user token and user token secret are passed as attributes “token” and “token_secret”inside “data.auth.credentials” attribute in the POST body of the call.

OAuth1 Configuration Fields

To add an OAuth1 provider on a botlet, you must create an authentication configuration (i.e., OAuth1), you must complete all the required fields. Each of these fields are described below the image.

Note: If you are new to the OAuth1 specifications and require more detailed information, refer to the OAuth.net website.

alternate text

Name

This is a unique identifier used for your configuration in your SCL code.

Domain

This is an internal identifier for your OAuth1 provider. For example, if Microsoft is your OAuth1 provider, add www.microsoft.com in this field.

Consumer Key

The Consumer Key is from the OAuth1 provider. It is a value used by the consumer to identify itself to the service provider.

For more details about Consumer Keys and service providers, refer to section 4.2 of the OAuth Core Specification.

Consumer Secret

The Consumer Secret is from the OAuth1 provider. A secret used by the consumer to establish ownership of the consumer key.

For more details about the Consumer Secret, refer to section 4 of the OAuth Core Specification.

Request Token URL (URI)

The Request Token URL is from the OAuth1 provider. The URL is used to obtain an unauthorized request token.

For more details about the Request Token URL, refer to section 4.1 of the OAuth Core Specification.

Auth URL (URI)

The Auth URL (User Authorization URL) is from the OAuth1 provider. The URL is used to obtain user authorization for consumer access.

Access Token URL (URI)

The Access Token URL is from the OAuth1 provider. The URL is used to exchange the user-authorized request token for an access token.

The callback URL for the runtime is https://api.botletstore.com/callback/oauth1 and it needs to be configured at the OAuth provider.

OAuth2

The runtime has built in support for standard OAuth2. As with OAuth1, you can configure an OAuth2 provider, trigger an OAuth2 flow, and generate an OAuth2 access token for a user of your botlet.

This section provides details on how to configure an OAuth2 provider, how to use CREATE_AUTH to trigger OAuth2 flows, and how to pass and retrieve the generated credentials in your external service.

Adding an OAuth2 Provider

To add an OAuth2 provider on a botlet, you must create an authentication configuration (i.e., OAuth2), and you must complete all the required fields. Each of these fields are described in more details further below.

For more specific details regarding the purpose of these field, refer to the OAuth 2.0 Authorization Framework site RFC 6749.

Triggering an OAuth2 Flow

Once the configuration for an OAuth2 provider is added, an OAuth2 flow can be triggered in SCL using the CREATE_AUTH command.

The following is an example of this usage:

CREATE_AUTH “microsoft” STORE creds

The above command will check the user vault to see if the credentials from a previous OAuth2 flow already exists and if they do, the credentials will be populated with the reference to the credentials. If they do not exist, a new OAuth2 flow will be triggered and the user will be prompted with a URL that will allow approval and generation of the credentials.

Passing Credentials to External Services

The generated credentials from the above step can be passed to other botlets and external services. When the credentials are passed to external services, the runtime populates the reference with the generated OAuth2 access token.

Example

CALL “example.service”, “gcal”, auth=creds

In the above example, example.service is an external web service and “creds” are the generated reference from above. When the call is made to the external service, the access token is passed in an attribute “token” in data.auth.credentials attribute in the POST body of the call.

OAuth2 Configuration Field Descriptions

To add an OAuth2 provider on a botlet, you must create an authentication configuration (i.e., OAuth2), and you must complete all the required fields. Each of these fields are described below the image.

Note: If you are new to the OAuth2 specifications and require more detailed information, refer to the OAuth 2.0 Authorization Framework specification.

alternate text

Name

This is a unique identifier used for your configuration in your SCL code.

Domain

This is an internal identifier for your OAuth2 provider. For example, if Microsoft is your oauth2 provider, add www.microsoft.com in this field.

Client ID

The Client ID is from your OAuth2 provider. For more details about the Client ID, refer to section 2.2 of the OAuth 2.0 Authorization Framework.

Additional Information

The client ID is not a secret. It is exposed to the resource owner and must not be used alone for client authentication. The authorization server issues the registered client a client ID.

Client Secret

The Client Secret is from your OAuth2 provider. For more details about the Client Secret, refer to section 2.3.1 of the OAuth 2.0 Authorization Framework.

User Tenant Auth

Select this option if you want your botlet to authenticate with your own service that is hosted in Microsoft Azure and uses the Azure Active Directory (AAD). For more details on authorizing access to web applications using OAuth 2.0 and AAD, see OAuth2 and Microsoft Azure Active Directory Protocol.

Token URL

The Token URL is from your OAuth2 provider. For more details about the Token URL, refer to section 3.2 of the OAuth 2.0 Authorization Framework.

Auth URL (URI)

The Auth URL is from your OAuth2 provider. For more details about the Auth URL, refer to section 3.1 of the OAuth 2.0 Authorization Framework.

Redirect URL (URI)

The Redirect URL is an optional URL. The default redirect URL is:

https://api.botletstore.com/callback/oauth2

This URL needs to be added as the Redirect URL at the OAuth provider site. For more details about the Redirect URL, refer to section 3.2 of the OAuth 2.0 Authorization Framework.

Scope

The Scope is an optional field in that it specifies the level of access that the application being requesting for the OAuth flow.

For more details about the Scope, refer to section 3.3 of the OAuth 2.0 Authorization Framework.

User Agent

An optional user-agent value to include in http calls to the OAuth provider from runtime. This value will be added in user-agent header of the token exchange and the refresh HTTP calls to the OAuth provider from runtime.

Authorization Header

An optional authorization value to include in HTTP calls to the OAuth provider from runtime. This value will be added to the authorization header of the token exchange and the refresh HTTP calls to the OAuth provider from runtime.

BotFramework Bot OAuth2 Configuration Settings

Note: Before you can apply OAuth2 configurations to a BotFramework bot, your bot must be registered in the Workspace. If you have a BotFramework bot that is not registered in the Workspace and you would like information on how to do this, refer to the tutorial: Connecting a BotFramework Bot to Cortana.

To authenticate a BotFramework bot that uses Microsoft’s Identity service, ensure to follow the instructions in the Add MSA authentication page that is available in the Cortana Dev Center. These instructions describe how to use Cortana’s Connected Account feature. Ensure that your BotFramework bot’s registration specifies the Redirect URL to:

https://www.bing.com/agents/oauth

To do this, visit the Microsoft Application Registration Portal. It is in the Application Registration portal that you can look up your Application ID, and if it is necessary, be able to generate or delete your Application Secrets.

If you are using a third-party authentication service, ensure to obtain the third-party’s authentication specific parameters. When you’ve obtained these parameters, populate them into the various fields by clicking the Authentication menu tab in the Workspace Control Panel. Refer to the section below to see a list of the OAuth2 configuration field descriptions.

Add OAuth2 Configuration Field Descriptions

To add OAuth2 configurations on a skill, you must complete all the required fields in the Add OAuth2 Configuration window. All the required and optional fields are described below the image.

alternate text

Name

The Name is a required field that is the unique identifier to your authentication settings.

Domain

The Domain is a required field that is an internal identifier for your OAuth2 provider. For example, if Microsoft is your OAuth2 provider, enter www.microsoft.com into this field.

Client ID

The Client ID is a required field that gets populated with your bot’s application ID. For a skill that uses a Microsoft service, you can find your application ID by going to the Microsoft Application Registration Portal. Click the name of your BotFramework bot listed under the section My Applications.

Auth URL (URI)

The Auth URL is a required field that gets populated with the Authorization URL field of your OAuth2 provider. If you are using a Microsoft service, ensure that the Authorization URL is set to:

https://login.microsoftonline.com/common/oauth2/v2.0/authorize

Response Method

The Request Method is a required field used for selecting the token options (i.e., GET or POST). If you are using a Microsoft Service, set this field to POST.

Response Type

The Request Type is a required field for selecting Code or Token. Select Code to use a code grant flow. Select Token to use an implicit flow.

Client Auth Scheme

The Client Auth Scheme is a required field for selecting Basic Authentication or Auth in Body. If you are not sure of the Client Auth Scheme, use Basic Authentication as the default option.

Client Secret

The Client Secret is a required field that gets mapped to the bot’s password. If you are using a Microsoft Identity Service, this is the password that is generated when you had registered your bot in the Microsoft Application Registration portal.

Note: The Client Secret gets displayed only once under the Application Secrets section of the Microsoft Application Registration Portal page. If you need to recreate to reveal your application’s secret password, click Generate New password.

Token URL

The Token URL is a required field that gets populated with the Token URL field of your OAuth2 provider.

If you are using a Microsoft service, ensure that the Token URL is set to:

https://login.microsoftonline.com/common/oauth2/v2.0/token

User Tenant Auth

Select this option if you want your botlet to authenticate with your own service that is hosted in Microsoft Azure and uses the Azure Active Directory (AAD). For more details on authorizing access to web applications using OAuth 2.0 and AAD, see OAuth2 and Microsoft Azure Active Directory Protocol.

Redirect URL (URI)

The Redirect URL is an optional field that you had registered with your OAuth2 provider.

If you are using a Microsoft service, ensure that the Redirect URL is set to:

https://www.bing.com/agents/oauth

Scope

The Scope is an optional field that specifies the level of access for the application that is being requested of the OAuth flow.

User Agent

This is an optional user-agent value that is include in HTTP calls to the OAuth provider from Cortana. This value will be added in the user-agent header of the HTTP call.

Authorization Header

This is an optional authorization value that is include in HTTP calls to the OAuth provider from Cortana. This value will be added in the authorization header of the HTTP call.

Username Password

The Username Password feature allows botlet developers to prompt their users for username and password credentials, and then pass this information securely to other botlets and to external services.

alternate text

Name

The Name is a required field that is the unique identifier to your authentication settings.

Prompt

The Prompt is a required field that will be displayed to the user before their username and password is requested.

Prompt User for Credentials

Once an Username/Password configuration is added, users of the botlet can be prompted for their credentials using the SCL CREATE_AUTH command. The following is an example of this usage:

CREATE_AUTH “microsoft” STORE creds

The above SCL command will check the user vault to see if credentials from a previous user flow already exists, and if so, the “creds” will be populated with a reference to the credentials. If they do not exist, the user will be prompted to enter the credentials at that time.

Passing Credentials to External Services

Just like OAuth1 and OAuth2, the reference generated by the CREATE_AUTH command does not contain the actual credentials. But when this reference is passed to an external service using the CALL command, the actual username and password entered by the user are populated.

Example:

CALL “example.service”, “gcal”, auth=creds

In the above example, example.service is an external web service and “creds” are the generated reference from above. When the call is made to the external service, the actual username & password are passed as attributes “user_name” and “password” in data.pass_chain attribute in the POST body of the call.

Botlet Secret

The Botlet Secret feature allows bot developers to configure a generic secret like an API token or OAuth2 client id/secret and securely pass it to a list of allowed botlets. This section defines how to configure a botlet secret and how to generate a reference to the secret and pass it to other botlets or external services.

alternate text

Name

The Name is a required field that is the unique identifier to your authentication settings.

Secret ID

The Secret ID is an optional field for cases where the secret has both an ID and a value (e.g., client ID and client secret in case of OAuth).

Secret

The Secret is a required field containing the actual secret. For example, it can be an API token or a Client Secret.

Allowed botlet IDs

Allowed botlets IDs are the list of all botlet ids that are given access to the defined botlet secret. When a secret is passed to an external service, the credentials are only populated if all the botlets in the auth chain are added in the allowed botlets list.

Adding a New Botlet Secret

Generate the Reference

After a secret is added in the Authentication menu tab, a reference to the secret can be generated in a userflow using the CREATE_AUTH command. The following is an example of this usage:

CREATE_AUTH "microsoft" STORE secret

The above command will create a reference to the secret that can then be passed to other botlets or to external services.

Passing the Reference

The reference below can now be passed to other botlets or to external services using the CALL command.

Example:

CALL "example.second_botlet", "secret_example", secret=secret

When the above reference is finally passed to an external service, the secret is populated. If the reference is passed to other botlets and before passing to an external service, the runtime checks if all those botlets are configured in the allowed botlets IDs list before adding the credentials. If there exists a botlet that is not in the allowed list, the flow will error out. For the external service cal, the credentials will be in secret_id and secret_value under data.credentials attribute in the POST body of the call.

External OAuth2

Sometimes there are external auth providers that have custom or non standard OAuth implementations. External auth allows a bot developer to orchestrate OAuth flows in these scenarios. This section describes how to trigger an auth session with the user of the botlet, how to call back to the user session, how to save and refresh the generated credentials.

Triggering an Auth Session

After the configuration for an external auth provider is added, an auth session with a user can be triggered using the CREATE_AUTH command. For the initial flow, the error “auth.user_credentials_not_found” can be caught to trigger a new authentication flow. The developer can then create a custom URL specific to the auth provider and present that to the user for the initial authorization flow. Refer to the code sample below.

Example:

CREATE_AUTH "vso"
ON_ERROR "auth.user_credentials_not_found"
      # Start auth flow
      LOAD "vso" FROM BOTLET_SECRETS
      CREATE "$mst.auth.ext.oauth2.auth_url_request", config=SECRET, state=BOT_CONTEXT["session"]
      CALL "msl.example.vso_oauth2", "vso_oauth2_step1_get_auth", request=ENTITY
      SAY "Please authenticate at: ${CALL_RESULT.url.url}"
      GET_INPUT

In the above example, the “vso” external auth configuration is loaded from the vault, and an entity of type $auth.ext.oauth2.auth_url_request is created. This entity is then passed to the external service “msl.example.vso_oauth2” and the result of the service (${CALL_RESULT.url.url} in the above case) is presented to the user. Also the user session will be interrupted at the GET_INPUT call until the authentication flow is completed by the user and the callback to the botlet happens.

Calling Back to the User Session

The runtime provides a custom callback URL to a botlet. It has the format: https://api.botletstore.com/botlet/<BOTLET_ID>/call/<LABEL>.

When the callback happens to the runtime, the code at LABEL will be executed. For reinitiating a user session, the CALL_SESSION command must be used. Refer to the code sample below:

# Receive the HTTP redirect from the browser.
# Extract the session_id and the auth code and send it to the session
oauth2_callback:
CALL_SESSION CALLBACK_DATA.state, code=CALLBACK_DATA.code
RETURN text="Please return to the chat"

In the above example, the CALL_SESSION tries to retrieve the “state” attribute from the GET parameters of the HTTP callback. This attribute must have the format botlet_id:BOT_CONTEXT["session"] from the trigger an auth session section above. After the code under this label is run, the original user session that was interrupted in the GET_INPUT call will be resumed.

Save and Refresh Credentials

After the user session resumes and the botlet now has access to the user credentials, they can be saved in the user store. If the credentials are in the standard OAuth2 format, they can be refreshed as well. The following is the above example with the saving credentials added. Also in this example, the external auth provider has credentials in the standard OAuth2 format and also has the standard OAuth2 token exchange step.

Example:

CREATE_AUTH "vso"
ON_ERROR "auth.user_credentials_not_found"
      # Start auth flow
      LOAD "vso" FROM BOTLET_SECRETS
      CREATE "$mst.auth.ext.oauth2.auth_url_request", config=SECRET, state=BOT_CONTEXT["session"]
      CALL "msl.example.vso_oauth2", "vso_oauth2_step1_get_auth", request=ENTITY
      SAY "Please authenticate at: ${CALL_RESULT.url.url}"
      GET_INPUT
      SAY "Got Code: ${CALLBACK_DATA}"
      CREATE "$secret", text=CALLBACK_DATA.code
      LOAD "vso" FROM BOTLET_SECRETS
      CALL "example.vso_oauth2", "vso_oauth2_step2_exchange_code", config=SECRET, code=ENTITY
      SAY "Got credentials: ${CALL_RESULT.credentials}"
      SAVE CALL_RESULT.credentials AS "vso" TO USER_SECRETS
      CREATE_AUTH "vso" STORE creds

If the credentials are standard OAuth2 format and when the generated credentials expire, an error “auth.expired” is thrown that can be caught and the token refreshed.