Embed Private S3 Videos in Notion with Pre-Signed URLs
Learn how to embed private S3 videos in Notion using pre-signed URLs and AWS Lambda. Step-by-step setup, security best practices, and troubleshooting tips.
When you need to embed video recordings in Notion while keeping them private in AWS S3, pre-signed URLs offer a secure solution that generates temporary access links without exposing your entire S3 bucket publicly.
Private S3 video embed in Notion using pre-signed URLs
The Challenge: Private Videos in Notion
Many teams store meeting recordings, training videos, or confidential content in private AWS S3 buckets. When you try to embed these videos directly in Notion using standard S3 URLs, Notion cannot access them because the bucket is private.
The typical workflow looks like this:
Download video from source (Zoom, Teams, etc.)
Upload to private S3 bucket for secure storage
Attempt to embed in Notion page
Video fails to load due to permission errors
What Are S3 Pre-Signed URLs?
Pre-signed URLs are temporary access links that AWS S3 generates for private objects. They include authentication credentials in the URL itself, allowing anyone with the link to access the file for a limited time without needing AWS credentials.
Key benefits:
Maintain bucket privacy while sharing specific files
Set custom expiration windows (minutes to months)
No public bucket policies required
Audit trail through AWS CloudTrail
Implementation Architecture
The solution requires three components:
1. AWS S3 Bucket (Private)
Store your video files in a private S3 bucket with standard IAM permissions. Do not enable public access.
2. AWS Lambda Function
Create a Lambda function that generates pre-signed URLs on demand. This function should:
Accept a video file identifier
Validate the request
Generate a pre-signed URL with appropriate expiration
Return the temporary URL
3. Notion Integration
Embed the pre-signed URL in your Notion page as a video block. When the URL expires, trigger the Lambda function to generate a fresh one.
Step-by-Step Implementation
Configure Your S3 Bucket
Ensure your S3 bucket is private with these settings:
Block all public access: Enabled
Bucket policy: Restricted to authorized IAM roles only
CORS configuration: Add Notion domains if needed
Create the Lambda Function
Your Lambda function endpoint should generate pre-signed URLs with configurable expiration:
Recommended expiration windows:
Short-term access (1-7 days): For time-sensitive content
Medium-term access (1-3 months): For recurring reference material
Long-term access (6-12 months): For evergreen training content
Important considerations:
Longer expirations reduce maintenance overhead
Shorter expirations improve security
Balance based on your content sensitivity
Integration with Notion
Once you have the Lambda endpoint:
Generate the pre-signed URL by calling your Lambda function with the video file path
Embed in Notion by pasting the pre-signed URL and selecting "Create embed"
Set up refresh automation (optional) to regenerate URLs before expiration
Handling URL Expiration
Pre-signed URLs eventually expire. You have two options:
Manual refresh:
When a video stops working, regenerate the pre-signed URL and update the Notion embed.
Automated refresh:
Build a refresh mechanism that:
Tracks pre-signed URL expiration dates
Automatically generates new URLs before expiration
Updates Notion pages via the Notion API
Can be triggered by a button or schedule
Security Best Practices
Never commit AWS credentials to version control
Use IAM roles with minimum required permissions
Enable CloudTrail logging to track pre-signed URL generation
Set appropriate expiration windows based on content sensitivity
Validate requests in your Lambda function to prevent abuse
Consider IP restrictions for highly sensitive content
Cost Considerations
This solution incurs minimal AWS costs:
S3 storage: Standard storage rates for your videos
Lambda invocations: Charged per URL generation (typically fractions of a cent)
S3 data transfer: Charged when videos are viewed in Notion
CloudTrail (optional): Additional logging costs if enabled
For most teams, the total additional cost is negligible compared to the security and workflow benefits.
Alternative Approaches
Public S3 bucket with obfuscated URLs:
Less secure, but simpler if content isn't highly sensitive.
Notion-native video upload:
Limited by file size restrictions and less control over hosting.
Third-party video hosting:
Services like Vimeo or Wistia offer privacy controls but add subscription costs.
Common Troubleshooting
Video won't play in Notion:
Verify the pre-signed URL hasn't expired
Check S3 bucket CORS configuration
Ensure video format is supported (MP4 recommended)
Lambda function errors:
Confirm IAM role has S3 GetObject permissions
Verify bucket name and file path are correct
Check Lambda timeout settings for large files
Slow video loading:
Consider CloudFront CDN for better global performance
Optimize video compression and resolution
Use adaptive bitrate streaming for longer videos
Ready to Implement?
Secure video embedding in Notion doesn't require public S3 buckets or complex infrastructure. With AWS Lambda and pre-signed URLs, you can maintain privacy while sharing video content with your team.
Setting up S3 pre-signed URL workflows usually breaks at the IAM permissions or the Lambda endpoint configuration. If you'd rather skip the trial-and-error, book a ZoomFlow session — one of our consultants will build it with you in real time and you'll own the working setup when the call ends.
Should you lock your Notion database? Learn how database permissions and locking affect recurring task templates—and the best safe workflow for your team.
Notion AI meeting notes for consulting teams provides live transcription, instant summaries, and clear action items—so you can send accurate client recaps in minutes.