Security Best Practices
Keep your Resync integration secure.
API Key Management
Never Hardcode API Keys
// ❌ Bad
const apiKey = 'rsk_live_abc123def456';
// ✅ Good
const apiKey = process.env.RESYNC_API_KEY;
Use Environment Variables
.env file (NOT in version control):
RESYNC_API_KEY=your-api-key-here
RESYNC_APP_ID=7
.gitignore:
.env
.env.local
.env.production
Separate Keys by Environment
- Development:
rsk_sandbox_dev123 - Staging:
rsk_sandbox_stage456 - Production:
rsk_live_prod789
Key Rotation
Rotate keys periodically:
- Create new API key in dashboard
- Update environment variables
- Deploy to all environments
- Monitor for errors
- Delete old key after 7 days
Client vs Server
Publishable Keys (Client-Side)
Safe for client-side use:
- Read-only operations
- Get config
- Log events
- Get variants
// ✅ Safe in browser/mobile
Resync.init({
key: 'rsk_live_abc123', // Publishable key
// ...
});
Secret Keys (Server-Side Only)
Never expose in client code:
- Create/update campaigns
- Manage content
- Delete data
- Admin operations
// ✅ Only on server
const resyncAdmin = new ResyncAdmin({
secretKey: process.env.RESYNC_SECRET_KEY,
});
Data Privacy
User Data
Minimize PII (Personally Identifiable Information):
// ❌ Bad - Excessive PII
await Resync.setUserAttributes({
email: 'user@example.com',
phone: '+1234567890',
ssn: '123-45-6789', // Never!
creditCard: '4111111111111111', // Never!
});
// ✅ Good - Minimal, necessary data
await Resync.setUserAttributes({
attributes: {
userTier: 'premium',
country: 'US',
},
});
Event Metadata
Don't log sensitive data:
// ❌ Bad
Resync.logEvent({
eventId: 'payment_processed',
metadata: {
cardNumber: '4111111111111111', // Never!
cvv: '123', // Never!
},
});
// ✅ Good
Resync.logEvent({
eventId: 'payment_processed',
metadata: {
paymentMethod: 'visa',
last4: '1111',
amount: 99.99,
},
});
Network Security
Use HTTPS
Always use HTTPS in production:
// ✅ Automatic with Resync
// All API calls use HTTPS
Validate Webhooks
Verify webhook signatures:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(JSON.stringify(payload.data));
const expectedSignature = `sha256=${hmac.digest('hex')}`;
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
app.post('/webhook', (req, res) => {
const signature = req.headers['x-resync-signature'];
const payload = req.body;
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
res.sendStatus(200);
});
Access Control
Principle of Least Privilege
Grant minimum necessary permissions:
- Developers: Sandbox access only
- QA: Staging access
- Ops: Production read-only
- Admins: Full access
Team Management
Use Resync's team features:
- Invite team members
- Assign roles
- Review permissions regularly
- Remove access when no longer needed
Compliance
GDPR
Resync is GDPR compliant. To help you comply:
- Data Minimization: Only collect necessary data
- Right to Access: Use API to retrieve user data
- Right to Deletion: Delete user data via API
- Consent: Get user consent before tracking
// Delete user data
async function deleteUserData(userId) {
await fetch(`https://api.getresync.com/v1/users/${userId}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${process.env.RESYNC_SECRET_KEY}`,
},
});
}
CCPA
Similar considerations for California users.
Security Checklist
- API keys in environment variables
- Keys not in version control
- Separate keys per environment
- Regular key rotation
- Minimal PII collection
- No sensitive data in events
- HTTPS everywhere
- Webhook signature verification
- Principle of least privilege
- Regular security audits
Incident Response
If API key is compromised:
- Immediately: Delete key in dashboard
- Create: New API key
- Update: Environment variables
- Deploy: To all environments
- Monitor: For suspicious activity
- Document: Incident for review