JWT Claims Reference
AuthOS uses JSON Web Tokens (JWT) for authentication. This reference documents all JWT claims and token types.
Token Types
| Token Type | Purpose | Lifetime | Prefix |
|---|---|---|---|
| Access Token | API authentication | 24 hours | None |
| Refresh Token | Token renewal | 30 days | None (UUID) |
| Pre-auth Token | MFA pending | 10 minutes | preauth_ |
| Admin Token | Platform/Org admin | 24 hours | None |
Access Token Claims
Standard access tokens contain these claims:
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"exp": 1705401600,
"iat": 1705315200,
"nbf": 1705315200,
"jti": "unique-token-id",
"org": "acme-corp",
"service": "main-app",
"is_platform_owner": false
}
Claim Details
| Claim | Type | Required | Description |
|---|---|---|---|
sub |
string |
Yes | Subject - User ID (UUID) |
email |
string |
Yes | User’s email address |
exp |
integer |
Yes | Expiration time (Unix timestamp) |
iat |
integer |
Yes | Issued at time (Unix timestamp) |
nbf |
integer |
Yes | Not before time (Unix timestamp) |
jti |
string |
Yes | JWT ID - Unique token identifier |
org |
string |
No | Organization slug (empty for platform context) |
service |
string |
No | Service slug (empty for platform context) |
is_platform_owner |
boolean |
No | True if user is a platform owner |
Token Contexts
Platform Context Token
Token without organization or service claims. Used for platform-level operations.
{
"sub": "user-uuid",
"email": "admin@example.com",
"org": "",
"service": "",
"is_platform_owner": true
}
Use Cases:
- Platform owner administration
- User profile management before org selection
- Cross-organization operations
Organization Context Token
Token with organization but no service. Used for org administration.
{
"sub": "user-uuid",
"email": "admin@acme.com",
"org": "acme-corp",
"service": "",
"is_platform_owner": false
}
Use Cases:
- Organization settings management
- Member management
- Service configuration
Service Context Token
Token with both organization and service. Standard end-user token.
{
"sub": "user-uuid",
"email": "user@example.com",
"org": "acme-corp",
"service": "main-app",
"is_platform_owner": false
}
Use Cases:
- End-user authentication
- Service-specific API calls
- Provider token access
Pre-auth Token
Issued when MFA verification is required before completing authentication.
{
"sub": "user-uuid",
"email": "user@example.com",
"exp": 1705315800,
"iat": 1705315200,
"type": "preauth",
"org": "acme-corp",
"service": "main-app"
}
Pre-auth Specific Claims
| Claim | Type | Description |
|---|---|---|
type |
string |
Always "preauth" for pre-auth tokens |
Notes:
- Short-lived (10 minutes)
- Must be exchanged for full access token via MFA verification
- Cannot be used for API access
Token Validation
JWKS Endpoint
Retrieve public keys for token verification:
GET /.well-known/jwks.json
Response:
{
"keys": [
{
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"kid": "sso-key-2025-01-01",
"n": "base64url-encoded-modulus",
"e": "AQAB"
}
]
}
Validation Steps
- Parse the JWT - Extract header, payload, signature
- Verify signature - Use public key from JWKS endpoint
- Check expiration - Ensure
exp> current time - Check not-before - Ensure
nbf<= current time - Verify issuer - Match expected issuer (if configured)
- Check claims - Validate
organdservicematch expected values
Example: Node.js Validation
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');
const client = jwksClient({
jwksUri: 'https://sso.example.com/.well-known/jwks.json'
});
function getKey(header, callback) {
client.getSigningKey(header.kid, (err, key) => {
const signingKey = key.getPublicKey();
callback(null, signingKey);
});
}
function verifyToken(token) {
return new Promise((resolve, reject) => {
jwt.verify(token, getKey, {
algorithms: ['RS256']
}, (err, decoded) => {
if (err) reject(err);
else resolve(decoded);
});
});
}
Refresh Tokens
Refresh tokens are opaque UUIDs stored in the database.
| Property | Value |
|---|---|
| Format | UUID v4 |
| Lifetime | 30 days |
| Storage | Hashed in database |
| Rotation | New token on refresh |
Refresh Flow
POST /api/auth/refresh
Content-Type: application/json
{
"refresh_token": "550e8400-e29b-41d4-a716-446655440000"
}
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"refresh_token": "660f9500-f30c-52e5-b827-557766551111",
"expires_in": 86400
}
Security Notes:
- Refresh token is rotated on each use
- Old refresh token is invalidated
- Store refresh tokens securely (httpOnly cookies recommended)
Session Management
Session Invalidation
Sessions can be invalidated via:
- Logout - Revokes current session
- Password change - Revokes all other sessions
- MFA disable - Revokes all sessions
- Admin force-logout - Revokes specific user sessions
Checking Session Validity
The jti claim can be checked against the session store:
async function isSessionValid(decodedToken) {
const session = await sessionStore.findByJti(decodedToken.jti);
return session && !session.revoked_at;
}