Everyone's showing off their cool Notion+ElevenLabs automations. Nobody's talking about the IAM mess and data exposure they're creating.
Here's the secure way to do it. The core problem: your ElevenLabs API key in a plaintext environment variable in some random automation platform is a liability.
**Step 1: Isolate the API Call**
Don't call ElevenLabs directly from Notion/Make/Zapier. Use an AWS Lambda function as a proxy. This keeps your key off third-party servers.
**Step 2: Least Privilege IAM**
The execution role for the Lambda should have *zero* permissions beyond logging. It doesn't need S3, DynamoDB, or network access.
**Step 3: Secure Key Storage**
Store the ElevenLabs API key in AWS Secrets Manager. Lambda fetches it at runtime. Rotate it regularly.
Basic Lambda proxy structure (Python):
```python
import json
import requests
import os
import boto3
from botocore.exceptions import ClientError
def lambda_handler(event, context):
# Get secret
secret_name = "elevenlabs/api-key"
client = boto3.client('secretsmanager')
try:
secret_response = client.get_secret_value(SecretId=secret_name)
api_key = secret_response['SecretString']
except ClientError as e:
raise e
# Get text from event (parsed from Notion webhook)
text_to_speak = event.get('text')
# Call ElevenLabs
headers = {
"Accept": "audio/mpeg",
"Content-Type": "application/json",
"xi-api-key": api_key
}
response = requests.post(
f"https://api.elevenlabs.io/v1/text-to-speech/YOUR_VOICE_ID",
json={"text": text_to_speak, "voice_settings": {"stability": 0.5, "similarity_boost": 0.5}},
headers=headers
)
# Return audio stream or store in a *private* S3 bucket with a presigned URL
return {
'statusCode': 200,
'body': json.dumps({'audio_url': '...'})
}
```
**Step 4: Lock Down the Trigger**
If using API Gateway, use a strong API key and request validation. Monitor logs for unusual call volume.
This adds complexity, but it prevents a leaked key from being used to drain your ElevenLabs credits or exfiltrate sensitive text processed through the pipeline.
Least privilege is not a suggestion.
Finally, someone talking about security instead of just the shiny outcome.
Your AWS Lambda proxy is clever, but it's still a proxy. You're now on the hook for Lambda's VPC, subnet, and API Gateway configs, plus the Secrets Manager costs. It solves one problem by creating a new, simpler-but-still-present AWS admin problem.
Anyone following this now has to manage IAM policies for two services instead of just securing a single API key. It's trading a small, specific risk for a new category of cloud misconfig risk.
Feels like overkill for turning meeting notes into a voice memo.
Trust but verify.
Overengineering at its finest. That lambda is just another API endpoint to secure and monitor. Now you've got cold starts, timeout errors, and a new monthly bill for what? To hide a key you could have just kept in a dedicated automation platform's vault.
The real vendor lock-in isn't ElevenLabs, it's AWS. Try removing that lambda setup later.
Trust but verify.