Add comments about AWS S3

This commit is contained in:
binwiederhier 2026-03-22 20:52:25 -04:00
parent 4d07897d2d
commit 69cc80ec1e
4 changed files with 63 additions and 4 deletions

View file

@ -157,7 +157,7 @@ func (c *Store) sync() error {
// than the grace period to account for races, and skipping objects with invalid IDs.
cutoff := time.Now().Add(-orphanGracePeriod)
var orphanIDs []string
var size int64
var count, size int64
sizes := make(map[string]int64, len(remoteObjects))
for _, obj := range remoteObjects {
if !fileIDRegex.MatchString(obj.ID) {
@ -166,11 +166,12 @@ func (c *Store) sync() error {
if _, ok := localIDMap[obj.ID]; !ok && obj.LastModified.Before(cutoff) {
orphanIDs = append(orphanIDs, obj.ID)
} else {
count++
size += obj.Size
sizes[obj.ID] = obj.Size
}
}
log.Tag(tagStore).Debug("Attachment store updated: %d attachment(s), %s", len(localIDs), util.FormatSizeHuman(size))
log.Tag(tagStore).Debug("Attachment store updated: %d attachment(s), %s", count, util.FormatSizeHuman(size))
c.mu.Lock()
c.size = size
c.sizes = sizes

View file

@ -565,6 +565,34 @@ When `endpoint` is specified, path-style addressing is enabled automatically (us
Note that the access key and secret key may have to be URL encoded. For instance, a secret key `YmxhY+mxhYmxhC` (note the `+`) should
be encoded as `YmxhY%2BmxhYmxhC` (note the `%2B`), so the URL would be `s3://ACCESS_KEY:YmxhY%2BmxhYmxhC@my-bucket/attachments...`.
For **AWS S3**, the IAM user needs the following permissions on the bucket:
``` json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:ListBucketMultipartUploads"
],
"Resource": "arn:aws:s3:::BUCKET_NAME"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::BUCKET_NAME/*"
}
]
}
```
## Access control
By default, the ntfy server is open for everyone, meaning **everyone can read and write to any topic** (this is how
ntfy.sh is configured). To restrict access to your own server, you can optionally configure authentication and authorization.

View file

@ -1802,7 +1802,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
**Features:**
* Add S3-compatible object storage as an alternative [attachment](config.md#attachments) backend via `attachment-cache-dir` config option
* Add S3-compatible object storage as an alternative [attachment store](config.md#attachments) via `attachment-cache-dir` config option
**Bug fixes + maintenance:**

View file

@ -25,6 +25,32 @@ const (
// and ListObjectsV2 operations using AWS Signature V4 signing. The bucket and optional key prefix
// are fixed at construction time. All operations target the same bucket and prefix.
//
// The following IAM policy is required for AWS S3:
//
// {
// "Version": "2012-10-17",
// "Statement": [
// {
// "Effect": "Allow",
// "Action": [
// "s3:ListBucket",
// "s3:ListBucketMultipartUploads"
// ],
// "Resource": "arn:aws:s3:::BUCKET_NAME"
// },
// {
// "Effect": "Allow",
// "Action": [
// "s3:GetObject",
// "s3:PutObject",
// "s3:DeleteObject",
// "s3:AbortMultipartUpload"
// ],
// "Resource": "arn:aws:s3:::BUCKET_NAME/*"
// }
// ]
// }
//
// Fields must not be modified after the Client is passed to any method or goroutine.
type Client struct {
config *Config
@ -149,7 +175,11 @@ func (c *Client) ListObjectsV2(ctx context.Context) ([]*Object, error) {
// listObjectsV2 performs a single ListObjectsV2 request using the client's configured prefix.
func (c *Client) listObjectsV2(ctx context.Context, continuationToken string) (*listObjectsV2Result, error) {
log.Tag(tagS3Client).Debug("Listing remote objects with continuation token '%s'", continuationToken)
if continuationToken == "" {
log.Tag(tagS3Client).Debug("Listing remote objects")
} else {
log.Tag(tagS3Client).Debug("Listing remote objects, continuing with token '%s'", continuationToken)
}
query := url.Values{"list-type": {"2"}}
if prefix := c.config.ListPrefix(); prefix != "" {
query.Set("prefix", prefix)