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.

May 28, 2026
Embed Private S3 Videos in Notion with Pre-Signed URLs
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
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:
  1. Generate the pre-signed URL by calling your Lambda function with the video file path
  1. Embed in Notion by pasting the pre-signed URL and selecting "Create embed"
  1. 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.