Call Recording Encryption Configuration Guide¶
Overview¶
This guide explains how to configure HIPAA-compliant encryption for call recordings in your account using our API. Encrypting recordings ensures that sensitive call data is protected both in transit and at rest, meeting security and compliance requirements.
What is Recording Encryption?¶
Recording encryption protects your call recordings by converting the audio data into an encrypted format that can only be accessed with the proper encryption keys. This ensures that even if recordings are accessed by unauthorized parties, the data remains protected.
Key Benefits: - HIPAA Compliance: Meets healthcare data protection requirements - Data Security: Protects sensitive customer information - Access Control: Only authorized parties can decrypt and access recordings - Regulatory Compliance: Helps meet various industry regulations
API Endpoints¶
Get Current Encryption Configuration¶
Retrieve the current encryption settings for your account.
Endpoint:
GET /api/v2/config/call_recording_encryption
Headers:
- X-Account-ID: Your account identifier
- Authorization: Bearer JWT token
Example Request:
curl -X GET "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token"
Example Response:
{
"success": true,
"config": {}
}
Configure Encryption Settings¶
Enable or update encryption settings for your account.
Endpoint:
PUT /api/v2/config/call_recording_encryption
Headers:
- X-Account-ID: Your account identifier
- Authorization: Bearer JWT token
- Content-Type: application/json
Example Request:
curl -X PUT "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"algorithm": "AES-256-GCM",
"salt": "unique_salt_value",
"key": "your_encryption_key_here_at_least_32_characters"
}'
Note: key_version and key_id are automatically managed by the backend and should not be provided in the request. They will be returned in the response for reference only.
Example Response:
{
"success": true,
"message": "Encryption configuration updated successfully",
"config": {
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_auto_your_acc",
"salt": "unique_salt_value",
"key": "your_encryption_key_here_at_least_32_characters",
"historical_keys": {},
"historical_salts": {}
}
}
Configuration Parameters¶
enabled (Required)¶
What it does: Activates or deactivates encryption for your account.
Type: Boolean (true or false)
Values:
- true: Enables encryption. All new recordings will be encrypted before storage.
- false: Disables encryption. New recordings will be stored unencrypted.
Important Notes:
- This is the only required field to enable basic encryption
- When set to true, default values will be applied for other parameters if not specified
- Changing this setting only affects new recordings; existing recordings retain their current encryption status
Example:
{
"enabled": true
}
algorithm (Optional)¶
What it does: Specifies which encryption method to use for protecting your recordings.
Type: String
Supported Values:
- "AES-256-GCM" (Recommended): Modern, secure encryption with built-in authentication
- "AES-256-CBC": Standard encryption method, widely supported
Default: "AES-256-GCM" (when enabled is true)
What this means for you: - AES-256-GCM: More secure, includes authentication to prevent tampering. Recommended for new implementations. - AES-256-CBC: Traditional encryption method, compatible with older systems.
Best Practice: Use AES-256-GCM unless you have specific compatibility requirements.
Example:
{
"enabled": true,
"algorithm": "AES-256-GCM"
}
key_version (Read-only in Response)¶
What it does: Identifies which version of your encryption key is currently being used. This is automatically managed by the backend and cannot be set in requests.
Type: Integer (positive number, read-only)
How it works:
- Automatically starts at 1 when encryption is first enabled
- Automatically increments when you change key or salt values
- Each version corresponds to a specific encryption key/salt pair
- Older recordings encrypted with version 1 can still be accessed with version 1 keys
- New recordings will use the current version number
- This allows automatic key rotation without losing access to historical recordings
Important: You cannot set key_version in requests. It is managed internally and shown in responses for reference only.
Example Response (showing key_version):
{
"config": {
"enabled": true,
"key_version": 1,
"key": "...",
"salt": "..."
}
}
key_id (Read-only in Response)¶
What it does: Provides a unique identifier for your encryption key. This is automatically generated by the backend and cannot be set in requests.
Type: String (read-only)
Auto-Generation: The system automatically generates a unique key ID based on your account identifier (format: key_auto_<account_prefix>).
Important: You cannot set key_id in requests. It is managed internally and shown in responses for reference only.
Example Response (showing key_id):
{
"config": {
"enabled": true,
"key_id": "key_auto_b02d27af63",
"key": "..."
}
}
salt (Optional)¶
What it does: Adds an extra layer of security by mixing a random value with your encryption process. This prevents attackers from using pre-computed tables to crack your encryption.
Type: String (base64-encoded or plain text)
Required: No
Auto-Generation: If not provided, the system will automatically generate a cryptographically secure 128-bit salt (16 bytes, base64-encoded to 24 characters). This generated salt will be returned in the API response.
Restrictions:
- Cannot be "default_salt" (this value is rejected for security reasons)
What this means:
- Salt is like adding a unique "spice" to each account's encryption
- Makes encryption stronger by preventing pattern-based attacks
- Should be unique per account for maximum security
- The salt is stored in each recording's metadata - this allows decryption even if the salt configuration changes
- Historical salts are preserved - when you rotate salts, old salts are stored in historical_salts map
- If you don't provide one, a secure salt will be auto-generated and returned in the response
Salt Storage and Rotation:
- Each recording stores its salt in metadata (allows backward compatibility)
- When you provide a new salt (different from current), the system automatically:
- Increments key_version
- Moves the current salt to historical_salts[old_version]
- Moves the current key to historical_keys[old_version] (for backward compatibility)
- Stores the new salt for the new version
- Gorec can decrypt old recordings using the salt stored in their metadata or from historical_salts
- System automatically manages historical_salts map - no manual intervention needed
Security Recommendation: - Save the generated salt: If the system generates a salt for you, save it securely from the API response - Use a unique, random value for each account if providing manually - Generate using cryptographically secure random number generators - Historical salts are preserved automatically during rotation - Never reuse salt values across accounts
Validation: The API will reject encryption configuration if: - The salt matches the insecure default value "default_salt"
Example - With your own salt:
{
"enabled": true,
"salt": "unique_random_value_for_account_001"
}
Example - Auto-generated:
{
"enabled": true
}
key (Optional, but recommended)¶
What it does: The actual encryption key used to encrypt and decrypt recordings. This is a plain text key that will be automatically converted to base64 for secure storage in the database.
Type: String (plain text key)
Required: No, but strongly recommended
Format: Plain text string, minimum 32 characters long
Auto-Generation: If not provided, the system will automatically generate a cryptographically secure 256-bit key as a readable hexadecimal string (64 hex characters). This generated key will be returned in the API response for you to save securely.
Security Requirements (if provided): - Minimum Length: Must be at least 32 characters long (plain text) - Cannot be default values: Values like "default_encrypted_key", "default", "test", or other insecure defaults are rejected - Should be unique: Each account should have a unique key
What this means: - You provide the key in plain text (no need to encode in base64 manually) - The system automatically converts your plain text key to base64 before storing it in the database - Used directly by the encryption service (Gorec) to encrypt/decrypt recordings - Required to decrypt recordings later - The key is stored as base64 in the database for compatibility, but you work with it in plain text - If you don't provide one, a secure readable key (hexadecimal) will be auto-generated and returned in the response
Important Security Notes:
- Save the generated key: If the system generates a key for you, save it securely from the API response
- The key you provide should be in plain text - the system handles base64 conversion automatically
- Transmit keys securely over HTTPS only
- Store keys in secure key management systems on your side
- Keys must meet minimum security requirements (minimum 32 characters) if provided manually
- Auto-generated keys are hexadecimal strings (readable, like: 1a2b3c4d5e6f...)
Validation: The API will reject encryption configuration if: - The key is provided but shorter than 32 characters - The key matches insecure default values
Example - With your own key (plain text):
{
"enabled": true,
"key": "my_secure_encryption_key_at_least_32_characters_long"
}
Example - Letting system generate (recommended for simplicity):
{
"enabled": true
}
key that you should save securely.
How Encryption Works¶
Basic Flow¶
- Configuration: You configure encryption settings via the API
- Key Management: Your encryption keys are securely stored and managed
- Recording Creation: When a call is recorded, the system:
- Generates a unique identifier for the recording
- Uses your encryption key to encrypt the audio data
- Stores metadata (key ID, version, algorithm) with the recording
- Saves the encrypted recording to storage
- Recording Access: When you access a recording:
- The system retrieves your encryption configuration
- Uses the stored metadata to identify the correct key and version
- Decrypts the recording for authorized access
Automatic Key Version Management¶
The key_version is automatically managed by the backend. You don't need to (and cannot) set it manually. The system automatically handles key rotation when you change key or salt values.
Scenario 1: Initial Setup
- Enable encryption with your first encryption key (plain text)
- System automatically sets key_version: 1
- All recordings are encrypted with version 1
- historical_keys and historical_salts maps are empty
Scenario 2: Automatic Key Rotation
- Provide a new encryption key (different from current) OR a new salt (different from current)
- The system automatically:
- Detects the change
- Increments key_version (e.g., 1 → 2)
- Moves the current key to historical_keys[old_version]
- Moves the current salt to historical_salts[old_version]
- Stores the new key as key for the new version
- Stores the new salt as salt for the new version
- Preserves all historical keys and salts in their respective maps
- New recordings use the new version's key and salt (stored in recording metadata)
- Old recordings remain accessible using old version's key and salt from historical_keys and historical_salts, or from their stored metadata
- Both versions remain active for decryption
- Each recording stores its salt in metadata - allowing decryption even if configuration changes
Important: Even if you only change key or only change salt, the system will preserve BOTH the old key and old salt in historical maps. This ensures you can decrypt recordings encrypted with any previous version.
Benefits of Automatic Key Versioning:
- ✅ Automatic version management - no manual version tracking needed
- ✅ Automatic historical key preservation - no manual management needed
- ✅ Maintain access to historical recordings across all key versions
- ✅ Security through regular key rotation
- ✅ Compliance with key rotation policies
- ✅ Smooth transitions between key generations
- ✅ The historical_keys and historical_salts maps store all previous versions automatically
Getting Started¶
Step 1: Check Current Configuration¶
First, check if encryption is already enabled:
curl -X GET "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token"
Step 2: Enable Encryption (Simple Method)¶
Enable encryption with auto-generated secure values:
curl -X PUT "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'
⚠️ IMPORTANT: The response will include auto-generated key, salt, key_version, and key_id values. Save the key and salt securely - you'll need them to decrypt your recordings! The key_version and key_id are shown for reference only.
Response Example:
{
"success": true,
"message": "Encryption configuration updated successfully",
"config": {
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_auto_b02d27af63",
"salt": "KxY9mP2qR8vN3wT6...", // ⚠️ SAVE THIS
"key": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890" // ⚠️ SAVE THIS (readable hex format)
}
}
Step 2 (Alternative): Enable Encryption with Your Own Keys¶
If you prefer to provide your own keys for advanced key management:
curl -X PUT "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"algorithm": "AES-256-GCM",
"salt": "your_unique_salt_value",
"key": "your_encryption_key_must_be_at_least_32_characters_long"
}'
Note:
- key_version and key_id are automatically managed - do not include them in requests
- key must be at least 32 characters (plain text, no base64 needed)
- salt cannot be "default_salt"
- The system will auto-generate key_id and start key_version at 1
Step 3: Configure Advanced Settings (Optional)¶
For production use, configure with specific values:
curl -X PUT "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_production_001",
"salt": "your_unique_salt_value",
"key": "your_encryption_key_value_at_least_32_characters"
}'
Step 4: Verify Configuration¶
Confirm your settings were applied:
curl -X GET "https://api.example.com/api/v2/config/call_recording_encryption" \
-H "X-Account-ID: your_account_id" \
-H "Authorization: Bearer your_jwt_token"
Common Use Cases¶
⚠️ Important: Saving Auto-Generated Values¶
When enabled: true without providing all fields:
First-time enabling (encryption was disabled):
- key: Auto-generated 256-bit secure key (readable hexadecimal format)
- key_id: Auto-generated unique identifier based on your account
- salt: Auto-generated 128-bit secure salt (base64-encoded)
Re-enabling (encryption was previously disabled):
- Existing values are preserved - the system will keep your current key, salt, and key_id if:
- There are valid values stored in the database (even if encryption was disabled)
- You don't provide new key or salt values in the request
- The system maintains the same key_version unless you change key or salt
Note: This works even if encryption was previously disabled (enabled: false) but had valid encryption configuration stored. When you re-enable without providing new key or salt, the system will preserve your stored keys and maintain the same version.
⚠️ CRITICAL: When new values are auto-generated (first time or key rotation), they are returned in the API response. You must save them securely as you'll need them to access your encrypted recordings in the future.
Simple Encryption Configuration¶
The easiest way to enable encryption is to just set enabled: true and let the system generate secure values:
{
"enabled": true
}
Response (first time enabling):
{
"success": true,
"message": "Encryption configuration updated successfully",
"config": {
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_auto_b02d27af63",
"salt": "aBc123XyZ456...", // Save this!
"key": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890", // Save this!
}
}
Response (re-enabling with same key_version): If encryption was previously configured (even if disabled) and you send the same request, the system will preserve your existing values:
{
"success": true,
"message": "Encryption configuration updated successfully",
"config": {
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_auto_b02d27af63", // Preserved
"salt": "aBc123XyZ456...", // Preserved - same as before
"key": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890", // Preserved - same as before
}
}
⚠️ IMPORTANT:
- When new values are generated (first time or key rotation), save the key and salt values from the response in a secure location
- When existing values are preserved, you can verify they match your stored values
Example - Re-enabling after disabling:
If you previously disabled encryption (enabled: false) but had valid encryption keys stored:
// Database state before request:
{
"enabled": false,
"key_version": 1,
"key": "stored_key_from_before...",
"salt": "stored_salt_from_before...",
"key_id": "key_production_001"
}
// Request:
{
"enabled": true
}
// Result: System preserves stored values and re-enables encryption
{
"enabled": true,
"key_version": 1,
"key": "stored_key_from_before...", // Preserved!
"salt": "stored_salt_from_before...", // Preserved!
"key_id": "key_production_001" // Preserved!
}
This ensures you can re-enable encryption without losing access to previously encrypted recordings.
Production Configuration¶
For production environments, configure all parameters:
{
"enabled": true,
"algorithm": "AES-256-GCM",
"key_version": 1,
"key_id": "key_production_account_001",
"salt": "unique_production_salt_2024",
"key": "production_encryption_key_value_at_least_32_characters"
}
Best Practices: - Use descriptive key IDs that identify the environment - Use unique salt values per account - Store encrypted keys securely - Document your key rotation schedule
Disabling Encryption¶
To disable encryption (recordings will be stored unencrypted):
{
"enabled": false
}
Important Behavior:
- Existing encryption values are preserved - The system keeps your key, salt, key_id, and key_version even when encryption is disabled
- This ensures you can re-enable encryption with the same keys later
- Existing encrypted recordings remain encrypted and accessible when you re-enable
- New recordings will be stored without encryption while disabled
- Consider data retention and compliance requirements before disabling
Example - Disabling preserves values:
// Request to disable
{
"enabled": false
}
// Response - values are preserved
{
"enabled": false,
"algorithm": "AES-256-GCM",
"key_version": 2,
"key_id": "key_production_001", // Preserved
"salt": "stored_salt_value...", // Preserved
"key": "stored_key_value..." // Preserved
}
When you re-enable with {"enabled": true}, these preserved values will be used automatically.
Key Rotation¶
To rotate encryption keys and maintain access to historical recordings:
How Key Rotation Works:
- Current Key Management: The system automatically manages historical keys for you
- Automatic Preservation: When you rotate to a new
key_version, the currentkeyis automatically moved tohistorical_keys - Historical Access: All previous key versions are stored in
historical_keysmap, allowing access to old recordings
Example - Rotating from version 1 to version 2:
Before rotation:
{
"enabled": true,
"key_version": 1,
"salt": "KxY9mP2qR8vN3wT6sA7bC4dF1gH8j=",
"key": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890",
"historical_keys": {},
"historical_salts": {}
}
Request to rotate (simply provide new key or salt):
{
"enabled": true,
"algorithm": "AES-256-GCM",
"salt": "bmV3X3NhbHRfZm9yX3ZlcnNpb25fMg==",
"key": "new_encryption_key_plain_text_at_least_32_characters_long"
}
key_version or key_id. The system automatically increments key_version when it detects changes to key or salt.
After rotation (automatic):
{
"enabled": true,
"key_version": 2,
"salt": "bmV3X3NhbHRfZm9yX3ZlcnNpb25fMg==",
"key": "new_encryption_key_plain_text_at_least_32_characters_long",
"historical_keys": {
"1": "1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef1234567890"
},
"historical_salts": {
"1": "KxY9mP2qR8vN3wT6sA7bC4dF1gH8j="
}
}
What happens automatically:
- System detects changes to key and/or salt
- System automatically increments key_version from 1 to 2
- Old key (version 1) is automatically moved to historical_keys[1]
- Old salt (version 1) is automatically moved to historical_salts[1]
- New key and salt are stored for version 2
- Both keys and salts remain accessible for decrypting recordings
- New recordings use version 2 key and salt
- Old recordings remain accessible with version 1 key and salt (from historical_keys and historical_salts)
Important: The system preserves BOTH the old key and old salt, even if you only changed one of them. This ensures backward compatibility.
Key Points:
- ✅ Automatic version increment when key or salt changes
- ✅ Historical keys and salts are automatically preserved
- ✅ No manual intervention needed for version management or key/salt storage
- ✅ All key and salt versions remain accessible
- ✅ System manages both historical_keys and historical_salts maps automatically
- ✅ Both old key AND old salt are always preserved together, ensuring complete backward compatibility
- ✅ Each recording stores its salt in metadata for backward compatibility
- ✅ Gorec can decrypt recordings using stored metadata or historical values
Security Best Practices¶
1. Use Strong Configuration¶
Always configure all parameters in production:
- Use
AES-256-GCMalgorithm - Set unique key IDs for easy identification
- Use unique salt values per account
- Never reuse keys across accounts
2. Regular Key Rotation¶
Implement a key rotation schedule:
- Rotate keys at least annually (more frequently for high-security environments)
- Increment
key_versionwith each rotation - Maintain access to previous key versions
- Document key rotation dates
3. Secure Key Management¶
- Never transmit unencrypted keys
- Store keys in secure key management systems
- Limit access to encryption keys
- Monitor key usage and access
4. Monitor Configuration¶
- Regularly verify encryption is enabled
- Check that configurations haven't been unexpectedly changed
- Review access logs to encryption endpoints
Troubleshooting¶
Issue: "Could not get account ID from context"¶
Solution: Ensure you're including the X-Account-ID header in your request.
Issue: "Failed to update encryption configuration"¶
Solution: - Verify your account ID is correct - Ensure you have admin permissions - Check that all required fields are included
Issue: Cannot decrypt old recordings¶
Solution:
- Verify the key_version matches the version used for old recordings
- Ensure old encryption keys are still available
- Check that the key ID and encrypted key are correct
Issue: Configuration not applied¶
Solution: - Verify the request was successful (check response status) - Retrieve configuration to confirm changes were saved - Wait a few moments for changes to propagate
API Response Codes¶
| Code | Meaning | Action |
|---|---|---|
| 200 | Success | Configuration retrieved/updated successfully |
| 400 | Bad Request | Invalid request body or missing required fields |
| 401 | Unauthorized | Invalid or missing JWT token |
| 403 | Forbidden | User lacks required permissions |
| 404 | Not Found | Account or endpoint not found |
| 500 | Internal Server Error | Server-side error occurred |
Compliance Considerations¶
HIPAA Requirements¶
Encryption helps meet HIPAA requirements for protecting Protected Health Information (PHI) in call recordings:
- Encryption at Rest: Ensures recordings are encrypted when stored
- Access Controls: Only authorized parties can decrypt recordings
- Audit Trails: Key versioning provides audit capability
Other Regulations¶
Recording encryption also helps meet: - GDPR data protection requirements - PCI-DSS for payment card information - SOC 2 security controls - Industry-specific compliance needs
Support and Resources¶
Getting Help¶
If you need assistance with encryption configuration:
- Check this documentation for common issues
- Review API responses for specific error messages
- Contact support with your account ID and error details
Additional Resources¶
- API Authentication Guide
- Account Management Documentation
- Security Best Practices Guide
Summary¶
Recording encryption provides essential security for your call recordings:
- Enable encryption by setting
enabled: true - Configure parameters for production use
- Use key versioning for secure key rotation
- Follow best practices for maximum security
Start with basic encryption using defaults, then configure advanced settings as needed. Remember to verify your configuration and maintain proper key management practices.
Last Updated: 2025-10-29