Technical Overview of Amazon Device Activation via Code
The Device Activation via Code flow, often referred to as Code-Based Linking (CBL), is an authentication mechanism designed for devices with limited input capabilities, such as Smart TVs, set-top boxes, and IoT devices. This document outlines the technical specifications, architectural components, and implementation details required to integrate Amazon's authentication services into such devices.
Instead of requiring users to enter their credentials directly on the device using a cumbersome on-screen keyboard, this flow generates a short alphanumeric code on the device. The user then enters this code on a secondary device (laptop or smartphone) to authorize the primary device.
Overview
The Code-Based Linking (CBL) process decouples the authentication request from the credential entry. It relies on the OAuth 2.0 Device Authorization Grant (RFC 8628). The high-level workflow is as follows:
- The Client Device requests a device code and user code from the authorization server.
- The Authorization Server returns a device code, a user code, and a verification URI.
- The Client Device displays the User Code and instructs the user to visit the verification URI.
- Simultaneously, the Client Device begins polling the Authorization Server to check if the user has completed the authorization.
- The User navigates to the verification URI on a secondary device, logs in to Amazon, and enters the User Code.
- Once validated, the Authorization Server responds to the Client Device's polling request with an Access Token and Refresh Token.
Technical Architecture
The architecture consists of three primary entities interacting over HTTPS:
- Client Device: The constrained device (e.g., Smart TV) requesting access. It must be capable of making outbound HTTPS requests and rendering text to a display.
- LWA (Login with Amazon) Service: The authorization server responsible for issuing codes and tokens.
- User Agent: A browser on a secondary device (PC/Mobile) used by the end-user to authenticate and approve the request.
Step-by-Step Activation Steps
Phase 1: Authorization Request
The device initiates the flow by sending a POST request to the LWA authorization endpoint.
Endpoint: https://api.amazon.com/auth/O2/create/codepair
Parameters:
response_type: Must bedevice_code.client_id: The unique client identifier assigned during device registration.scope: The permissions requested (e.g.,alexa:all,profile).
Phase 2: User Interaction
Upon a successful request, the server returns a JSON response containing:
user_code: The code displayed to the user (e.g., "ABCD-1234").verification_uri: The URL the user must visit (e.g., amazon.com/code).device_code: A unique handle used by the device to poll the server.expires_in: The validity period of the codes in seconds (typically 600 seconds).interval: The minimum time in seconds the device must wait between polling requests.
Phase 3: Polling for Token
The device polls the token endpoint using the device_code.
Endpoint: https://api.amazon.com/auth/O2/token
Parameters:
grant_type: Must bedevice_code.device_code: The code received in Phase 2.user_code: The user code displayed (optional but recommended for tracking).
API Endpoints and Authentication
Requesting a Code Pair
POST /auth/O2/create/codepair HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
response_type=device_code
&client_id=amzn1.application-oa2-client.xxxxxxxxx
&scope=profileSample Response
{
"user_code": "DNJ7-KQP3",
"device_code": "ed3f98a7-...",
"verification_uri": "https://amazon.com/code",
"expires_in": 600,
"interval": 5
}Polling for Token
POST /auth/O2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
grant_type=device_code
&device_code=ed3f98a7-...Code Examples
Python Implementation (Polling Logic)
import time
import requests
def poll_for_token(device_code, interval, expires_in):
url = "https://api.amazon.com/auth/O2/token"
payload = {
"grant_type": "device_code",
"device_code": device_code
}
start_time = time.time()
while (time.time() - start_time) < expires_in:
response = requests.post(url, data=payload)
data = response.json()
if response.status_code == 200:
return data # Contains access_token and refresh_token
error = data.get('error')
if error == 'authorization_pending':
time.sleep(interval) # Wait before retrying
elif error == 'slow_down':
interval += 5 # Increase polling interval
time.sleep(interval)
elif error == 'expired_token':
raise Exception("Code expired, restart flow")
else:
raise Exception(f"Fatal error: {error}")
raise Exception("Timeout")Security Tips
Code Expiration
The user_code and device_code have a limited lifespan (usually 10 minutes). Implementations must respect the expires_in parameter. If the timer runs out, the device must generate a new code pair rather than continuing to poll.
Token Storage
Access Tokens and Refresh Tokens must be stored securely on the device.
- Use hardware-backed secure storage (e.g., KeyStore, Secure Element) if available.
- Never log tokens or the
device_codein plain text debug logs. - Access tokens typically expire after 1 hour; use the Refresh Token to obtain new Access Tokens without user intervention.
SSL/TLS Pinning
To prevent Man-in-the-Middle (MITM) attacks, it is recommended to implement certificate pinning for the api.amazon.com domain.
Troubleshooting Issues
| Error Code | Cause | Resolution |
|---|---|---|
authorization_pending | The user has not yet entered the code on the website. | Continue polling. Do not treat this as a fatal error. |
slow_down | The device is polling too frequently. | Increase the polling interval by at least 5 seconds before the next request. |
expired_token | The device_code has expired. | Stop polling. Inform the user and restart the flow to generate a new code. |
invalid_grant | The device_code is invalid or malformed. | Verify the code storage logic; restart the flow. |
Best Practices
- User Experience (UX): Display the
user_codein a large, legible font. Clearly display the URLamazon.com/code. If possible, generate a QR code containing the pre-filled URL to simplify the mobile experience. - Polling Strategy: Strictly adhere to the
intervalreturned by the server. Aggressive polling may result in rate limiting (HTTP 429) or theslow_downerror. - Network Resilience: Implement exponential backoff for network timeouts (e.g., DNS failures, connection drops) separate from the LWA polling logic.
- Refresh Token Rotation: When refreshing tokens, if a new Refresh Token is returned, immediately discard the old one and persist the new one.
Comments
Post a Comment