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 publishable keys
<CyborgProvider config={{ publishableKey: "cpk_live_ak1nDk3jF9sL2mP0qR8tU7vW5xY6zB4cE3fG2hI1jK0" }} />

Good:

typescript
// ✅ Use environment variables
<CyborgProvider config={{ publishableKey: process.env.REACT_APP_CYBORG_PUBLISHABLE_KEY }} />

2. Store Keys in Environment Variables ​

Development (.env.local):

bash
REACT_APP_CYBORG_PUBLISHABLE_KEY=cpk_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:  cpk_test_...
Staging:      cpk_test_...
Production:   cpk_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 UI → API 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 Settings → Data 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 Settings → Delete 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 Settings → Audit 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 = 'cpk_live_xxx';

// Bad: Key in config file
export const config = { apiKey: 'cpk_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