Security Best Practices
Secure implementation of the Audian API is critical. Follow these guidelines to protect your data and API credentials.
Authentication Security​
API Keys​
Storage​
Do:
# Use environment variables
export AUDIAN_API_KEY="sk_live_abc123xyz..."
# Use secure configuration management
# .env file (never commit to git)
AUDIAN_API_KEY=sk_live_abc123xyz...
# Use OS keychain/credential manager
# Or cloud secret management (AWS Secrets Manager, Azure Key Vault)
Don't:
# Don't hardcode
API_KEY = "sk_live_abc123xyz..." # Bad!
# Don't log or print
logger.info(f"Using API key: {api_key}") # Bad!
# Don't put in URLs
url = f"https://api.audian.com:8443/v2/audio?key={api_key}" # Bad!
# Don't commit to git
git add api_keys.txt # Bad!
Rotation​
Rotate API keys regularly:
Development: Every 180 days
Staging: Every 90 days
Production: Every 30-90 days
Create a new key before retiring the old one:
# 1. Generate new key
curl -X POST https://api.audian.com:8443/v2/api-keys \
-H "X-Auth-Token: OLD_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Production (New)"}'
# 2. Update your application to use new key
# 3. Test thoroughly
# 4. Delete old key or set retirement date
curl -X DELETE https://api.audian.com:8443/v2/api-keys/old_key_id \
-H "X-Auth-Token: NEW_KEY"
Permissions​
Use least privilege principle - grant only necessary permissions:
# Bad: Full permissions
curl -X POST https://api.audian.com:8443/v2/api-keys \
-d '{"permissions": ["*"]}' # Dangerous!
# Good: Specific permissions
curl -X POST https://api.audian.com:8443/v2/api-keys \
-d '{
"permissions": [
"audio:read",
"job:read"
]
}'
OAuth Tokens​
Client Secrets​
Protect your OAuth client secret:
# Environment variable
export AUDIAN_CLIENT_SECRET="secret_abc123..."
# Never in frontend code
const CLIENT_SECRET = "secret_abc123..." // DON'T DO THIS!
Token Storage​
For web applications:
# Backend: Secure session storage
session['access_token'] = token
session['token_expiry'] = expiry_time
# Always use HTTPS
secure=True,
httponly=True,
samesite='Lax'
For mobile applications:
// iOS: Use Keychain
KeychainItem.save(token, account: "audian_token")
// Android: Use EncryptedSharedPreferences
val encryptedPrefs = EncryptedSharedPreferences.create(...)
encryptedPrefs.edit().putString("token", token).apply()
Refresh Tokens​
Implement automatic refresh before expiration:
import time
import requests
def get_valid_token():
# Check if token expired
if time.time() > token_expiry - 300: # Refresh 5 min before
refresh_token_impl()
return current_token
def refresh_token_impl():
global current_token, token_expiry
response = requests.post('https://api.audian.com:8443/v2/oauth/token', {
'grant_type': 'refresh_token',
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'refresh_token': refresh_token
})
data = response.json()
current_token = data['access_token']
token_expiry = time.time() + data['expires_in']
Network Security​
HTTPS Only​
Always use HTTPS for API calls:
# Good
curl https://api.audian.com:8443/v2/audio
# Bad
curl http://api.audian.com:8443/v2/audio # Insecure!
Certificate Pinning​
For mobile apps, implement certificate pinning:
iOS:
let session = URLSession(
configuration: URLSessionConfiguration.default,
delegate: CertificatePinningDelegate(),
delegateQueue: nil
)
Android:
val certificatePinner = CertificatePinner.Builder()
.add("api.audian.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
Request/Response Validation​
Verify API responses:
import json
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
# Validate response signature
response = requests.get('https://api.audian.com:8443/v2/audio')
# Check content type
assert response.headers['content-type'] == 'application/json'
# Validate JSON
try:
data = response.json()
except json.JSONDecodeError:
raise ValueError("Invalid JSON response")
# Check response signature if provided
if 'x-signature' in response.headers:
validate_signature(response.content, response.headers['x-signature'])
Data Protection​
Sensitive Data Handling​
Never send sensitive data to Audian:
# Bad: Sensitive data in audio metadata
curl -X POST https://api.audian.com:8443/v2/audio/upload \
-H "X-Auth-Token: $KEY" \
-F "file=@audio.mp3" \
-F "metadata={\"user_ssn\": \"123-45-6789\"}"
# Good: Only necessary metadata
curl -X POST https://api.audian.com:8443/v2/audio/upload \
-H "X-Auth-Token: $KEY" \
-F "file=@audio.mp3" \
-F "metadata={\"language\": \"en-US\"}"
Encryption at Rest​
Store sensitive API responses securely:
from cryptography.fernet import Fernet
# Encrypt sensitive results
cipher_suite = Fernet(encryption_key)
encrypted_results = cipher_suite.encrypt(results.encode())
# Decrypt when needed
decrypted_results = cipher_suite.decrypt(encrypted_results)
Encryption in Transit​
All API communication is TLS 1.2+:
# Verify TLS version
curl -I https://api.audian.com:8443/v2/audio --tlsv1.2
# Minimum supported version
TLS 1.2 (recommended: TLS 1.3)
Rate Limiting & DDoS Protection​
Implement Backoff​
import time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session():
session = requests.Session()
retry = Retry(
total=5,
backoff_factor=0.5,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
# Use the session
session = create_session()
response = session.get('https://api.audian.com:8443/v2/audio')
Monitor Rate Limits​
response = requests.get('https://api.audian.com:8443/v2/audio')
# Check rate limit headers
remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
limit = int(response.headers.get('X-RateLimit-Limit', 0))
reset = int(response.headers.get('X-RateLimit-Reset', 0))
print(f"Remaining: {remaining}/{limit}")
print(f"Resets at: {reset}")
if remaining < limit * 0.1: # Less than 10%
logger.warning("Approaching rate limit")
Error Handling​
Don't Expose Sensitive Details​
# Bad: Exposing internal errors
except requests.RequestException as e:
return {"error": str(e)} # May contain sensitive info
# Good: Generic error to user
except requests.RequestException as e:
logger.error(f"API error: {str(e)}")
return {"error": "Request failed"}
Log Securely​
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Good: Redact sensitive data
def log_request(url, headers):
safe_headers = headers.copy()
if 'Authorization' in safe_headers:
safe_headers['Authorization'] = '***REDACTED***'
logger.info(f"Request to {url}: {safe_headers}")
Webhook Security​
Verify Signatures​
Audian signs all webhook requests. Verify the signature:
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# In your webhook handler
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Audian-Signature')
if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
return {"error": "Invalid signature"}, 401
# Process webhook
data = request.json
return {"status": "ok"}
Use HTTPS for Webhooks​
Always configure webhook endpoints with HTTPS:
# Good
https://your-domain.com/webhook
# Bad
http://your-domain.com/webhook # Insecure!
Idempotency​
Handle webhook retries:
from uuid import uuid4
@app.route('/webhook', methods=['POST'])
def webhook():
event_id = request.json.get('id')
# Check if already processed
if is_processed(event_id):
return {"status": "ok"} # Already processed
# Process event
process_event(request.json)
# Mark as processed
mark_processed(event_id)
return {"status": "ok"}
Infrastructure Security​
Network Isolation​
For backend services, use VPC/subnet isolation:
# AWS example: Security group with limited access
AllowedInbound:
- Protocol: HTTPS
FromPort: 443
ToPort: 443
SourceSecurityGroup: app-servers
API Gateway​
Use API gateway for additional security:
// API Gateway request validation
{
"type": "REQUEST",
"identitySource": "method.request.header.Authorization",
"validationExpression": "Bearer .*"
}
IP Allowlisting​
Restrict API access to known IPs if possible:
# In API key permissions (dashboard)
Allowed IPs:
- 192.0.2.1/32 # Office
- 198.51.100.0/24 # AWS VPC
Incident Response​
Compromised API Key​
If you suspect a key is compromised:
- Immediately delete the key from dashboard
- Check activity log for unauthorized access
- Create new key with different name
- Update applications to use new key
- Monitor account for suspicious activity
- Contact support if unauthorized access detected
# Delete compromised key immediately
curl -X DELETE https://api.audian.com:8443/v2/api-keys/KEY_ID \
-H "X-Auth-Token: NEW_KEY"
# Check activity
curl -X GET https://api.audian.com:8443/v2/account/activity \
-H "X-Auth-Token: NEW_KEY"
Data Breach Notification​
If you discover unauthorized data access:
- Contact Audian security: security@audian.com
- Preserve evidence: Don't modify logs or data
- Notify affected users: If user data was accessed
- Implement fixes: Address the vulnerability
Compliance​
GDPR Compliance​
If processing EU resident data:
- Use Data Processing Agreement (DPA)
- Ensure GDPR-compliant data handling
- Enable data deletion requests
- Document legal basis for processing
SOC 2 Compliance​
Audian is SOC 2 Type II certified. Review compliance docs at my.audian.com.
Security Checklist​
- API keys stored in environment variables
- Never commit credentials to version control
- Using HTTPS for all API calls
- Rotate API keys every 30-90 days
- Implement request signing for webhooks
- Use least privilege for permissions
- Log API activity securely
- Monitor for unauthorized access
- Have incident response plan
- Regular security audits
Getting Help​
- Security Issues: security@audian.com
- Incident Support: support@audian.com
- Documentation: Security Overview