Enforce private-file authorization for Next.js | Ample

INFRASTRUCTURE

What it needs

Before you start

Exactly what was tested

How to do it

  1. 1

Authorize before touching storage

Return 401 for unauthenticated requests; never expose object keys or the bucket endpoint to the browser.

  1. 2

Record metadata in PostgreSQL

Keep the owner, name and object key in a table so authorization decisions come from your data, not from the bucket.

  1. 3

Store and stream through the app

PutObject on upload, GetObject on download, both server-side with the injected credentials.

ample deploy . --name <app-name> --public --env S3_ENDPOINT=... --env S3_REGION=... --env S3_BUCKET=... --env S3_ACCESS_KEY_ID=... --env S3_SECRET_ACCESS_KEY=...
  1. 4

Test both paths

An unauthenticated request must return 401; an authorized request must return the stored content.

  1. 5

Verify

Fetch the live URL and run the success checks below. On failure read the build log, then the runtime log, fix the cause and deploy again; do not blind-retry.

ample logs <deployment_id> --kind build

Tested examples

How to know it worked

Know the limits

Cost estimate

Estimated 10.00 USD per month (size prices from pricing.toml at build revision a1b8c38919e59cd035ebabaced73cf84ece24371).

Apps and managed databases auto-pause when idle; the estimate is the always-on monthly price of the tested sizes. Plan quotas and budgets apply.

Verification evidence

Execution binding

MCP tool ample_deploy (registry mcp:ample_deploy), schema hash 876465fce906da0c observed 2026-09-20T01:55:48.667900+00:00 at revision 199ff1dfd526. Binding state at export: current. Required scopes: servers:write, databases:read, buckets:read.