Skip to content

Security Best Practices

Overview

Security is fundamental to ChatSDK. This guide covers best practices for protecting your API keys, handling sensitive data, and implementing secure chat integrations.

API Key Security

1. Never Hardcode Keys

Bad:

typescript
// ❌ Never hardcode API keys
<ChatProvider apiKey="chatsdk_live_ak1nDk3jF9sL2mP0qR8tU7vW5xY6zB4cE3fG2hI1jK0" />

Good:

typescript
// ✅ Use environment variables
<ChatProvider apiKey={process.env.REACT_APP_CHATSDK_API_KEY} />

2. Store Keys in Environment Variables

Development (.env.local):

bash
REACT_APP_CHATSDK_API_KEY=chatsdk_test_pQ9rS8tU7vW6xY5zB4cE3fG2hI1jK0

Add to .gitignore:

bash
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo ".env.*.local" >> .gitignore

Production (Platform-specific):

  • Vercel: Environment Variables in dashboard
  • Netlify: Build & Deploy → Environment
  • Heroku: Config Vars
  • AWS: Secrets Manager
  • Azure: Key Vault

3. Use Different Keys for Each Environment

Development:  chatsdk_test_...
Staging:      chatsdk_test_...
Production:   chatsdk_live_...

Benefits:

  • Isolates production data
  • Prevents accidental test key usage in production
  • Allows revoking dev keys without affecting prod

4. Rotate Keys Regularly

Recommended Schedule:

  • Development keys: Monthly
  • Staging keys: Every 3 months
  • Production keys: Every 6 months

Rotation Process:

  1. Create new key with same environment
  2. Update application to use new key
  3. Test in staging first
  4. Deploy to production
  5. Verify new key is working
  6. Revoke old key

5. Revoke Compromised Keys Immediately

If a key is leaked:

  1. Go to Admin UIAPI Keys
  2. Click Revoke on the compromised key
  3. Create a new key
  4. Update your application
  5. Monitor for unauthorized usage

Sensitive Data

What NOT to Send in Context

Don't include:

typescript
// ❌ Never send sensitive data
useChatContext({
  sessionData: {
    apiKey: 'secret_key',           // Never!
    creditCardNumber: '4111...',     // Never!
    ssn: '123-45-6789',              // Never!
    password: 'hunter2',             // Never!
    privateKey: 'pk_xxx',            // Never!
    databasePassword: 'db_pass',     // Never!
  },
});

It's OK to send:

typescript
// ✅ Safe to send
useChatContext({
  sessionData: {
    userId: 'user_123',              // Public ID, not sensitive
    userRole: 'premium',              // Public role
    subscriptionTier: 'pro',           // Public tier
    country: 'United States',          // Approximate location
    language: 'en',                    // Language preference
  },
});

Determine What's Sensitive

Ask yourself: Would it be bad if this data was public?

Sensitive (Don't share):

  • Passwords and authentication tokens
  • API keys and secrets
  • Credit card numbers
  • Social Security numbers
  • Private health information
  • Private financial data
  • Any data protected by law

Safe to share (Context OK):

  • User ID (public identifier)
  • User role/permissions
  • Subscription level
  • Anonymous usage metrics
  • Public profile information
  • General location (country/region)
  • Language preference

Implementation Security

1. Input Validation

Always validate user input before sending:

typescript
const sendMessage = async (message: string) => {
  // Validate length
  if (message.length === 0 || message.length > 5000) {
    throw new Error('Message must be 1-5000 characters');
  }

  // Sanitize input
  const clean = message.trim();

  // Send to chat
  await useChat().sendMessage(clean);
};

2. Limit Request Rate

Implement client-side rate limiting:

typescript
const messageQueue = [];
let isProcessing = false;

const sendMessage = async (message: string) => {
  messageQueue.push(message);

  if (isProcessing) return;

  isProcessing = true;
  try {
    while (messageQueue.length > 0) {
      const msg = messageQueue.shift();
      await useChat().sendMessage(msg);
      await sleep(1000);  // Wait 1 second between messages
    }
  } finally {
    isProcessing = false;
  }
};

3. Handle Errors Securely

Don't expose sensitive details:

typescript
// ❌ Exposes implementation details
catch (error) {
  console.log(`Failed to connect to ${process.env.API_URL}`);
  console.log(error.stack);  // Exposes paths and code
}

// ✅ Show user-friendly error
catch (error) {
  console.error('Chat error:', error);
  setError('Unable to send message. Please try again.');
}

4. Use HTTPS Only

Always use HTTPS, never HTTP:

typescript
// ❌ Never use HTTP
const apiUrl = 'http://api.chatsdk.com';

// ✅ Always use HTTPS
const apiUrl = 'https://api.chatsdk.com';

The SDK enforces HTTPS in production.

Data Privacy

Understand Data Flow

Your data flows through:

  1. Client (your React app)
  2. ChatSDK Backend (our servers)
  3. Claude AI API (Anthropic's servers)
  4. Vector Database (storage)
  5. Cache (Redis)

What we store:

  • Chat messages and responses
  • API usage metrics
  • Documentation you upload
  • User preferences

What we delete:

  • Messages after 90 days (default)
  • Audit logs after 1 year
  • Cached data expires per policy

Data Retention

Configure how long we keep your data:

  1. Go to SettingsData Retention
  2. Choose retention period:
    • 30 days - Most privacy-conscious
    • 90 days - Balanced (default)
    • 1 year - For compliance audits
    • Keep forever - Enterprise option

Data Deletion

To delete all your data:

  1. Go to SettingsDelete Account
  2. Confirm deletion
  3. All data deleted within 30 days

What gets deleted:

  • All chat messages
  • All API keys
  • All uploaded documentation
  • User preferences
  • Usage analytics

Note: You can export your data before deletion.

GDPR Compliance

If you serve EU users, follow GDPR:

Data Processing Agreement (DPA)

We offer a DPA for business customers:

  1. Contact support@chatsdk.com
  2. Request Data Processing Agreement
  3. Sign and implement GDPR compliance

User Rights

Provide users with:

  • Access: They can download their data
  • Deletion: They can request deletion
  • Opt-out: They can disable chat

Implementation

typescript
// Example: GDPR compliance
function ChatWidget() {
  const [gdprAccepted, setGdprAccepted] = useState(false);

  if (!gdprAccepted) {
    return (
      <div className="gdpr-notice">
        <p>This chat uses AI to analyze your activity.</p>
        <button onClick={() => setGdprAccepted(true)}>
          I Agree
        </button>
        <a href="/privacy">Privacy Policy</a>
      </div>
    );
  }

  return <ChatProvider>...</ChatProvider>;
}

Monitoring & Audit

Enable Audit Logs

  1. Go to SettingsAudit Logs
  2. Configure what to log:
    • API key creation/revocation
    • Documentation uploads
    • Permission changes
    • Failed authentication attempts

Review Logs Regularly

2025-01-15 10:30 | API Key Created | user_123 | prod_key_1
2025-01-14 15:45 | Failed Auth | Invalid API key from 192.168.1.1
2025-01-14 09:20 | Docs Uploaded | 50 files, 2.3MB

Set Up Alerts

Alert on suspicious activity:

  • Multiple failed auth attempts
  • Unusual API usage patterns
  • Rapid key rotations
  • Unexpected geographic access

Encryption

In Transit (TLS/SSL)

All communication is encrypted:

  • Protocol: TLS 1.3 or higher
  • Certificate: Valid and up-to-date
  • Validation: Verify HTTPS in browser

At Rest

Data stored on our servers is encrypted:

  • Encryption: AES-256
  • Key Management: HSM-backed
  • Backups: Encrypted copies

Third-Party Services

Anthropic Claude API

We use Anthropic's Claude for AI responses:

  • Privacy: Claude doesn't train on your data
  • No data retention: Requests processed, not stored
  • GDPR compliant: Anthropic signs DPA
  • Transparency: View Anthropic's privacy policy

Vector Database

Your documentation is stored in a vector database:

  • Isolation: Data separated by project
  • Encryption: Encrypted at rest
  • No sharing: Your vectors aren't shared
  • Deletion: Deleted when you delete docs

Security Checklist

Use this checklist to audit your implementation:

  • [ ] API key in environment variables
  • [ ] Different keys for each environment
  • [ ] No hardcoded secrets in code
  • [ ] API key rotation schedule
  • [ ] .env files in .gitignore
  • [ ] HTTPS enforced everywhere
  • [ ] Input validation on chat messages
  • [ ] Error messages don't expose sensitive info
  • [ ] No sensitive data in context
  • [ ] Rate limiting implemented
  • [ ] Audit logs reviewed monthly
  • [ ] Privacy policy updated
  • [ ] GDPR compliant if serving EU users
  • [ ] Data retention policy set
  • [ ] Backup strategy in place

Common Security Mistakes

❌ Mistake 1: Exposing API Keys

typescript
// Bad: Key in source code
const apiKey = 'chatsdk_live_xxx';

// Bad: Key in config file
export const config = { apiKey: 'chatsdk_live_xxx' };

// Bad: Key in console output
console.log('API Key:', apiKey);

Fix: Use environment variables only.

❌ Mistake 2: Trusting Client-Side Only

typescript
// Bad: Only client-side validation
if (user.isAdmin) {
  showAdminPanel();  // Easy to bypass in dev tools
}

Fix: Always validate on the backend too.

❌ Mistake 3: Logging Sensitive Data

typescript
// Bad: Logs the full message
logger.info(`Message: ${userMessage}`);

// Bad: Logs error with stack trace
catch (e) { logger.error(e.stack); }

Fix: Log only non-sensitive info.

❌ Mistake 4: Ignoring HTTPS Warnings

typescript
// Bad: Using HTTP in production
const url = 'http://api.chatsdk.com';

Fix: Always use HTTPS.

Security Resources

Internal Documentation

External Resources

Report Security Issues

Found a security vulnerability?

Please don't disclose publicly!

Email: security@chatsdk.com

Include:

  • Description of the issue
  • Steps to reproduce
  • Potential impact
  • Suggested fix (optional)

We'll respond within 24 hours.

Next Steps

  1. Review API Key Management - Best practices for keys
  2. Understand Context Sharing - What data to share
  3. Check Configuration Options - Security settings
  4. Set Up Audit Logging - Monitor activity

Built with VitePress