UNPKG

@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
# 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