The key server bundles a presign endpoint that generates presigned S3 PUT URLs. The Uploader uses this to upload encrypted segments directly from the browser to S3 — without routing bytes through your server.
Enable presign
docker run -d \
-e MASTER_KEY_HEX=... \
-e SALT_HEX=... \
-e CORS_ORIGINS=https://app.example.com \
-e ENABLE_PRESIGN=true \
-e S3_BUCKET=my-video-bucket \
-e S3_REGION=us-east-1 \
-e AWS_ACCESS_KEY_ID=... \
-e AWS_SECRET_ACCESS_KEY=... \
-p 4100:4100 \
blindcast/keyserver
How it works
- The uploader sends
POST /presign with the S3 key and content type
- The key server validates the JWT (if auth is enabled), then generates a presigned PUT URL
- The uploader uploads encrypted bytes directly to S3 using the presigned URL
POST /presign
Authorization: Bearer <token>
Content-Type: application/json
{
"key": "content/my-video-001/seg-0.ts",
"contentType": "video/mp2t"
}
Presign response
{
"url": "https://my-video-bucket.s3.us-east-1.amazonaws.com/content/my-video-001/seg-0.ts?X-Amz-Algorithm=..."
}
The presigned URL expires after 300 seconds (5 minutes) by default.
Configuration
| Variable | Default | Description |
|---|
ENABLE_PRESIGN | false | Set to true to enable |
S3_BUCKET | — | S3 bucket name (required) |
S3_REGION | us-east-1 | AWS region |
AWS_ACCESS_KEY_ID | — | AWS credentials |
AWS_SECRET_ACCESS_KEY | — | AWS credentials |
S3_ENDPOINT | — | Custom S3 endpoint (for MinIO, R2, etc.) |
S3-compatible storage
For MinIO, Cloudflare R2, or Backblaze B2, set S3_ENDPOINT:
-e S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
Security
If authentication is not configured (AUTH_JWT_SECRET or AUTH_JWKS_URL), the presign endpoint is open to anyone who can reach the key server. Always enable authentication when ENABLE_PRESIGN=true in production.
- Presign requests require the same JWT authentication as key requests (if auth is enabled)
- The key server validates that the S3 key starts with an allowed prefix (default:
content/)
- Presigned URLs are short-lived (5 minutes) and single-use