Authentication
Overview
All APIs use AWS Cognito for authentication:
- User Pool:
us-east-1_75Rp4zNBg - JWT validated via JWKS endpoint
- Token extraction: httpOnly cookie first, Bearer header fallback
Token Extraction Priority
JwtStrategy extracts tokens in this order:
- httpOnly cookie
statux_id_token(browser requests viacredentials: 'include') Authorization: Bearerheader (API clients, mobile app, testing)
Auth Flows
Browser Auth (httpOnly Cookies)
The primary auth flow for web dashboards uses httpOnly cookies managed by AuthCookieController (registered on all APIs):
| Endpoint | Method | Auth | Description |
|---|---|---|---|
/auth/set-cookie | POST | JWT | Store tokens in httpOnly cookies |
/auth/me | GET | Cookie/JWT | Get current user from session |
/auth/refresh | POST | Cookie | Refresh tokens using refresh cookie |
/auth/logout | POST | Public | Clear httpOnly auth cookies |
Frontend flow:
- User signs in via Cognito hosted UI
- Frontend calls
POST /auth/set-cookiewith the Cognito tokens - API sets
statux_id_tokenandstatux_refresh_tokenas httpOnly cookies - All subsequent requests include cookies automatically via
credentials: 'include' - Token refresh handled via
POST /auth/refresh
Cookie settings:
- Domain:
.statux.io - SameSite:
Lax - Secure:
true - Max-Age: 30 days (refresh token), 1 hour (ID token)
API Client Auth (Bearer Token)
Mobile apps, API clients, and testing use the standard Bearer header:
curl -H "Authorization: Bearer $TOKEN" https://alerts-api.statux.io/api/v1/users/me
Guards
JwtAuthGuard (Global)
Applied globally via APP_GUARD -- all endpoints require valid JWT unless marked @Public().
OrgAccessGuard
Validates organization membership, attaches request.organization:
@UseGuards(JwtAuthGuard, OrgAccessGuard)
@Controller('organizations/:orgId/components')
export class ComponentsController {
// User must be a member of :orgId
}
OrgRolesGuard
Validates organization role (admin, owner, etc.):
@OrgRoles('admin', 'owner')
@UseGuards(JwtAuthGuard, OrgRolesGuard)
@Controller('organizations/:orgId/settings')
export class OrgSettingsController {
// User must be admin or owner of :orgId
}
OrgProductAccessGuard
Validates per-product role with hierarchy checks:
@ProductAccess('alerting', 'manager')
@UseGuards(JwtAuthGuard, OrgAccessGuard, OrgProductAccessGuard)
@Controller('organizations/:orgId/alerts')
export class AlertsController {
// User must have manager+ role for alerting product
}
Org OWNER, GLOBAL_ADMIN, and ADMIN bypass product role checks automatically.
PlatformAdminGuard
Restricts to Cognito PlatformAdmins group:
@PlatformAdmin()
@UseGuards(JwtAuthGuard, PlatformAdminGuard)
export class AdminController { ... }
ScimAuthGuard
Validates SCIM 2.0 bearer tokens (SHA256 hash lookup, revokedAt check):
@UseGuards(ScimAuthGuard)
@Controller('scim/v2')
export class ScimController { ... }
Accessing User Info
// Full user object
@Get('me')
getProfile(@CurrentUser() user: AuthUser) {
// user.userId, user.email, user.groups, user.isPlatformAdmin
}
// Shorthand: just the user ID
@Get('widgets')
getWidgets(@User('userId') userId: string) { ... }
Impersonation
Platform admins can impersonate users by setting the x-impersonate-user-id header. The original admin's identity is preserved:
user.originalUserId-- the admin's real user IDuser.originalEmail-- the admin's real email
This allows debugging user-specific issues without sharing credentials.
JWT Testing with curl
For testing production APIs from the command line:
One-Time Setup
Cache a refresh token (valid 30 days):
cd statux-api
AWS_CLI="aws" bash scripts/get-refresh-token.sh <your-email>
This prompts for your Cognito password once and saves the refresh token to ~/.statux-refresh-token.
Get a Fresh ID Token
TOKEN=$(aws cognito-idp admin-initiate-auth \
--user-pool-id us-east-1_75Rp4zNBg \
--client-id 2u986rkhchk6mur28sgpt0bm8p \
--auth-flow REFRESH_TOKEN_AUTH \
--auth-parameters "REFRESH_TOKEN=$(cat ~/.statux-refresh-token)" \
--query "AuthenticationResult.IdToken" --output text)
ID tokens expire after 1 hour. Re-run the command to get a fresh one. If the refresh token expires (after 30 days), re-run get-refresh-token.sh.
Use the Token
# Any API
curl -s -H "Authorization: Bearer $TOKEN" https://platform-api.statux.io/api/v1/users/me
# Org-scoped endpoint
ORG_ID="<org-uuid>"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://alerts-api.statux.io/api/v1/organizations/$ORG_ID/alerts?page=1&limit=10"
The Cognito client has ALLOW_ADMIN_USER_PASSWORD_AUTH enabled. admin-initiate-auth requires AWS IAM credentials (SSO admin role) and is not exposed to the internet.