Kindly API Authentication Guide¶
Overview¶
The Kindly API uses two primary authentication methods to ensure secure access:
- JWT Bearer Tokens - For user sessions and temporary access
- API Keys - For long-term programmatic access
Both methods provide full access to the API, but have different use cases and security characteristics.
JWT Bearer Token Authentication¶
JWT (JSON Web Token) authentication is ideal for: - Web applications with user sessions - Mobile applications - Short-lived access requirements - Scenarios requiring user-specific permissions
Registration¶
Create a new user account:
curl -X POST https://api.kindly.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecureP@ssw0rd!",
"name": "John Doe"
}'
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"created_at": "2024-01-08T12:00:00Z"
}
}
Login¶
Authenticate an existing user:
curl -X POST https://api.kindly.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecureP@ssw0rd!"
}'
Using the Access Token¶
Include the access token in the Authorization header:
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
https://api.kindly.com/api/compression/stats
Token Refresh¶
Access tokens expire after 1 hour. Use the refresh token to obtain a new access token:
curl -X POST https://api.kindly.com/api/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'
Logout¶
Invalidate the current session:
curl -X POST https://api.kindly.com/api/auth/logout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
JWT Token Structure¶
Our JWT tokens contain:
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"name": "John Doe",
"iat": 1704720000,
"exp": 1704723600,
"jti": "unique-token-id"
}
}
API Key Authentication¶
API Keys are ideal for: - Server-to-server communication - CI/CD pipelines - Long-running services - Automated scripts
Creating an API Key¶
First, authenticate with JWT, then create an API key:
curl -X POST https://api.kindly.com/api/keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Server",
"expires_at": "2025-01-08T00:00:00Z"
}'
Response:
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"key": "kapi_prod_7f3d9a2b5c1e4890abcdef1234567890",
"name": "Production Server",
"expires_at": "2025-01-08T00:00:00Z"
}
Important: The key field is only shown once. Store it securely!
Using API Keys¶
Include the API key in the X-API-Key header:
curl -H "X-API-Key: kapi_prod_7f3d9a2b5c1e4890abcdef1234567890" \
https://api.kindly.com/api/compression/stats
API Key Format¶
API keys follow a consistent format: - Prefix: kapi_ - Environment: prod_, test_, dev_ - Random string: 32 characters
Example: kapi_prod_7f3d9a2b5c1e4890abcdef1234567890
Managing API Keys¶
List all your API keys:
Revoke an API key:
curl -X DELETE https://api.kindly.com/api/keys/660e8400-e29b-41d4-a716-446655440001 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Security Best Practices¶
1. Secure Storage¶
Never store credentials in: - Source code - Version control - Client-side code - Unencrypted databases - Log files
Do store credentials in: - Environment variables - Secure key management services (AWS KMS, HashiCorp Vault) - Encrypted configuration files - Operating system keychains
2. Key Rotation¶
Regularly rotate your credentials:
import os
from datetime import datetime, timedelta
class KeyRotationManager:
def __init__(self, api_client):
self.api_client = api_client
self.rotation_interval = timedelta(days=90)
def should_rotate(self, key_created_at):
age = datetime.utcnow() - key_created_at
return age > self.rotation_interval
def rotate_api_key(self, old_key_id):
# Create new key
new_key = self.api_client.create_api_key({
"name": f"Rotated key - {datetime.utcnow().isoformat()}"
})
# Update application configuration
os.environ['KINDLY_API_KEY'] = new_key['key']
# Schedule old key deletion (grace period)
self.schedule_key_deletion(old_key_id, delay_hours=24)
return new_key
3. Least Privilege¶
Create specific API keys for different purposes:
// Development key with limited permissions
const devKey = await createApiKey({
name: "Development - Local Testing",
permissions: ["read:compression", "read:context"],
ip_whitelist: ["127.0.0.1", "::1"],
expires_at: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) // 7 days
});
// Production key with full permissions
const prodKey = await createApiKey({
name: "Production - Main Service",
permissions: ["*"],
ip_whitelist: ["52.44.123.456", "52.44.123.457"],
expires_at: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) // 1 year
});
4. Request Signing (Advanced)¶
For additional security, sign your requests:
import hmac
import hashlib
import time
import json
class SignedRequestClient:
def __init__(self, api_key, api_secret):
self.api_key = api_key
self.api_secret = api_secret
def create_signature(self, method, path, body=None):
timestamp = str(int(time.time()))
nonce = os.urandom(16).hex()
# Create message to sign
message_parts = [method, path, timestamp, nonce]
if body:
message_parts.append(json.dumps(body, sort_keys=True))
message = ''.join(message_parts)
# Create HMAC signature
signature = hmac.new(
self.api_secret.encode(),
message.encode(),
hashlib.sha256
).hexdigest()
return {
'X-API-Key': self.api_key,
'X-Timestamp': timestamp,
'X-Nonce': nonce,
'X-Signature': signature
}
5. IP Whitelisting¶
Restrict API key usage to specific IP addresses:
# Configure IP restrictions when creating key
api_key = client.create_api_key(
name: "Production Server",
allowed_ips: [
"203.0.113.0/24", # Production subnet
"198.51.100.42" # Backup server
],
denied_ips: [
"192.168.0.0/16", # Block all private IPs
"10.0.0.0/8"
]
)
CSRF Protection¶
For browser-based applications, implement CSRF protection:
1. Get CSRF Token¶
const response = await fetch('https://api.kindly.com/api/csrf-token', {
credentials: 'include'
});
const { csrf_token } = await response.json();
2. Include in State-Changing Requests¶
const result = await fetch('https://api.kindly.com/api/compression/compress', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'X-CSRF-Token': csrf_token,
'Content-Type': 'application/json'
},
body: JSON.stringify(data),
credentials: 'include'
});
OAuth 2.0 Integration (Coming Soon)¶
We're implementing OAuth 2.0 for third-party integrations:
// Future OAuth flow
const authUrl = `https://api.kindly.com/oauth/authorize?
client_id=${CLIENT_ID}&
redirect_uri=${REDIRECT_URI}&
response_type=code&
scope=read:compression write:compression&
state=${STATE}`;
// After user authorization, exchange code for token
const tokenResponse = await fetch('https://api.kindly.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
grant_type: 'authorization_code',
code: authorizationCode,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
redirect_uri: REDIRECT_URI
})
});
Multi-Factor Authentication (MFA)¶
Enable MFA for enhanced security:
1. Enable MFA¶
Response includes QR code for authenticator apps.
2. Login with MFA¶
curl -X POST https://api.kindly.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecureP@ssw0rd!",
"mfa_code": "123456"
}'
Service Accounts¶
For automated systems, use service accounts:
# Create service account
service_account = api.create_service_account({
"name": "analytics-processor",
"description": "Automated analytics processing service",
"permissions": [
"read:analytics",
"write:analytics",
"read:compression"
]
})
# Service account authentication
service_client = KindlyAPIClient(
service_account_id=service_account['id'],
private_key=service_account['private_key']
)
Webhook Authentication¶
Verify webhook signatures to ensure authenticity:
func VerifyWebhookSignature(payload []byte, signature string, secret string) bool {
expectedSig := hmac.New(sha256.New, []byte(secret))
expectedSig.Write(payload)
expected := hex.EncodeToString(expectedSig.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signature))
}
// In your webhook handler
func HandleWebhook(w http.ResponseWriter, r *http.Request) {
payload, _ := ioutil.ReadAll(r.Body)
signature := r.Header.Get("X-Kindly-Signature")
if !VerifyWebhookSignature(payload, signature, webhookSecret) {
http.Error(w, "Invalid signature", http.StatusUnauthorized)
return
}
// Process webhook...
}
Troubleshooting¶
Common Authentication Errors¶
| Error Code | Description | Solution |
|---|---|---|
AUTH_001 | Invalid credentials | Check email/password |
AUTH_002 | Token expired | Refresh token or re-login |
AUTH_003 | Invalid token format | Ensure proper Bearer format |
AUTH_004 | API key not found | Check key hasn't been revoked |
AUTH_005 | IP not whitelisted | Add IP to allowed list |
AUTH_006 | MFA required | Provide MFA code |
AUTH_007 | Account locked | Contact support |
Debug Authentication Issues¶
Enable debug headers to troubleshoot:
Debug response headers:
X-Auth-Method: api_key
X-Auth-User-ID: 550e8400-e29b-41d4-a716-446655440000
X-Auth-Key-ID: 660e8400-e29b-41d4-a716-446655440001
X-Auth-IP: 203.0.113.42
X-Auth-Remaining-Quota: 9950
Security Checklist¶
- [ ] Store credentials securely (environment variables, key management service)
- [ ] Rotate API keys every 90 days
- [ ] Use HTTPS for all API calls
- [ ] Implement request signing for sensitive operations
- [ ] Enable MFA for user accounts
- [ ] Monitor API key usage for anomalies
- [ ] Use IP whitelisting for production keys
- [ ] Implement CSRF protection for web applications
- [ ] Verify webhook signatures
- [ ] Use service accounts for automated systems
- [ ] Implement proper error handling without exposing sensitive data
- [ ] Log authentication events for audit trails
Support¶
For authentication issues: - Check our Status Page for service availability - Review Common Issues - Contact support: support@kindly.com - Enterprise support: enterprise@kindly.com