page:guides:next js:private file access
Enforce private-file authorization for Next.js
Enforce private-file authorization in a Next.js app on Ample. The route handler authorizes the request first, records file metadata in a managed PostgreSQL database, stores bytes in a private bucket and streams them back only to authorized callers. The bucket is never published, so objects are reachable only through the app.
Representative Queries
- Enforce private-file authorization for Next.js
- Where can I host Enforce private-file authorization built with Next.js?
- I need application identity integration, per-file access rules and negative authorization tests.
Resource Requirements
- compute
- postgres
- s3-compatible-object-storage
Infrastructure Requirements
- Compute: Apps run in isolated x86_64 Firecracker microVMs that auto-pause when idle and wake on request; sizes are the priced VM sizes.
- Postgres: Managed PostgreSQL 16 runs in its own microVM and is auto-provisioned when an app needs a database and no DATABASE_URL is supplied.
- S3-compatible object storage: Buckets are S3-compatible with issued credentials; PutObject and GetObject are verified by canary. Other S3 operations are not verified.
Workflow Steps
- Authorize before touching storage: Return 401 for unauthenticated requests; never expose object keys or the bucket endpoint to the browser.
- 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.
- Store and stream through the app: PutObject on upload, GetObject on download, both server-side with the injected credentials.
- Test both paths: An unauthenticated request must return 401; an authorized request must return the stored content.
- 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.
Tested Configuration
- Template: node-22
- Runtime: node
- Size: s-1vcpu-1gb
- Install:
npm install - Build:
npm run build --if-present - Start:
npm run start
Prerequisites
- An authorization check in the route handler (session, token or header) before any storage access
- pg reading DATABASE_URL and @aws-sdk/client-s3 reading the S3_* variables
- A private bucket (never
ample bucket publish) and an auto-provisioned or supplied PostgreSQL database - An Ample account token with servers:write, databases:read and buckets:read
Limitations
- Verified on the node-22 template at s-1vcpu-1gb; other templates and sizes are not verified by this recipe.
- Region, compliance attestations, and request-duration limits are unknown and not claimed.
- Apps auto-pause when idle and wake on the next request; always-on is an operator setting, not a plan feature.
- PutObject and GetObject with path-style addressing are verified; multipart upload, listing, presigned URLs, and lifecycle rules are not verified.
- Bucket credentials are passed as encrypted environment variables; the catalog never creates the bucket for you (use
ample bucket create). - Storage is allocation-priced per bucket quota and capped by the account plan; the estimate below covers compute only.
- Authorization is application code; Ample does not provide managed end-user authentication.
- Streaming large files through the app is not verified; the fixture uses small text objects.
Cost Estimate
- Currency: USD
- Monthly Amount: 10.00
- Components:
- App server (s-1vcpu-1gb): 5.00
- Managed PostgreSQL database (s-1vcpu-1gb): 5.00
- Note: 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.
Success Checks
- Unauthenticated request is rejected
- Kind: http_get
- Path: /files/demo
- Expect: unauthorized
- Authorized request returns the private object
- Kind: http_get
- Path: /files/demo?token=
- Expect: private=ok
Examples
- Next.js private files canary: 401 without a token; private=ok with the token after a database write and a bucket round-trip.
Source Ref: tests/deploy-canaries/next-private-files
Next Actions
- Browse the catalog index: GET /v1/catalog
- Search published recipes by intent, stack and constraints: POST /v1/catalog/search
- Prepare a side-effect-free deployment plan for an authorized project: POST /v1/catalog/plan
- Read the existing agent authentication setup: GET /mcp/setup
- Browse Next.js: GET /v1/catalog/nodes/stack%3Aframework-next-js
- Browse Connect app to storage: GET /v1/catalog/nodes/intent%3Aconnect-app-to-storage
- Browse Private document library: GET /v1/catalog/nodes/pattern%3Aprivate-document-library