AWorld Lab uses AWS Cognito with multi-tenant architecture. Each workspace has its own Cognito app client with isolated credentials.Auth Domain: https://auth.aworld.cloudAPI Domain: https://api.aworld.cloudDashboard (Admin) API: https://api.aworld.cloud/dashboard/v1/*
App (Consumer) API: https://api.aworld.cloud/app/v1/*
Authentication Methods#
1. Email OTP (Passwordless)#
Primary authentication method for end users. Sends a one-time password via email.Step 1: Initiate OTP Request#
Important: Store the returned Session token. It's required for OTP verification and expires after 3 minutes.Step 2: Verify OTP Code#
JWT Token Structure#
Understanding the token structure helps clarify why two separate credential sets are needed: each token is scoped to a specific context ("dashboard" or "app") and platform ("web", "mobile", or "m2m").Access Token Claims#
| Claim | Type | Required | Description |
|---|
sub | string | ✓ | Cognito user ID |
workspaceId | string | ✓ | Workspace ID (multi-tenant isolation) |
accountId | string | ✓ | Account ID |
userId | string | ✓ | User ID |
context | string | ✓ | API context: "dashboard" | "app" |
platform | string | ✓ | "web" | "mobile" | "m2m" |
role | string | ✓ | User role (e.g., "admin", "editor", "viewer") |
lang | string | - | ISO 639-1 language code (default: "en") |
timezone | string | - | IANA timezone (default: "UTC") |
exp | number | ✓ | Expiration timestamp (Unix seconds) |
iat | number | ✓ | Issued at timestamp (Unix seconds) |
ID Token Claims#
Contains user profile information:| Claim | Type | Description |
|---|
sub | string | Same as access token |
email | string | User email address |
email_verified | boolean | Email verification status |
name | string | Full name |
given_name | string | First name |
family_name | string | Last name |
picture | string | Avatar URL |
exp | number | Expiration timestamp |
Refresh Token#
Used to obtain new access and ID tokens
Does NOT change when refreshed
2. Server-side Authentication (Client Credentials)#
For server-to-server API calls without user interaction, using the OAuth2 client credentials grant. Each API context (Dashboard and App) requires its own Cognito app client with separate clientId and clientSecret. You will receive two sets of credentials from your AWorld administrator.Dashboard Server-side Credentials (Admin/Management API)#
Use Dashboard credentials for administrative operations: creating users, managing content, configuring the workspace.App Server-side Credentials (Consumer/User-facing API)#
Use App credentials for operations on behalf of end users: reading missions, checking balances, submitting actions. Typically combined with User Impersonation (see below).3. User Impersonation (Server-side Delegation)#
When calling the App API with server-side credentials, you typically need to act on behalf of a specific user. This is done by including a delegation header in your API requests.| Header | Description | Resolves by |
|---|
x-user-id | AWorld internal user ID | Primary key lookup |
x-external-user-id | Your system's user identifier | GSI query on externalId |
The two headers are mutually exclusive — sending both returns 400 Bad Request.
On endpoints that require delegation, omitting both headers returns 401 Unauthorized.
Some endpoints allow optional delegation — server-side calls work without the header, but providing it scopes the response to that user. Whether delegation is required or optional depends on the specific endpoint.
How It Works#
When a valid delegation header is provided, the platform resolves the user and enriches the server-side token claims with:userId — the resolved AWorld user ID
principalId — the user's principal
lang — the user's language preference
timezone — the user's timezone
These enriched claims are then used for authorization and data scoping on downstream endpoints.Example#
Token Refresh#
Access tokens expire after 1 hour. Use the refresh token to obtain new tokens without re-authentication.Cognito does NOT issue a new refresh token during refresh flow
The original refresh token remains valid until its 30-day expiration
When refresh token expires, user must re-authenticate
Using Tokens in API Calls#
Cookie-Based Authentication (Web Apps)#
Store tokens in HTTP-only cookies for security:Security: HTTP-only cookies prevent JavaScript access, protecting against XSS attacks.API Context and Required Claims#
Different API contexts require different token claims and different client credentials:| API Context | Base URL | Required Claims | Credentials | Use Case |
|---|
| Dashboard (Admin API) | /dashboard/v1/* | userId, workspaceId, role | Dashboard clientId/clientSecret | User management, content creation & configuration |
| App (Consumer API) | /app/v1/* | userId, workspaceId | App clientId/clientSecret | End-user interactions (with x-user-id for server-side calls) |
Validation: APIs validate that tokens contain the required claims for their context. Missing claims result in 403 Forbidden.Multi-Tenant Security#
Workspace ID Validation#
Every API request validates that:1.
Token contains valid workspaceId claim
2.
Requested resources belong to that workspace
3.
User has permission to access those resources
Critical: workspaceId in token must match the workspace being accessed. Cross-workspace access is blocked at the API gateway level.Tenant Isolation#
Each workspace has isolated Cognito credentials
User pools are separate per workspace
Tokens are scoped to a single workspace
Database queries automatically filter by workspaceId
Best Practices#
1.
Store tokens securely: Use HTTP-only cookies for web apps, secure storage for mobile
2.
Validate workspaceId: Always verify token's workspaceId matches the requested workspace
3.
Implement token refresh: Handle token expiration gracefully without forcing re-login
4.
Never expose client secrets: Keep secrets server-side only
5.
Use HTTPS: All authentication requests must use HTTPS in production
6.
Implement proper logout: Clear all tokens and terminate Cognito sessions
7.
Handle token expiration: Check exp claim and refresh proactively
Common Errors#
| Error | Cause | Solution |
|---|
NotAuthorizedException | Invalid credentials or expired token | Re-authenticate or refresh token |
CodeMismatchException | Wrong OTP code | Verify user entered correct code |
ExpiredCodeException | OTP or session expired | Request new OTP |
InvalidParameterException | Missing or invalid SECRET_HASH | Verify SECRET_HASH calculation |
UserNotFoundException | Email not registered | User must sign up first |
Token Validation Example#
Endpoint Reference#
Auth Domain: https://auth.aworld.cloud
API Domain: https://api.aworld.cloudDashboard (Admin): https://api.aworld.cloud/dashboard/v1/*
App (Consumer): https://api.aworld.cloud/app/v1/*
Cognito Region: eu-west-1 (Ireland)
Cognito IDP: https://cognito-idp.eu-west-1.amazonaws.com/
Token Endpoint: https://auth.aworld.cloud/oauth2/token
Modified at 2026-03-19 16:03:01