Security Overview
earnlayer is secure by design with multiple layers of protection
Secure by Design
Key Security Features
API Keys Never Exposed
All API calls go through your Next.js backend proxy
// app/api/earnlayer/[...slug]/route.ts
import { createEarnLayerProxy } from '@earnlayer/sdk/nextjs';
const handler = createEarnLayerProxy({
apiKey: process.env.EARNLAYER_API_KEY
});
export { handler as GET, handler as POST };
const handler = createEarnLayerProxy({
apiKey: process.env.EARNLAYER_API_KEY
});
export { handler as GET, handler as POST };
Your
EARNLAYER_API_KEY stays in .env.local and never reaches the browser.Server-to-Server Authentication
The proxy endpoint handles JWT authentication automatically
1
Browser requests ad → Your proxy endpoint2
Your proxy → earnlayer API (with API key)3
earnlayer returns JWT token4
Proxy forwards response → Browser (no API key)No CORS Configuration Needed
All requests are same-origin (your domain)
Browser → yoursite.com/api/earnlayer → earnlayer API
No cross-origin requests = no CORS vulnerabilities.
Click Tracking via Backend Redirects
Ad URLs include backend redirects for secure tracking
// ad.url format:
https://api.earnlayerai.com/redirect?
impression_id=imp_123&
target=https://example.com
impression_id=imp_123&
target=https://example.com
Clicks are tracked server-side before redirecting to the advertiser.
Environment Variables
Environment Variables
Required variables and where they're used
# .env.local (NEVER commit this file)
# Server-side only (used in proxy endpoint)
EARNLAYER_API_KEY=el_your_api_key_here
# Server-side only (used in chat API route for MCP)
EARNLAYER_MCP_URL=https://mcp.earnlayerai.com/mcp
# Your LLM provider keys (server-side only)
OPENAI_API_KEY=sk_your_openai_key_here
# OR
GOOGLE_API_KEY=your_google_api_key_here
| Variable | Used In | Exposed to Browser? |
|---|---|---|
| EARNLAYER_API_KEY | Proxy endpoint, MCP server | No |
| EARNLAYER_MCP_URL | Chat API route | No |
| OPENAI_API_KEY | Chat API route | No |
| GOOGLE_API_KEY | Chat API route | No |
All keys are server-side only. They never reach the browser.
Best Practices
DO
- Store API keys in
.env.local - Add
.env.localto.gitignore - Use the proxy endpoint for all SDK calls
- Keep SDK updated for security patches
- Rotate API keys periodically
DON'T
- Hardcode API keys in code
- Commit
.env.localto git - Use API keys in client-side code
- Share API keys publicly
- Expose API keys in browser console logs
Verifying Security
Check 1: No API Keys in Browser
Open browser DevTools → Network tab → Check any
/api/earnlayer/* requests:Request Headers:
Content-Type: application/json
Request Body:
{ "conversationId": "conv_123" }
No
x-api-key or EARNLAYER_API_KEY should appear in browser requests.Check 2: Environment Variables Not in Bundle
Check your built JavaScript:
npm run build
# Search the build output:
grep -r "el_" .next/
No API keys should appear in the build output.
Check 3: Proxy Endpoint Working
Test the proxy endpoint:
curl -X POST http://localhost:3000/api/earnlayer/initialize \
-H "Content-Type: application/json"
Should return
{ "conversation_id": "..." } without errors.Security Checklist
Security Checklist
Before deploying to production
All API keys in .env.local (not .env)
.env.local added to .gitignore
No API keys hardcoded in source code
Proxy endpoint created and working
All SDK calls go through proxy
No API keys visible in browser DevTools
Environment variables set in production hosting platform
Reporting Security Issues
Found a security vulnerability? Email us at support@earnlayerai.com
Please do not create public issues for security vulnerabilities.