AVS Device SDK Authorization
The Alexa Voice Service (AVS) Device SDK uses Login with Amazon (LWA) to authorize your client's requests with one of the following protocols:
To authenticate the SDK with LWA, your device sends an access token to AVS with every request. The SDK abstracts the token retrieval process by using the AuthDelegateInterface
. This abstraction enables the SDK to work with any of the existing methods to acquire access tokens. It also allows you to specialize your implementation of AuthDelegateInterface
without changing the code that relies on the AuthDelegateInterface
.
How AuthDelegateInterface works
You inject an instance of AuthDelegateInterface
into your product to abstract the LWA token retrieval process. How you implement this abstraction depends on the authorization method you're using.
If you've based your product on the sample app
The sample app uses code-based linking authorization. When the sample app initializes, it creates an instance of AuthDelegateInterface
called CBLAuthDelegate
and passes it to these methods:
CapabilitiesDelegate::create()
- Authorizes theCapabilitiesDelegate
to publish the capabilities of the device.DefaultClient::create()
- Authorizes the Alexa Communications Library (ACL) to send requests to AVS.
To set up your product up with code-based linking, inject your implementation of AuthDelegateInterface
into the same places as the sample app
If you haven't based your product on the sample app
If your product isn't based on the sample app, you're using the Companion App, companion site or the on-product authorization method. You must create a custom instance of AuthDelegateInterface
that communicates with the Alexa Communications Library (ACL).
To do this, pass your instance of AuthDelegateInterface
into the MessageRouter
constructor call.
Next, pass your MessageRouter
instance into AVSConnectionManager::create()
. AVSConnectionManager
manages your persistent connection with AVS.
Required methods
AuthDelegateInterface
contains abstract methods that you must use in your implementation.
Get an LWA authorization token
getAuthToken()
Every time you make a call to AVS, you must check if you have a valid token.
getAuthToken()
returns the current access token.
- Returns an empty string if it's your first time requesting a token or an access token expires.
- Call
getAuthToken()
immediately before sending any messages to AVS. The ACL handles token refresh automatically. - Proper implementations of
getAuthToken()
preemptively refresh access tokens before they expire, meaning you can send requests to AVS without waiting for a refresh.
Example
virtual std::string getAuthToken() = 0;
Track state changes
addAuthObserver() and removeAuthObserver()
It's important to track any changes to the AuthDelegateInterface
state. Tracking prevents requests from failing due to an expired authorization token. Tracking also informs your client when the authorization process restores.
To track the AuthDelegateInterface
state, use the following abstract methods: addAuthObserver()
and removeAuthObserver()
.
When the authorization state changes, addAuthObserver()
and removeAuthObserver()
manage instances of AuthObserverInterface
that receive notifications.
Example
virtual void addAuthObserver(std::shared_ptr<avsCommon::sdkInterfaces::AuthObserverInterface> observer) = 0;
virtual void removeAuthObserver(std::shared_ptr<avsCommon::sdkInterfaces::AuthObserverInterface> observer) = 0;
onAuthStateChange()
You report state changes to the observers with onAuthStateChange()
. This method takes two parameters, the state and an error code. You can also receive callbacks when the state changes by calling setAuthObserver()
.
Parameter | Description |
---|---|
State | The new State of the authorization delegate. |
Error code | Error code that provides details about how the state. |
Handle customer data
CustomerDataHandler()
Your implementation of AuthDelegateInterface
must retain the current access token and refresh it before it expires. To refresh the token transfer device properties that might hold customer-specific data. You must wipe the customer data before refreshing the token.
To wipe customer data, implement an instance of the CustomerDataHandler
interface and its abstract method clearData()
. You must call cleardata()
for each instance of CustomerDataHandler
. You should wipe the data when the user resets the product or if the primary user associated with the product changes.
Example
virtual void clearData() = 0;
One way to incorporate CustomerDataHandler
into your implementation is to use multiple inheritance and derive your implementation from both AuthDelegateInterface
and CustomerDataHandler
.
Example
class MyAuthDelegate
: public avsCommon::sdkInterfaces::AuthDelegateInterface
, public registrationManager::CustomerDataHandler {
...
};
SDK authorization flows
Companion app
Companion app authorization is useful for devices headless devices, such as a smart speaker. It provides an interface for users to generate Authorization Codes and register device with AVS
The AVS Device SDK doesn't provide a companion app – you must create one for your product.
Companion app data flow

To integrate AuthDelegateInterface with a companion app to retrieve access tokens
- Check for a valid Refresh Token token. If you already have a valid refresh token, skip to step 7.
- Load the
Product ID
andDevice Serial Number
parameters. - Generate a Code Verifier and Code Challenge pair. Retain for use in later steps.
- Connect your product to the Companion App using a supported protocol, such as Bluetooth or Wi-Fi. Implement this functionality in the manner that best fits your product.
- After connecting, get the
Product ID
,Device Serial Number
, andCode Challenge
.
- After connecting, get the
- Using the Companion App, send the
Authorization Code
,Client ID
, andRedirect URI
to your product. Implement this functionality in the manner that best fits your product. Retain these values for use in later steps. - Get an Access token and Refresh Token. Send a
POST
request to the LWA. - The Access Token and Refresh Token can expire. To refresh them, send a
refresh token POST
request to the LWA.
AuthDelegateInterface
has a method to restart the authorization process.Get token
Gets an Access Token and Refresh Token from the LWA server.
Sample request
POST: https://api.amazon.com/auth/O2/token
Parameter | Description |
---|---|
grant_type |
authorization_code |
code |
The authorization code received from the companion app |
redirect_uri |
The Redirect URI received from the companion app |
client_id |
The Client ID received from the companion app |
code_verifier |
The Code Verifier initially generated by the product |
Sample response
If this request times out or fails due to a server error, retry after a delay until it succeeds or the product shuts down.
HTTP/1.1 200 OK
Content-Type: application/json;charset UTF-8
{
"access_token":"...",
"refresh_token":"Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX..."
"token_type":"bearer",
"expires_in":3600,
"code_verifier: "..."
}
Parameter | Description |
---|---|
access_token |
The access token |
refresh_token |
The refresh token |
token_type |
bearer |
expires_in |
The number of seconds for which the access token is still valid |
Refresh token
Refreshes an Access Token and Refresh Token from the LWA server.
Sample request
POST: https://api.amazon.com/auth/O2/token
Parameter | Description |
---|---|
grant_type |
refresh_token |
refresh_token |
The refresh token |
client_id |
The Client ID received from the companion app. |
Sample response
HTTP/1.1 200 OK
Content-Type: application/json;charset UTF-8
{
"access_token":"...",
"refresh_token":"Atzr|IQEBLzAtAhRPpMJxdwVz2Nn6f2y-tpJX2DeX..."
"token_type":"bearer",
"expires_in":3600,
}
Parameter | Description |
---|---|
access_token |
The access token |
refresh_token |
The refresh token |
token_type |
bearer |
expires_in |
The number of seconds for which the access token is still valid |
Code based linking (CBL)
The AVS Device SDK sample app provides an example implementation of the Code Based Linking with the class CBLAuthDelegate
.
You can use the provided CBLAuthDelegate
implementation exactly as provided in your product. If you want to create your own implementation of Code Based Linking, you must create the implementation yourself.
Companion app data flow

To create a custom CBLAuthDelegate
- Load the
Client ID
,Product ID
andDevice Serial Number
parameters. - Check for a valid Refresh Token. If you have one, skip to step 5.
- Send a Device Authorization Request to LWA. For more details, see Device Authorization Request.
- Prompt the user to visit your Verification URI and enter the User Code. For more details, see Direct the user to log in for details.
- At the same time that the user is entering User Code, poll LWA to acquire an initial access token by sending Device Token Requests to LWA. For more details, see Device Token Request.
On product
To create your own implementation of the On Product authorization, you must provide an implementation of AuthDelegateInterface
that uses the Android or iOS LWA Library operations described in the On Product documentation.
Related topics
Last updated: Jan 06, 2022