@spectrumsense/spectrum-chat-dev
Version:
Embeddable AI Widget - Add trusted, evidence-based answers directly to your website. Simple installation, enterprise-grade security.
748 lines (561 loc) • 19.7 kB
Markdown
# Spectrum Chat Security Implementation
**Version:** 1.0
**Last Updated:** October 6, 2025
**Implementation Date:** October 6, 2025
## Table of Contents
1. [Overview](#overview)
2. [Security Architecture](#security-architecture)
3. [Phase 0: Site-Key + Origin Validation](#phase-0-site-key--origin-validation)
4. [Phase 1: JWT Session Tokens](#phase-1-jwt-session-tokens)
5. [Configuration Guide](#configuration-guide)
6. [Usage Examples](#usage-examples)
7. [Security Features](#security-features)
8. [Error Handling](#error-handling)
9. [Best Practices](#best-practices)
10. [Troubleshooting](#troubleshooting)
## Overview
Spectrum Chat now implements a two-phase security model aligned with the KnowledgeInjester API specification:
- **Phase 0 (Required)**: Site-key based authentication with automatic origin validation
- **Phase 1 (Optional)**: Enhanced security with JWT session tokens
All conversations are managed server-side with automatic history tracking. The widget handles token lifecycle, error recovery, and conversation persistence transparently.
### Key Benefits
✅ **Origin-Bound Security**: Prevents unauthorized domains from using your chat service
✅ **Conversation Protection**: Server validates origin on every request
✅ **Automatic Token Refresh**: JWT tokens refresh automatically before expiration
✅ **Graceful Error Recovery**: Handles expired conversations and network errors
✅ **User-Friendly Messages**: Translates technical errors to readable messages
✅ **Backward Compatible**: Existing integrations continue to work
## Security Architecture
### Phase 0: Site-Key + Origin Validation (Required)
**How it works:**
1. Widget sends `siteKey` in request body for new conversations
2. Browser automatically sends `Origin` header (CORS)
3. API validates:
- Site key exists and is active
- Origin is HTTPS (or localhost for development)
- Origin is in the site's allowed origins list
4. Conversation is created and bound to origin
5. Subsequent requests must come from same origin
**Security guarantees:**
- ✅ Prevents unauthorized domains from using your site key
- ✅ Prevents conversation hijacking across domains
- ✅ No sensitive credentials in client code (site key is public)
- ✅ HTTPS enforcement in production
### Phase 1: JWT Session Tokens (Optional)
**How it works:**
1. Widget requests session token from `/api/v1/sessions`
2. API returns JWT token bound to origin
3. Widget stores token in `sessionStorage`
4. Widget includes token in `Authorization` header for all requests
5. API validates token signature, expiration, and origin binding
6. Token auto-refreshes 5 minutes before expiration
**Additional security guarantees:**
- ✅ Time-limited access (default: 1 hour)
- ✅ Token bound to origin (can't be reused from different domain)
- ✅ Server-side revocation support
- ✅ Full audit trail
- ✅ Automatic refresh on expiration
## Phase 0: Site-Key + Origin Validation
### Basic Configuration
This is the **minimum required** security configuration.
#### Custom Element (Plain HTML)
```html
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
<spectrum-chat
api-url="https://your-api-domain.com/api/v1/conversations"
site-key="pub_customer_a1b2c3d4"
title="AI Assistant"
citations="true">
</spectrum-chat>
```
#### Global Script (Template Integration)
```html
<script>
window.SpectrumChatConfig = {
apiUrl: 'https://your-api-domain.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
title: 'AI Assistant',
enableCitations: true,
useJWT: false // Phase 0 only
};
</script>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
```
### What Happens Behind the Scenes
**Starting a new conversation:**
```http
POST https://your-api-domain.com/api/v1/conversations
Origin: https://www.your-domain.com
Content-Type: application/json
{
"siteKey": "pub_customer_a1b2c3d4",
"message": "What is your return policy?",
"citations": true,
"pageUrlHash": "sha256_hash_optional",
"nonce": "uuid_optional"
}
```
**Continuing a conversation:**
```http
POST https://your-api-domain.com/api/v1/conversations/c_abc123xyz
Origin: https://www.your-domain.com
Content-Type: application/json
{
"message": "How long do I have to return items?",
"citations": true
}
```
### Origin Validation Rules
| Scenario | Allowed? | Notes |
|----------|----------|-------|
| `https://www.yoursite.com` | ✅ Yes | If in allowed origins list |
| `http://localhost:3000` | ✅ Yes | HTTP allowed for localhost (dev) |
| `http://127.0.0.1:8080` | ✅ Yes | HTTP allowed for localhost (dev) |
| `http://www.yoursite.com` | ❌ No | HTTPS required in production |
| `https://unauthorized.com` | ❌ No | Not in allowed origins list |
## Phase 1: JWT Session Tokens
### Enhanced Security Configuration
Enable JWT tokens for enhanced security with session management.
#### Custom Element (Plain HTML)
```html
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
<spectrum-chat
api-url="https://your-api-domain.com/api/v1/conversations"
site-key="pub_customer_a1b2c3d4"
use-jwt="true"
title="AI Assistant"
citations="true">
</spectrum-chat>
```
#### Global Script (Template Integration)
```html
<script>
window.SpectrumChatConfig = {
apiUrl: 'https://your-api-domain.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
useJWT: true, // Enable JWT authentication
title: 'AI Assistant',
enableCitations: true
};
</script>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
```
### What Happens Behind the Scenes
**1. Session initialization (automatic on first message):**
```http
POST https://your-api-domain.com/api/v1/sessions
Origin: https://www.your-domain.com
Content-Type: application/json
{
"siteKey": "pub_customer_a1b2c3d4",
"pageUrlHash": "sha256_hash",
"nonce": "uuid"
}
```
**Response:**
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"expires_in": 3600,
"expires_at": "2025-10-06T13:00:00Z"
}
```
**2. Starting a conversation (with JWT token):**
```http
POST https://your-api-domain.com/api/v1/conversations
Origin: https://www.your-domain.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"siteKey": "pub_customer_a1b2c3d4",
"message": "What is your return policy?",
"citations": true,
"pageUrlHash": "sha256_hash",
"nonce": "uuid"
}
```
**3. Continuing a conversation (with JWT token):**
```http
POST https://your-api-domain.com/api/v1/conversations/c_abc123xyz
Origin: https://www.your-domain.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
{
"message": "How long do I have to return items?",
"citations": true
}
```
### Token Lifecycle
```
┌─────────────────────────────────────────────────────────────┐
│ Token Lifecycle │
└─────────────────────────────────────────────────────────────┘
1. User opens widget → Check existing token
↓
Token valid?
↙ ↘
Yes No
↓ ↓
Use token Create new session
↓ ↓
Send message ← Store token
↓
2. Token expires in < 5 min → Auto-refresh
↓
3. Token expired (401) → Refresh & retry
↓
4. Session cleared → Remove from storage
```
### Storage Strategy
The widget uses `sessionStorage` by default (recommended):
- ✅ Token cleared when browser tab closes
- ✅ Fresh session on new visit
- ✅ Better security (limited lifetime)
**Storage keys:**
- `spectrum-chat-token`: JWT token data
- `spectrum-chat-conversation-id`: Current conversation ID
- `spectrum-chat-messages`: Message history (optional)
## Configuration Guide
### All Configuration Options
| Option | Type | Default | Phase | Description |
|--------|------|---------|-------|-------------|
| `api-url` / `apiUrl` | string | Required | Both | API endpoint URL |
| `site-key` / `siteKey` | string | Required | Both | Public site key for origin validation |
| `use-jwt` / `useJWT` | boolean | `false` | 1 | Enable JWT session tokens |
| `tenant-id` / `tenantId` | string | Optional | Both | Legacy tenant ID (backward compatibility) |
| `citations` / `enableCitations` | boolean | `true` | Both | Include source citations in responses |
| `title` | string | `'AI Assistant'` | Both | Widget header title |
| `intro-text` / `introText` | string | Default | Both | Welcome message text |
| `debug` | boolean | `false` | Both | Enable debug logging |
### Full Configuration Example
```javascript
window.SpectrumChatConfig = {
// Security (Required)
apiUrl: 'https://your-api-domain.com/api/v1/conversations',
siteKey: 'pub_customer_a1b2c3d4',
useJWT: true, // Phase 1
// Features
enableCitations: true,
title: 'Customer Support',
introText: 'Hello! How can we help you today?',
// Styling
primaryColor: 'hsl(220 15% 25%)',
userColor: 'hsl(220 15% 45%)',
aiColor: 'hsl(220 15% 25%)',
fabIcon: '💬',
fabColor: 'hsl(220 15% 25%)',
position: 'bottom-right',
width: '380px',
height: '500px',
// Development
debug: false
};
```
## Usage Examples
### Example 1: Basic Integration (Phase 0)
```html
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome to My Website</h1>
<!-- Spectrum Chat Widget -->
<spectrum-chat
api-url="https://api.mysite.com/api/v1/conversations"
site-key="pub_mysite_x8k9p2"
title="Help Center"
citations="true">
</spectrum-chat>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
</body>
</html>
```
### Example 2: With JWT (Phase 1)
```html
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome to My Website</h1>
<!-- Spectrum Chat Widget with JWT -->
<spectrum-chat
api-url="https://api.mysite.com/api/v1/conversations"
site-key="pub_mysite_x8k9p2"
use-jwt="true"
title="Help Center"
citations="true"
debug="false">
</spectrum-chat>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
</body>
</html>
```
### Example 3: Global Mode with JWT
```html
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
<script>
window.SpectrumChatConfig = {
apiUrl: 'https://api.mysite.com/api/v1/conversations',
siteKey: 'pub_mysite_x8k9p2',
useJWT: true,
title: 'Customer Support',
enableCitations: true,
primaryColor: '#2563eb',
debug: false
};
</script>
</head>
<body>
<h1>Welcome to My Website</h1>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
</body>
</html>
```
### Example 4: Programmatic Control
```html
<script>
window.SpectrumChatConfig = {
apiUrl: 'https://api.mysite.com/api/v1/conversations',
siteKey: 'pub_mysite_x8k9p2',
useJWT: true,
enableCitations: true
};
</script>
<script src="https://unpkg.com/@spectrumsense/spectrum-chat@latest/dist/spectrum-chat.js"></script>
<script>
// Wait for widget to initialize
document.addEventListener('DOMContentLoaded', () => {
// Get widget API
const chat = window.SpectrumChatGlobal;
// Check token status
console.log('Token valid:', chat.isTokenValid());
console.log('Session ID:', chat.getSessionId());
console.log('Conversation ID:', chat.getConversationId());
// Programmatically open chat
setTimeout(() => {
chat.open();
}, 2000);
// Clear session (logout)
document.getElementById('logout-btn').addEventListener('click', () => {
chat.clearSession();
console.log('Session cleared');
});
});
</script>
```
## Security Features
### 1. Automatic Origin Validation
The browser automatically sends the `Origin` header with every cross-origin request. The API validates this against your allowed origins list.
**No configuration needed** - this happens automatically!
### 2. Conversation Binding
Each conversation is bound to the origin that created it. Attempting to continue a conversation from a different domain results in `403 Forbidden`.
### 3. Token Auto-Refresh
JWT tokens automatically refresh 5 minutes before expiration. If a token expires, the widget:
1. Detects the 401 error
2. Creates a new session
3. Retries the request
4. User never sees an error
### 4. Stale Conversation Handling
If a conversation expires from server cache (LRU eviction):
1. Widget detects 404 error
2. Clears stale conversation ID
3. Starts new conversation
4. Retries the user's message
5. User sees: "Starting a new conversation..."
### 5. Content Moderation
The API includes built-in content moderation. If a message is flagged:
- Response includes user-friendly message
- Widget displays the moderation message
- Conversation continues (not terminated)
### 6. HTTPS Enforcement
Production environments require HTTPS origins:
- ✅ `https://www.yoursite.com` - Allowed
- ❌ `http://www.yoursite.com` - Blocked
- ✅ `http://localhost:3000` - Allowed (development)
### 7. Telemetry & Tracking
The widget includes optional telemetry:
- `pageUrlHash`: SHA256 hash of current page URL
- `nonce`: UUID for request tracking
- Both are optional and privacy-friendly
## Error Handling
### User-Friendly Error Messages
The widget translates technical errors into user-friendly messages:
| Technical Error | User Message | Action |
|----------------|--------------|--------|
| Network error | "Unable to connect to chat service. Please check your internet connection." | Retry |
| 403 - Origin not allowed | "This domain is not authorized to use this chat service." | Contact support |
| 403 - HTTPS required | "This chat service requires a secure connection (HTTPS)." | Use HTTPS |
| 403 - Origin mismatch | "Session security error. Please refresh the page." | Refresh |
| 404 - Conversation expired | "Conversation expired. Starting a new conversation." | Auto-retry |
| 404 - Invalid site key | "Chat service is currently unavailable." | Contact support |
| 401 - Token expired | "Session expired. Please try again." | Auto-refresh |
| Content moderation | Custom message from API | Continue |
| 500 - Server error | "An error occurred. Please try again later." | Retry later |
### Debug Mode
Enable debug mode to see detailed logging:
```html
<spectrum-chat
api-url="..."
site-key="..."
debug="true">
</spectrum-chat>
```
Debug output includes:
- Configuration values
- API requests and responses
- Token status
- Conversation ID tracking
- Error details
## Best Practices
### 1. Use Phase 1 (JWT) for Production
While Phase 0 is sufficient, Phase 1 provides:
- ✅ Better audit trails
- ✅ Server-side revocation
- ✅ Time-limited access
- ✅ Enhanced security
### 2. Configure Allowed Origins Properly
Work with your API administrator to configure allowed origins:
```python
# Server-side configuration (example)
organization.allowed_origins = [
"https://www.yoursite.com",
"https://app.yoursite.com",
"https://yoursite.com"
]
```
**Include all variations:**
- With and without `www`
- All subdomains that will use the widget
- All environments (staging, production)
### 3. Use sessionStorage (Default)
The widget uses `sessionStorage` by default, which:
- ✅ Clears tokens when tab closes
- ✅ Provides fresh session on new visit
- ✅ Better security than localStorage
### 4. Monitor Token Expiration
For long user sessions, tokens will auto-refresh. Monitor in debug mode:
```javascript
const chat = window.SpectrumChatGlobal;
console.log('Token valid:', chat.isTokenValid());
console.log('Token data:', chat.getTokenData());
```
### 5. Handle Logout Properly
When user logs out of your app, clear the chat session:
```javascript
// On user logout
window.SpectrumChatGlobal.clearSession();
```
### 6. Test in Development
Use localhost for testing:
- ✅ `http://localhost:3000` - Works
- ✅ `http://127.0.0.1:8080` - Works
- HTTP is allowed for localhost
### 7. Enable Citations
Citations improve user trust and provide source verification:
```html
<spectrum-chat citations="true"></spectrum-chat>
```
## Troubleshooting
### Issue: "This domain is not authorized"
**Cause:** Origin not in allowed origins list
**Solution:**
1. Check your domain matches exactly (with/without www)
2. Verify HTTPS in production
3. Contact API administrator to add your domain
### Issue: "This chat service requires a secure connection"
**Cause:** Using HTTP in production
**Solution:**
1. Enable HTTPS on your website
2. For localhost development, use `http://localhost:3000`
### Issue: "Session expired" errors
**Cause:** Token expired and auto-refresh failed
**Solution:**
1. Check your internet connection
2. Verify API is reachable
3. Check browser console for errors
4. Clear session and retry: `SpectrumChatGlobal.clearSession()`
### Issue: Conversation keeps restarting
**Cause:** Conversation expired from server cache
**Solution:**
1. This is normal for LRU cache eviction
2. Increase server cache size if needed
3. Messages are automatically retried
### Issue: Widget not loading
**Cause:** Script loading error
**Solution:**
1. Check browser console for errors
2. Verify script URL is correct
3. Check for Content Security Policy (CSP) issues
4. Ensure unpkg.com is accessible
### Issue: Token not refreshing
**Cause:** `useJWT` not enabled or session creation failed
**Solution:**
1. Verify `use-jwt="true"` in configuration
2. Check API `/sessions` endpoint is accessible
3. Verify site key is valid
4. Check browser console for errors
## Migration from Legacy Version
If you're migrating from a version without security:
### Step 1: Add Site Key
```html
<!-- Before -->
<spectrum-chat
api-url="..."
tenant-id="...">
</spectrum-chat>
<!-- After (Phase 0) -->
<spectrum-chat
api-url="..."
site-key="pub_customer_a1b2c3d4"
tenant-id="...">
</spectrum-chat>
```
### Step 2: Configure Allowed Origins
Contact your API administrator to add your domain to the allowed origins list.
### Step 3: Test
1. Test on staging environment first
2. Verify widget loads and functions
3. Check for any error messages
4. Monitor browser console
### Step 4: Enable JWT (Optional)
```html
<spectrum-chat
api-url="..."
site-key="pub_customer_a1b2c3d4"
use-jwt="true">
</spectrum-chat>
```
See [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) for detailed migration instructions.
## API Reference
For detailed API methods and properties, see [API_REFERENCE.md](./API_REFERENCE.md).
## Support
For issues or questions:
1. Check this documentation
2. Review the [Troubleshooting](#troubleshooting) section
3. Enable debug mode for detailed logging
4. Contact the Spectrum Chat support team
**Last Updated:** October 6, 2025
**Version:** 1.0.0