Tenant Management
Create tenants and manage Data Border access tokens
Tenant Management
These endpoints manage WMS tenant registration and access token lifecycle.
Create Tenant
Creates a new tenant (WMS system) in Data Border.
POST /api/create-tenant
Authentication
Requires Authorization: Bearer <JWT> header with a JWT containing the "create-tenant": true claim.
Request Body
{
"name": "string",
"redirectOrigin": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name for the WMS system |
redirectOrigin | string | Yes | Base URL for OAuth redirects (must start with https://) |
Response
{
"success": true,
"data": {
"tenant_id": "clx1y2z3a4b5c6d7e8f9g0h1",
"refresh_token": "rt_abc123def456..."
}
}
| Field | Description |
|---|---|
tenant_id | Unique identifier for the tenant |
refresh_token | Long-lived token for obtaining access tokens |
Example
# Generate JWT (on Data Border server with JWT_SECRET set)
JWT=$(npx tsx scripts/generate-jwt.ts --expiry 1h)
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"
}'
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Name is required | Missing or empty name |
| 400 | redirectOrigin must start with https:// | Invalid redirect origin |
| 401 | Invalid token | JWT is invalid or expired |
| 401 | Token missing create-tenant claim | JWT lacks required permission |
Store the refresh token securely. It cannot be retrieved again and is required for all future operations.
Get Data Border Access Token
Exchanges a tenant refresh token for a Data Border access token.
POST /api/get-adb-access-token
Authentication
Requires Authorization: Bearer <JWT> header with the "create-tenant": true claim.
Request Body
{
"tenant_id": "string",
"refresh_token": "string"
}
| Field | Type | Required | Description |
|---|---|---|---|
tenant_id | string | Yes | The tenant's unique identifier |
refresh_token | string | Yes | The tenant's refresh token |
Response
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIs..."
}
}
| Field | Description |
|---|---|
access_token | JWT access token valid for 30 days |
Token Claims
The access token contains:
{
"tenant_id": "clx1y2z3a4b5c6d7e8f9g0h1",
"iat": 1640995200,
"exp": 1643587200
}
Example
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_abc123def456..."
}'
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | tenant_id is required | Missing tenant ID |
| 400 | refresh_token is required | Missing refresh token |
| 401 | Invalid token | JWT is invalid or expired |
| 404 | Tenant not found | Tenant ID doesn't exist |
| 401 | Invalid refresh token | Refresh token doesn't match |
Token Lifecycle
Recommended Refresh Strategy
flowchart TD
A[Application Start] --> B{Token Cached?}
B -->|No| C[Exchange Refresh Token]
B -->|Yes| D{Expires in < 7 days?}
D -->|Yes| C
D -->|No| E[Use Cached Token]
C --> F[Cache Token + Expiry]
F --> E
E --> G[Make API Calls]
Token Storage
| Token | Storage | Encryption | Access |
|---|---|---|---|
| Tenant Refresh Token | Database | Yes (at rest) | Limited to token refresh |
| Data Border Access Token | Memory/Cache | Optional | API calls |
Security Considerations
- Refresh tokens never expire but can be revoked
- Access tokens are JWTs signed with HS256
- Always transmit tokens over HTTPS
- Never log tokens in plain text
- Implement token refresh before expiry
