Authentication
Understanding the multi-layer authentication system and token lifecycle
Authentication
Data Border uses a multi-layer authentication system designed for security and simplicity. This guide explains how authentication works and how to integrate it into your WMS.
Authentication Layers
Data Border has three authentication layers, each serving a different purpose:
flowchart TD
subgraph Layer1["Layer 1: Tenant"]
A[Create Tenant JWT] --> B[Tenant Refresh Token]
B --> C[Data Border Access Token]
end
subgraph Layer2["Layer 2: Seller"]
D[OAuth with Amazon] --> E[Seller Refresh Token]
E --> F[Seller Access Token]
end
subgraph Layer3["Layer 3: Amazon"]
G[Amazon Refresh Token] --> H[Amazon Access Token]
H --> I[SP-API Requests]
end
C --> D
F --> G
| Layer | Purpose | Your Responsibility |
|---|---|---|
| Tenant | Identifies your WMS | Store refresh token securely |
| Seller | Identifies a connected Amazon seller | Store refresh token per seller |
| Amazon | Accesses Amazon SP-API | Provide amazonTokenSecret for encryption |
Token Lifecycle
Token Validity
| Token Type | Validity | Refresh Method |
|---|---|---|
| Data Border Access Token | 30 days | Exchange tenant refresh token |
| Seller Access Token | 24 hours | Exchange seller refresh token |
| Claim Code | 5 minutes | Re-initiate OAuth flow |
| Amazon Access Token | ~1 hour | Automatic (handled by Data Border) |
Token Flow Diagram
sequenceDiagram
participant WMS
participant ADB
participant Amazon
Note over WMS,ADB: Initial Setup (once)
WMS->>ADB: POST /api/create-tenant
ADB->>WMS: tenant_id + tenant_refresh_token
WMS->>WMS: Store tenant credentials
Note over WMS,ADB: Get ADB Access (every 30 days)
WMS->>ADB: POST /api/get-adb-access-token
ADB->>WMS: adb_access_token (valid 30 days)
Note over WMS,Amazon: Connect Seller (once per seller)
WMS->>ADB: GET /auth/initialize
ADB->>Amazon: OAuth redirect
Amazon->>ADB: Authorization code
ADB->>WMS: Redirect with seller_id + claim_code
WMS->>ADB: POST /api/claim-code
ADB->>WMS: seller_refresh_token
WMS->>WMS: Store seller credentials
Note over WMS,ADB: Get Seller Access (every 24 hours)
WMS->>ADB: POST /api/get-seller-access-token
ADB->>WMS: seller_access_token (valid 24 hours)
Step-by-Step Integration
Step 1: Create Your Tenant
Before anything else, register your WMS as a tenant:
# Generate a JWT with create-tenant permission
# (Run on the Data Border server with JWT_SECRET set)
JWT=$(npx tsx scripts/generate-jwt.ts --expiry 1h)
# Create the tenant
curl -X POST https://adb.example.com/api/create-tenant \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT" \
-d '{
"name": "My WMS System",
"redirectOrigin": "https://my-wms.com/oauth/callback"
}'
Response:
{
"success": true,
"data": {
"tenant_id": "clx1y2z3a4b5c6d7e8f9g0h1",
"refresh_token": "rt_abc123..."
}
}
Store the tenant_id and refresh_token securely. The refresh token cannot be retrieved again.
Step 2: Get a Data Border Access Token
Exchange your tenant refresh token for an access token:
curl -X POST https://adb.example.com/api/get-adb-access-token \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT" \
-d '{
"tenant_id": "clx1y2z3a4b5c6d7e8f9g0h1",
"refresh_token": "rt_abc123..."
}'
Response:
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs..."
}
}
This access token is valid for 30 days. Schedule a refresh before expiry.
Step 3: Connect an Amazon Seller
When a seller wants to connect their Amazon account:
3a. Generate the Amazon Token Secret
Create a secure random secret that will encrypt the seller's Amazon tokens:
// Generate 32+ bytes of random data, base64 encode
const crypto = require('crypto')
const amazonTokenSecret = crypto.randomBytes(32).toString('base64')
// Store this with the seller - you'll need it for every API call
3b. Redirect to OAuth
Redirect the seller to the OAuth initialization endpoint:
https://adb.example.com/auth/initialize
?state=YOUR_STATE_DATA
&marketplace_region=us-east-1
&amazonTokenSecret=BASE64_ENCODED_SECRET
&sellerRedirectUrl=https://my-wms.com/oauth/callback/seller
| Parameter | Description |
|---|---|
state | Arbitrary data returned to you after OAuth (e.g., internal seller ID) |
marketplace_region | us-east-1 (NA), eu-west-1 (EU), or us-west-2 (FE) |
amazonTokenSecret | Your generated secret (32-64 chars of base64 random data) |
sellerRedirectUrl | Where to redirect after OAuth (must start with your redirectOrigin) |
3c. Handle the OAuth Callback
After the seller authorizes, they're redirected to your sellerRedirectUrl with:
https://my-wms.com/oauth/callback/seller
?state=YOUR_STATE_DATA
&seller_id=seller_abc123
&code=temp_claim_code_xyz
3d. Claim the Authorization
Exchange the claim code for a seller refresh token (within 5 minutes):
curl -X POST https://adb.example.com/api/claim-code \
-H "Content-Type: application/json" \
-H "x-adb-access-token: YOUR_ADB_ACCESS_TOKEN" \
-d '{
"seller_id": "seller_abc123",
"name": "Seller Display Name",
"callback_url": "https://my-wms.com/webhooks/seller",
"code": "temp_claim_code_xyz"
}'
Response:
{
"success": true,
"data": {
"refresh_token": "srt_def456..."
}
}
Store the seller's refresh_token and amazonTokenSecret securely together. You need both for all seller operations.
Step 4: Get a Seller Access Token
Exchange the seller refresh token for an access token:
curl -X POST https://adb.example.com/api/get-seller-access-token \
-H "Content-Type: application/json" \
-H "x-adb-access-token: YOUR_ADB_ACCESS_TOKEN" \
-d '{
"seller_id": "seller_abc123",
"refresh_token": "srt_def456..."
}'
Response:
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs..."
}
}
This access token is valid for 24 hours. Use it with the x-seller-access-token header.
Using Tokens in API Calls
Once you have tokens, use them in API requests:
# Example: Get orders via passthrough API
curl -X GET "https://adb.example.com/passthrough-api/orders/v0/orders?MarketplaceIds=ATVPDKIKX0DER" \
-H "x-seller-access-token: SELLER_ACCESS_TOKEN" \
-H "x-amazon-token-secret: AMAZON_TOKEN_SECRET"
| Header | Value | When Required |
|---|---|---|
x-adb-access-token | Data Border access token | Tenant management, seller management |
x-seller-access-token | Seller access token | All seller operations (PII, passthrough, labels, print) |
x-amazon-token-secret | Your generated secret | All seller operations that access Amazon |
Token Refresh Strategy
Implement automatic token refresh to avoid service interruptions:
// Pseudocode for token management
class TokenManager {
async getAdbAccessToken() {
if (this.adbToken && !this.isExpiringSoon(this.adbToken, '7d')) {
return this.adbToken
}
// Refresh 7 days before expiry
this.adbToken = await this.refreshAdbToken()
return this.adbToken
}
async getSellerAccessToken(sellerId) {
const token = this.sellerTokens[sellerId]
if (token && !this.isExpiringSoon(token, '1h')) {
return token
}
// Refresh 1 hour before expiry
this.sellerTokens[sellerId] = await this.refreshSellerToken(sellerId)
return this.sellerTokens[sellerId]
}
}
Security Best Practices
Token Storage
| Token | Storage Recommendation |
|---|---|
| Tenant refresh token | Encrypted at rest, limited access |
| Data Border access token | Can cache in memory, refresh on startup |
| Seller refresh token | Encrypted per-seller, database storage |
| Amazon token secret | Encrypted, stored with seller refresh token |
| Seller access token | Cache in memory, short-lived |
Never Do This
- Store tokens in client-side code or local storage
- Log tokens in plain text
- Share tokens between environments
- Use predictable values for
amazonTokenSecret - Skip HTTPS for any token exchange
Troubleshooting
"Invalid or expired token"
- Check token expiry times
- Ensure you're using the correct token for the endpoint
- Verify the token hasn't been revoked
"Invalid claim code"
- Claim codes expire after 5 minutes
- Each code can only be used once
- Re-initiate the OAuth flow if expired
"Invalid amazonTokenSecret"
- Must be at least 32 bytes when base64 decoded
- Must be the same secret used during OAuth initialization
- Store it securely - you can't recover it
