Authentication
My Dashboard API uses API key authentication to secure access to endpoints and protect against unauthorized usage.
API Key Authentication
How It Works
API keys are passed via the x-api-key
HTTP header:
curl -H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
"http://localhost:3000/api/apps"
Security Features
- Constant-time comparison: Prevents timing attacks
- Rate limiting: Protects against brute force attempts
- IP-based blocking: Automatic blocking of abusive IPs
- Request logging: Failed attempts are logged for monitoring
Obtaining an API Key
API keys are configured server-side via the API_SECURITY_KEY
environment variable. Contact your system administrator to:
- Request Access: Provide your use case and required permissions
- Receive Key: Get your unique API key securely
- Test Access: Validate your key using the validation endpoint
Validating Your API Key
Use the validation endpoint to test your API key:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"apiKey": "YOUR_API_KEY"}' \
"http://localhost:3000/api/auth/validate"
Success Response:
{
"valid": true,
"message": "API key is valid"
}
Error Response:
{
"valid": false,
"message": "Invalid API key"
}
Rate Limiting & Protection
Authentication Endpoints
Authentication endpoints have special protection:
- Rate Limit: 3 attempts per 15-minute window per IP
- Progressive Delays: Increasing delays after failed attempts
- IP Blocking: Temporary blocks for persistent abuse
- Security Headers: Additional security headers applied
Failed Attempt Handling
When authentication fails:
- Attempt Recorded: Failed attempt is logged with IP and timestamp
- Counter Incremented: Failure count increases for the IP
- Delay Applied: Progressive delay before next attempt allowed
- Blocking Triggered: After threshold, IP is temporarily blocked
Rate Limit Response
When rate limited, you'll receive:
{
"error": "Too many failed attempts. Try again in 10 minutes.",
"retryAfter": 600
}
Public Endpoints
These endpoints do not require authentication:
Health Check
GET /health
No authentication required. Returns server status.
API Key Validation
POST /api/auth/validate
Used to validate API keys. The key is provided in the request body, not headers.
Protected Endpoints
All other endpoints require the x-api-key
header:
/api/apps/*
- Application management/api/e2e_reports/*
- E2E test reports/api/pull_requests/*
- Pull request tracking/api/notifications/*
- Notification management/api/internal/*
- Internal administration
Best Practices
Secure Storage
- Environment Variables: Store API keys in environment variables
- Secret Management: Use proper secret management systems in production
- Never Commit: Never commit API keys to version control
# Good: Environment variable
export MY_DASHBOARD_API_KEY="your-key-here"
# Good: .env file (not committed)
MY_DASHBOARD_API_KEY=your-key-here
# Bad: Hardcoded in source
const apiKey = "abc123-secret-key"; // DON'T DO THIS
Error Handling
Always handle authentication errors gracefully:
async function apiRequest(endpoint, options = {}) {
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
...options,
headers: {
'x-api-key': process.env.MY_DASHBOARD_API_KEY,
'Content-Type': 'application/json',
...options.headers,
},
});
if (response.status === 401) {
throw new Error('Invalid API key - check your credentials');
}
if (response.status === 429) {
const data = await response.json();
throw new Error(`Rate limited - retry after ${data.retryAfter} seconds`);
}
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('API request failed:', error.message);
throw error;
}
}
Retry Logic
Implement proper retry logic for rate-limited requests:
async function apiRequestWithRetry(endpoint, options = {}, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await apiRequest(endpoint, options);
} catch (error) {
if (error.message.includes('Rate limited') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
continue;
}
throw error;
}
}
}
Request Logging
Log API requests for debugging and monitoring:
function logApiRequest(endpoint, method = 'GET', success = true) {
console.log(`[API] ${method} ${endpoint} - ${success ? 'SUCCESS' : 'FAILED'}`);
}
Troubleshooting
Common Issues
401 Unauthorized
- Check that your API key is correct
- Verify the
x-api-key
header is being sent - Ensure the key hasn't been revoked
429 Too Many Requests
- Wait for the retry period to expire
- Implement exponential backoff in your client
- Check if your IP has been temporarily blocked
403 Forbidden
- Your API key may not have permission for this endpoint
- Contact your administrator to verify permissions
Testing Authentication
Use these commands to test your authentication setup:
# Test health endpoint (no auth required)
curl "http://localhost:3000/health"
# Test API key validation
curl -X POST \
-H "Content-Type: application/json" \
-d '{"apiKey": "YOUR_API_KEY"}' \
"http://localhost:3000/api/auth/validate"
# Test protected endpoint
curl -H "x-api-key: YOUR_API_KEY" \
"http://localhost:3000/api/apps"
Debug Headers
Include debug information in your requests:
curl -v \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
"http://localhost:3000/api/apps"
The -v
flag shows request/response headers for debugging.
Security Considerations
- HTTPS Only: Always use HTTPS in production
- Key Rotation: Regularly rotate API keys
- Monitoring: Monitor for unusual API usage patterns
- Logging: Keep audit logs of API access
- Principle of Least Privilege: Only grant necessary permissions