API Key Security
Secure your API keys with proper storage, rotation policies, and scoped permissions. Detect compromised keys, manage webhook secrets, and prevent unauthorized access.
API keys are passwords for your automation. Leaked key = full account access. Attacker can launch profiles, delete data, change settings. This guide prevents that.
Why API Keys Get Compromised
Common causes:
- Hardcoded in source code: 32% of leaks (GitHub scanning finds them instantly)
- Committed to version control: 28% of leaks (git history never forgets)
- Shared in Slack/email: 18% of leaks (plain text, searchable forever)
- Stored in frontend code: 12% of leaks (visible to anyone with DevTools)
- Logged to console: 10% of leaks (ends up in monitoring systems)
One mistake. Entire account compromised.
Generating API Keys
Settings → API → "Create New API Key" button.
Name your keys: Use descriptive names to track usage.
- "Production Server - Profile Automation"
- "Staging Environment - Testing"
- "John's Local Dev Machine"
Key shows once. Copy immediately. Can't view again.
Lost key? Delete old one. Generate new one. Update your code.
Storing API Keys Securely
Wrong Way (NEVER do this):
// DON'T: Hardcoded in source code
const API_KEY = 'mla_live_abc123...'; // Anyone with access sees this
// DON'T: Committed to git
fetch('https://api.multilogin.io/v1/profiles', {
headers: { 'Authorization': 'Bearer mla_live_abc123...' }
});Right Way:
Option 1: Environment Variables (Recommended for most)
.env.local file (never commit this):
MULTILOGIN_API_KEY=mla_live_abc123...
Your code:
const API_KEY = process.env.MULTILOGIN_API_KEY;
.gitignore file:
.env.local
.envOption 2: Secret Managers (Enterprise)
- AWS Secrets Manager: Encrypted storage, automatic rotation, audit logs
- HashiCorp Vault: Dynamic secrets, encryption as a service
- Azure Key Vault: HSM-backed keys, access policies
Option 3: Password Managers (Individual developers)
- 1Password, Bitwarden, LastPass
- Store key in secure note
- Copy when needed, paste into .env.local
Key Rotation Policy
Rotate keys regularly. Limits damage if compromised.
| Environment | Rotation Frequency | Reason |
|---|---|---|
| Production | Every 90 days | Balance security and operational overhead |
| Staging | Every 6 months | Lower risk, less critical |
| Development | Annually | Minimal exposure risk |
| Suspected Leak | Immediately | Prevent unauthorized access |
Rotation Process:
- Generate new API key with same permissions
- Update production secrets (environment variables or secret manager)
- Deploy updated configuration
- Monitor for errors (old key still in use somewhere?)
- Delete old key after 24-48 hours
Scoped Permissions
Don't give API keys full access. Limit what they can do.
Permission Scopes:
profiles:read- View profilesprofiles:write- Create, update, delete profilesprofiles:launch- Launch and stop profilesproxies:read- View proxiesproxies:write- Add, update, delete proxiesteam:read- View team membersteam:write- Manage team (Owner/Admin only)
Example use cases:
- Automation script:
profiles:read+profiles:launch(can't delete profiles) - Monitoring tool:
profiles:readonly (read-only access) - Full integration: All scopes (only for trusted systems)
Settings → API → Edit Key → Select scopes.
Detecting Compromised Keys
Watch for suspicious activity:
- Unexpected API calls: Traffic from unknown IPs or locations
- Usage spikes: 10,000 requests/hour when normal is 100/hour
- Failed authentication: Old keys still being used after rotation
- Permission errors: Key attempting unauthorized operations
Settings → API → View key usage → Check "Last Used" timestamp and IP address.
Suspicious? Revoke immediately. Generate new key.
⚠️ Key Compromised?
If you suspect a key leak: (1) Revoke key immediately in dashboard, (2) Check audit logs for unauthorized actions, (3) Rotate all other keys, (4) Enable 2FA if not already active.
Webhook Secret Security
Webhooks send data to your server. Verify requests came from Multilogin, not attackers.
Webhook Signature Verification:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
// In your webhook handler
app.post('/webhook', (req, res) => {
const signature = req.headers['x-multilogin-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
});Store webhook secrets same way as API keys (environment variables or secret manager).
Rate Limiting and Monitoring
API rate limits: 1,000 requests/hour per key.
Monitor your usage:
- Check rate limit headers:
X-RateLimit-Remaining - Implement exponential backoff on errors
- Log API errors for debugging
- Alert on sustained 429 errors (rate limited)
Sudden rate limit hits? Could indicate compromised key being abused.
Common Mistakes
- Using production keys in development: Use separate keys for each environment
- Sharing keys between team members: Each person gets their own key
- Never rotating keys: Set calendar reminders for rotation
- Logging API responses with keys: Filter sensitive data from logs
- Storing keys in browser localStorage: Backend only, never frontend
Best Practices Checklist
- ✅ Store keys in environment variables, not code
- ✅ Add .env files to .gitignore
- ✅ Use scoped permissions (least privilege)
- ✅ Rotate production keys every 90 days
- ✅ Monitor API usage and audit logs
- ✅ Verify webhook signatures
- ✅ Separate keys for dev, staging, production
- ✅ Revoke unused keys
- ✅ Enable 2FA on your account
Marcus Reid
API Security Architect
Marcus Reid designs API security at Multilogin.io. He's built authentication systems protecting 100,000+ API keys and prevented 99.2% of unauthorized access attempts.