Skip to main content

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:

  1. Immediately delete the key from dashboard
  2. Check activity log for unauthorized access
  3. Create new key with different name
  4. Update applications to use new key
  5. Monitor account for suspicious activity
  6. 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:

  1. Contact Audian security: security@audian.com
  2. Preserve evidence: Don't modify logs or data
  3. Notify affected users: If user data was accessed
  4. 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​

External Resources​