Documentation

Learn how to architect your data pipeline in minutes.

S3 Permissions & IAM Best Practices

The exact IAM policy Rilavek needs to operate. Nothing more.

Quick Reference

Rilavek operates on a write-only, least-privilege model. We never need to read your files back. The permission groups below are ranked by priority.

Required
  • s3:PutObject
  • s3:CreateMultipartUpload
  • s3:UploadPart
  • s3:CompleteMultipartUpload
  • s3:AbortMultipartUpload
  • s3:ListMultipartUploadParts

Core write + multipart. Without these, nothing works.

Recommended
  • s3:ListBucket

Enables directory listings and empty-folder checks for FTP/SFTP clients. Not strictly required for HTTP/TUS uploads.

Situational
  • s3:GetObject
  • s3:DeleteObject

GetObject: Keep disabled. A write-only policy means your bucket contents stay private by design, not by luck.
DeleteObject: Only add if you need FTP/SFTP clients to delete files.

IAM Policy

Replace YOUR-BUCKET-NAME with your actual bucket name.

iam-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RilavekBucketLevel",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME"
    },
    {
      "Sid": "RilavekObjectLevel",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:AbortMultipartUpload",
        "s3:ListMultipartUploadParts"
      ],
      "Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
    }
  ]
}
AWS only: On non-AWS providers like Wasabi or MinIO, s3:PutObject does not implicitly cover multipart actions. Switch to the Expanded policy if uploads fail.

Why these actions?

s3:PutObject

The fundamental write operation. Every file Rilavek delivers to your bucket goes through PutObject. On AWS, this implicitly covers CreateMultipartUpload, UploadPart, and CompleteMultipartUpload, which is why the minimal policy is shorter.

s3:AbortMultipartUpload

Used to clean up incomplete uploads when a transfer is cancelled or an UploadId becomes stale. Without this, incomplete parts accumulate in your bucket and incur S3 storage costs.

s3:ListMultipartUploadParts

Before resuming an interrupted upload, Rilavek verifies the UploadId is still valid. This requires ListMultipartUploadParts. Without it, a resume attempt against an expired upload would fail silently with corrupted state rather than cleanly restarting.

s3:ListBucket

Applied at the bucket level, not object level. Used by FTP/SFTP clients to browse directory contents and to verify a folder is empty before deletion. Not required for HTTP/TUS pipelines.

Security Recommendation: Write-Only by Default

The safest configuration is write-only with no read access. With this posture, any access to your ingest credentials can only result in new data being written. Existing data remains inaccessible by design. Rilavek treats your bucket as a drop box, not a full filesystem.

Provider Setup & Access Key Guides

Find the direct credential setup guide and permission requirements for your specific cloud storage provider:

AWS S3

AWS S3

s3:PutObject implicitly covers multipart sub-actions. The minimal policy works as-is.

Backblaze B2

Backblaze B2

Create an Application Key scoped to a single bucket with Write Only capability. B2's S3 compatibility layer maps these automatically.

Cloudflare R2

Cloudflare R2

Uses API tokens, not IAM policies. Grant Object Read & Write scoped to the specific bucket.

Wasabi Hot Cloud

Wasabi Hot Cloud

Requires explicit multipart actions in the policy. Use the expanded variant if uploads fail with AccessDenied.

IDrive e2

IDrive e2

No IAM policies. Permissions are set per access key in the e2 console. Select Write Only when creating the key and scope it to the target bucket.

DigitalOcean Spaces

DigitalOcean Spaces

Generate an Access Key under Spaces Object Storage > Access Keys in your DigitalOcean cloud console. Limited (scoped to your bucket) or account-wide Full access keys both work seamlessly.

RustFS

RustFS

Generate an access token with write capabilities scoped to your target bucket from the RustFS management console.

Troubleshooting

AccessDenied on multipart upload

Your provider requires explicit multipart actions. Switch to the expanded policy.

NoSuchBucket

The bucket name in your data store config does not match an existing bucket. Double-check for typos and confirm the region.

InvalidAccessKeyId / SignatureDoesNotMatch

Credentials are incorrect. Regenerate the access key and secret from your provider console.

Empty directory listing via FTP/SFTP

Your IAM policy is missing s3:ListBucket. Add it to the bucket-level statement.

Resumed upload fails after provider lifecycle cleanup

The multipart upload was expired by a lifecycle rule. Rilavek will detect this and restart, but needs s3:ListMultipartUploadParts to verify the UploadId is still valid before resuming.