File download (S3 signed URL)
Sells a one-time download. After payment, the buyer is shown a time-limited signed URL to the file in your S3-compatible bucket.
What it does
When an order is paid, the glue uses @aws-sdk/s3-request-presigner to generate a
pre-signed GET URL with the configured expiry (default 24h) and surfaces it on the
buyer's confirmation page + customer portal. The same URL is sent via the
entitlement.applied webhook payload.
Prerequisites
- An S3-compatible bucket. The default install ships MinIO at
:9000with bucketopenbitum-files(auto-created on first boot). - For production with public AWS S3, swap the env vars to your AWS creds and CDN URL.
Step-by-step (MinIO, default)
- After install, open
https://<your-domain>:9001(MinIO console). - Sign in with
MINIO_ROOT_USER/MINIO_ROOT_PASSWORDfrom.env. - Bucket
openbitum-filesalready exists. Upload your file (drag and drop) — saypdfs/my-book.pdf. - In the dashboard, add an entitlement of type File download to your product:
- S3 key:
pdfs/my-book.pdf - Expiry seconds:
86400(24 h)
- S3 key:
Step-by-step (AWS S3)
-
Create a bucket with public access blocked and CORS allowing your domain.
-
Create an IAM user with
s3:GetObjectands3:PutObjecton the bucket. -
Override env vars (post-MVP we'll surface these in the dashboard; for now edit
.envdirectly):S3_ENDPOINT=https://s3.eu-west-1.amazonaws.com S3_REGION=eu-west-1 S3_BUCKET=openbitum-files S3_ACCESS_KEY_ID=AKIA... S3_SECRET_ACCESS_KEY=... -
Restart the glue:
docker compose up -d glue.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| 403 SignatureDoesNotMatch | clock skew on host (run timedatectl) or wrong secret |
| 403 AccessDenied | IAM policy missing s3:GetObject on the key |
| 404 NoSuchKey | wrong S3 key spelling on the entitlement |
| Link works for buyer but caches in browser | the signed URL is one-time-visible by design; ask the buyer to keep the tab open until download completes |
Coming after MVP launch
Single-use download tokens (download counter), client-side encrypted files with keys held in glue, R2/Backblaze docs.