Skip to main content

Auth Module

The Auth module handles authentication and token management for the EnterpriseAI platform. It supports multiple authentication flows including API keys, OAuth 2.0 client credentials, and custom token providers.

Basic Usage

import { PlatformClient } from '@enterpriseaigroup/platform-sdk';

const client = new PlatformClient({ /* config */ });

// Get current token
const token = await client.auth.getToken();

// Refresh token
const newToken = await client.auth.refreshToken();

// Validate token
const isValid = await client.auth.validateToken(token);

Methods

getToken()

Get the current authentication token.

getToken(): Promise<string>

Returns

A valid JWT access token string.

Example

const token = await client.auth.getToken();
console.log(`Token: ${token.substring(0, 20)}...`);

// Use token in custom API calls
const response = await fetch('https://api.example.com/data', {
headers: {
'Authorization': `Bearer ${token}`
}
});

refreshToken()

Refresh the current token (if using OAuth flow).

refreshToken(refreshToken?: string): Promise<TokenResponse>

Parameters

ParameterTypeRequiredDescription
refreshTokenstringNoRefresh token (uses stored token if not provided)

Returns

interface TokenResponse {
accessToken: string;
refreshToken?: string;
expiresIn: number; // Seconds until expiration
tokenType: 'Bearer';
}

Example

const tokens = await client.auth.refreshToken();

console.log(`New access token: ${tokens.accessToken.substring(0, 20)}...`);
console.log(`Expires in: ${tokens.expiresIn} seconds`);

// Tokens are automatically stored and used by the client

validateToken()

Validate a token's authenticity and expiration.

validateToken(token?: string): Promise<TokenValidation>

Parameters

ParameterTypeRequiredDescription
tokenstringNoToken to validate (uses current token if not provided)

Returns

interface TokenValidation {
valid: boolean;
expiresAt?: string; // ISO 8601 timestamp
userId?: string;
tenantId?: string;
scopes?: string[];
}

Example

const validation = await client.auth.validateToken();

if (validation.valid) {
console.log(`Token valid until: ${validation.expiresAt}`);
console.log(`User ID: ${validation.userId}`);
console.log(`Scopes: ${validation.scopes?.join(', ')}`);
} else {
console.log('Token is invalid or expired');
await client.auth.refreshToken();
}

revokeToken()

Revoke a token (logout).

revokeToken(token?: string): Promise<void>

Example

// Logout current session
await client.auth.revokeToken();
console.log('Token revoked. User logged out.');

Authentication Flows

API Key Authentication

Simple authentication using a static API key:

const client = new PlatformClient({
apiKey: process.env.EAI_API_KEY,
tenantId: 'acme-corp'
});

// No explicit auth calls needed
const resources = await client.resources.list({ type: 'project' });

Client Credentials Flow

OAuth 2.0 client credentials for server-to-server authentication:

const client = new PlatformClient({
clientId: process.env.EAI_CLIENT_ID,
clientSecret: process.env.EAI_CLIENT_SECRET,
tenantId: 'acme-corp'
});

// Tokens are obtained and refreshed automatically
const user = await client.users.getCurrent();

Custom Token Provider

Dynamic token management with custom logic:

const client = new PlatformClient({
tenantId: 'acme-corp',
tokenProvider: async () => {
// Custom token retrieval logic
const token = await getTokenFromDatabase();

// Check expiration
if (isTokenExpired(token)) {
return await refreshTokenFromAuthServer(token);
}

return token;
}
});

Token Provider Interface

type TokenProvider = () => Promise<string> | string;

The token provider function is called before each API request to obtain a valid token. It can be synchronous or asynchronous.

Example Token Provider

class TokenManager {
private token: string | null = null;
private expiresAt: number = 0;

async getToken(): Promise<string> {
// Return cached token if still valid
if (this.token && Date.now() < this.expiresAt) {
return this.token;
}

// Fetch new token
const response = await fetch('https://auth.example.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET
})
});

const data = await response.json();
this.token = data.access_token;
this.expiresAt = Date.now() + (data.expires_in * 1000);

return this.token;
}
}

const tokenManager = new TokenManager();

const client = new PlatformClient({
tenantId: 'acme-corp',
tokenProvider: () => tokenManager.getToken()
});

Token Caching

The SDK automatically caches tokens and refreshes them before expiration:

const client = new PlatformClient({
clientId: process.env.EAI_CLIENT_ID,
clientSecret: process.env.EAI_CLIENT_SECRET,
tenantId: 'acme-corp'
});

// First request: obtains token
const user1 = await client.users.getCurrent();

// Subsequent requests: uses cached token
const user2 = await client.users.getCurrent();
const resources = await client.resources.list({ type: 'project' });

// Token is automatically refreshed when needed

Token Scopes

Tokens include scopes that define permitted operations:

const validation = await client.auth.validateToken();

console.log('Available scopes:');
validation.scopes?.forEach(scope => {
console.log(`- ${scope}`);
});

// Common scopes:
// - resources:read
// - resources:write
// - documents:upload
// - chat:access
// - users:manage
// - admin:access

Security Best Practices

Secure Token Storage

// ❌ Don't store tokens in plain text
localStorage.setItem('token', token);

// ✅ Use secure storage mechanisms
import { SecureStorage } from '@enterpriseaigroup/secure-storage';

const storage = new SecureStorage();
await storage.setToken(token);

Token Rotation

// Implement automatic token rotation
setInterval(async () => {
try {
const validation = await client.auth.validateToken();
const expiresIn = new Date(validation.expiresAt!) - Date.now();

// Refresh if expiring in less than 5 minutes
if (expiresIn < 5 * 60 * 1000) {
await client.auth.refreshToken();
console.log('Token refreshed');
}
} catch (error) {
console.error('Token rotation failed:', error);
}
}, 60 * 1000); // Check every minute

Handle Expired Tokens

async function makeAuthenticatedRequest() {
try {
return await client.resources.list({ type: 'project' });
} catch (error) {
if (error.code === 'UNAUTHORIZED') {
// Token expired, refresh and retry
console.log('Token expired. Refreshing...');
await client.auth.refreshToken();
return await client.resources.list({ type: 'project' });
}
throw error;
}
}

Environment Variables

Recommended environment variable names for authentication:

# API Key
EAI_API_KEY=your_api_key_here

# OAuth Client Credentials
EAI_CLIENT_ID=your_client_id
EAI_CLIENT_SECRET=your_client_secret

# Tenant
EAI_TENANT_ID=your_tenant_id

# Base URL
EAI_BASE_URL=https://api.enterpriseai.com

Error Handling

try {
const token = await client.auth.getToken();
} catch (error) {
if (error.code === 'INVALID_CREDENTIALS') {
console.error('Invalid client ID or secret');
} else if (error.code === 'TOKEN_EXPIRED') {
console.error('Token has expired');
await client.auth.refreshToken();
} else if (error.code === 'INVALID_TOKEN') {
console.error('Token is malformed or invalid');
} else {
console.error('Authentication error:', error.message);
}
}

Complete Example

Full authentication setup with error handling and token management:

import { PlatformClient } from '@enterpriseaigroup/platform-sdk';

class AuthService {
private client: PlatformClient;
private tokenRefreshInterval?: NodeJS.Timeout;

constructor() {
this.client = new PlatformClient({
clientId: process.env.EAI_CLIENT_ID,
clientSecret: process.env.EAI_CLIENT_SECRET,
tenantId: process.env.EAI_TENANT_ID,
baseURL: process.env.EAI_BASE_URL
});

this.startTokenRefresh();
}

private startTokenRefresh() {
// Refresh token every 50 minutes (tokens typically expire in 60 minutes)
this.tokenRefreshInterval = setInterval(async () => {
try {
await this.client.auth.refreshToken();
console.log('Token refreshed successfully');
} catch (error) {
console.error('Failed to refresh token:', error);
}
}, 50 * 60 * 1000);
}

async validateSession(): Promise<boolean> {
try {
const validation = await this.client.auth.validateToken();
return validation.valid;
} catch (error) {
return false;
}
}

async logout() {
try {
await this.client.auth.revokeToken();
if (this.tokenRefreshInterval) {
clearInterval(this.tokenRefreshInterval);
}
console.log('Logged out successfully');
} catch (error) {
console.error('Logout failed:', error);
}
}

getClient(): PlatformClient {
return this.client;
}
}

// Usage
const authService = new AuthService();

// Validate session
const isValid = await authService.validateSession();
if (isValid) {
console.log('Session is valid');
}

// Use authenticated client
const client = authService.getClient();
const projects = await client.resources.list({ type: 'project' });

// Logout
await authService.logout();

Next Steps