Skip to content

docs: Make file-upload storage setup the default path for S3, GCP, and R2 - #763

Open
abdulawalarif wants to merge 2 commits into
serverpod:mainfrom
abdulawalarif:docs/improve-pubdev-readiness
Open

docs: Make file-upload storage setup the default path for S3, GCP, and R2#763
abdulawalarif wants to merge 2 commits into
serverpod:mainfrom
abdulawalarif:docs/improve-pubdev-readiness

Conversation

@abdulawalarif

@abdulawalarif abdulawalarif commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

serverpod/serverpod#3470 is a pub.dev packaging audit. This PR updates the File uploads page so it is the canonical setup path those packages can link to. It does not close that issue.

S3, GCP, and R2 each get one default setup path. Native GCP and custom S3-compatible endpoints stay as labelled variants. The GCP HMAC region example is us-central1 instead of auto, and preventOverwrite is documented as enforced on native GCP and R2, and ignored on S3 and HMAC GCP.

Test plan

  • Open Next → Concepts → Endpoints & APIs → File uploads.
  • Walk HMAC GCP, native GCP, S3, and R2: install, import, constructor, and passwords or env vars.
  • Confirm the custom S3-compatible section is last and is not the default path.
  • Check links to Configuration, Sessions, pub.dev packages, GCP HMAC keys, and Cloudflare R2 tokens.

…d R2

Give each provider a single setup path, document s3_compat as a building block, and correct the GCP HMAC region and preventOverwrite behavior.
@developerjamiu

developerjamiu commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Closes serverpod/serverpod#3470 points at "Improve pub.dev readiness for all Serverpod packages", an open framework issue about package READMEs and pub scores. Cross-repo closing keywords fire, so merging this would close it. Remove the line.

There are a few steps required to upload a file. First, you must create an upload description on the server and pass it to your app. The upload description grants access to the app to upload the file. If you want to grant access to any file, you can add the following code to one of your endpoints. However, in most cases, you may want to restrict which files can be uploaded.
### Create an upload description

Create an upload description on the server and pass it to the app. The description grants the app permission to upload that file. Restrict who can request one.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 13 says "Do not accept an arbitrary client path", but both samples below take path from the caller and pass it straight through. The previous version labelled the first sample as the deliberately unrestricted one, and that sentence is gone.

Suggested change
Create an upload description on the server and pass it to the app. The description grants the app permission to upload that file. Restrict who can request one.
Create an upload description on the server and pass it to the app. The description grants the app permission to upload that file. Restrict who can request one. The example below accepts whatever path it is given. Build the path on the server rather than copying it as-is.

```

For environments that support Application Default Credentials (e.g. Google Compute Engine, Cloud Run), use `fromApplicationDefaultCredentials`:
On Google Compute Engine or Cloud Run, use Application Default Credentials instead:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section previously documented a third constructor, fromServiceAccountJson, for passing the JSON directly. It still exists at native_google_cloud_storage.dart:97, and the other two constructors survived the rewrite.

Suggested change
On Google Compute Engine or Cloud Run, use Application Default Credentials instead:
To pass the JSON directly instead, use `fromServiceAccountJson`:
```dart
pod.addCloudStorage(
await gcp.NativeGoogleCloudStorage.fromServiceAccountJson(
storageId: 'public',
public: true,
bucket: 'my-bucket-name',
serviceAccountJson: myServiceAccountJson,
),
);
```
On Google Compute Engine or Cloud Run, use Application Default Credentials instead:

### AWS S3
### Configure AWS S3

Create an S3 bucket and an IAM user whose access is limited to that bucket. Put CloudFront in front of the bucket if you want a custom domain and TLS certificate. Add the access keys to `config/passwords.yaml`, or pass them as `SERVERPOD_AWS_ACCESS_KEY_ID` and `SERVERPOD_AWS_SECRET_KEY`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old S3 section ended with "Avoid root-user access keys." The IAM-user half made it into this rewrite, but that warning is the part that stops someone reaching for their root keys.

Suggested change
Create an S3 bucket and an IAM user whose access is limited to that bucket. Put CloudFront in front of the bucket if you want a custom domain and TLS certificate. Add the access keys to `config/passwords.yaml`, or pass them as `SERVERPOD_AWS_ACCESS_KEY_ID` and `SERVERPOD_AWS_SECRET_KEY`.
Create an S3 bucket and an IAM user whose access is limited to that bucket. Avoid root-user access keys. Put CloudFront in front of the bucket if you want a custom domain and TLS certificate. Add the access keys to `config/passwords.yaml`, or pass them as `SERVERPOD_AWS_ACCESS_KEY_ID` and `SERVERPOD_AWS_SECRET_KEY`.

Label the unrestricted path example, restore fromServiceAccountJson, and warn against root-user AWS keys.
@abdulawalarif

abdulawalarif commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review:
I addressed the suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants